]> git.feebdaed.xyz Git - 0xmirror/grpc-go.git/commitdiff
xds: make it possible to create a StringMatcher from arguments outside of test code...
authorEaswar Swaminathan <easwars@google.com>
Wed, 26 Nov 2025 18:56:53 +0000 (10:56 -0800)
committerGitHub <noreply@github.com>
Wed, 26 Nov 2025 18:56:53 +0000 (10:56 -0800)
Changes in this PR:

- Add a new constructors for StringMatcher that can be shared between test and non-test code. This will be used as part of an internal feature to support ext_authz.
- Create new pointers to match strings instead of using the ones from the proto. This would ensure that the xDS proto structs (which are usually huge) can be garbage collected earlier that currently.
- Fixes a bug involving the regex matcher, which should not be considering the ignore_case field, but was.

RELEASE NOTES:

* xds: Fix a bug in StringMatcher where regexes would match incorrectly when ignore_case is set to true.

credentials/xds/xds_client_test.go
internal/credentials/xds/handshake_info_test.go
internal/xds/matcher/string_matcher.go
internal/xds/matcher/string_matcher_test.go
internal/xds/xdsclient/xdsresource/unmarshal_cds_test.go

index e013184f55ee1b389ff06624198dc6215cf16d01..cb316ec6e1bd125c65436e3f6c85c2a845edac57 100644 (file)
@@ -226,7 +226,7 @@ func newTestContextWithHandshakeInfo(parent context.Context, root, identity cert
        // NewSubConn().
        var sms []matcher.StringMatcher
        if sanExactMatch != "" {
-               sms = []matcher.StringMatcher{matcher.StringMatcherForTesting(newStringP(sanExactMatch), nil, nil, nil, nil, false)}
+               sms = []matcher.StringMatcher{matcher.NewExactStringMatcher(sanExactMatch, false)}
        }
        info := xdsinternal.NewHandshakeInfo(root, identity, sms, false)
        uPtr := unsafe.Pointer(info)
@@ -542,7 +542,7 @@ func (s) TestClientCredsProviderSwitch(t *testing.T) {
        // Create a root provider which will fail the handshake because it does not
        // use the correct trust roots.
        root1 := makeRootProvider(t, "x509/client_ca_cert.pem")
-       handshakeInfo := xdsinternal.NewHandshakeInfo(root1, nil, []matcher.StringMatcher{matcher.StringMatcherForTesting(newStringP(defaultTestCertSAN), nil, nil, nil, nil, false)}, false)
+       handshakeInfo := xdsinternal.NewHandshakeInfo(root1, nil, []matcher.StringMatcher{matcher.NewExactStringMatcher(defaultTestCertSAN, false)}, false)
        // We need to repeat most of what newTestContextWithHandshakeInfo() does
        // here because we need access to the underlying HandshakeInfo so that we
        // can update it before the next call to ClientHandshake().
@@ -568,7 +568,7 @@ func (s) TestClientCredsProviderSwitch(t *testing.T) {
        // Create a new root provider which uses the correct trust roots. And update
        // the HandshakeInfo with the new provider.
        root2 := makeRootProvider(t, "x509/server_ca_cert.pem")
-       handshakeInfo = xdsinternal.NewHandshakeInfo(root2, nil, []matcher.StringMatcher{matcher.StringMatcherForTesting(newStringP(defaultTestCertSAN), nil, nil, nil, nil, false)}, false)
+       handshakeInfo = xdsinternal.NewHandshakeInfo(root2, nil, []matcher.StringMatcher{matcher.NewExactStringMatcher(defaultTestCertSAN, false)}, false)
        // Update the existing pointer, which address attribute will continue to
        // point to.
        atomic.StorePointer(&uPtr, unsafe.Pointer(handshakeInfo))
@@ -596,7 +596,3 @@ func (s) TestClientClone(t *testing.T) {
                t.Fatal("return value from Clone() doesn't point to new credentials instance")
        }
 }
-
-func newStringP(s string) *string {
-       return &s
-}
index 53b2700b41efa1ecb4c8163672bc2b83a29c6036..7577813eba9d40aeb989261c4cab1897d03b138c 100644 (file)
@@ -170,40 +170,40 @@ func TestMatchingSANExists_FailureCases(t *testing.T) {
                {
                        desc: "exact match",
                        sanMatchers: []matcher.StringMatcher{
-                               matcher.StringMatcherForTesting(newStringP("abcd.test.com"), nil, nil, nil, nil, false),
-                               matcher.StringMatcherForTesting(newStringP("http://golang"), nil, nil, nil, nil, false),
-                               matcher.StringMatcherForTesting(newStringP("HTTP://GOLANG.ORG"), nil, nil, nil, nil, false),
+                               matcher.NewExactStringMatcher("abcd.test.com", false),
+                               matcher.NewExactStringMatcher("http://golang", false),
+                               matcher.NewExactStringMatcher("HTTP://GOLANG.ORG", false),
                        },
                },
                {
                        desc: "prefix match",
                        sanMatchers: []matcher.StringMatcher{
-                               matcher.StringMatcherForTesting(nil, newStringP("i-aint-the-one"), nil, nil, nil, false),
-                               matcher.StringMatcherForTesting(nil, newStringP("192.168.1.1"), nil, nil, nil, false),
-                               matcher.StringMatcherForTesting(nil, newStringP("FOO.BAR"), nil, nil, nil, false),
+                               matcher.NewPrefixStringMatcher("i-aint-the-one", false),
+                               matcher.NewPrefixStringMatcher("192.168.1.1", false),
+                               matcher.NewPrefixStringMatcher("FOO.BAR", false),
                        },
                },
                {
                        desc: "suffix match",
                        sanMatchers: []matcher.StringMatcher{
-                               matcher.StringMatcherForTesting(nil, nil, newStringP("i-aint-the-one"), nil, nil, false),
-                               matcher.StringMatcherForTesting(nil, nil, newStringP("1::68"), nil, nil, false),
-                               matcher.StringMatcherForTesting(nil, nil, newStringP(".COM"), nil, nil, false),
+                               matcher.NewSuffixStringMatcher("i-aint-the-one", false),
+                               matcher.NewSuffixStringMatcher("1::68", false),
+                               matcher.NewSuffixStringMatcher(".COM", false),
                        },
                },
                {
                        desc: "regex match",
                        sanMatchers: []matcher.StringMatcher{
-                               matcher.StringMatcherForTesting(nil, nil, nil, nil, regexp.MustCompile(`.*\.examples\.com`), false),
-                               matcher.StringMatcherForTesting(nil, nil, nil, nil, regexp.MustCompile(`192\.[0-9]{1,3}\.1\.1`), false),
+                               matcher.NewRegexStringMatcher(regexp.MustCompile(`.*\.examples\.com`)),
+                               matcher.NewRegexStringMatcher(regexp.MustCompile(`192\.[0-9]{1,3}\.1\.1`)),
                        },
                },
                {
                        desc: "contains match",
                        sanMatchers: []matcher.StringMatcher{
-                               matcher.StringMatcherForTesting(nil, nil, nil, newStringP("i-aint-the-one"), nil, false),
-                               matcher.StringMatcherForTesting(nil, nil, nil, newStringP("2001:db8:1:1::68"), nil, false),
-                               matcher.StringMatcherForTesting(nil, nil, nil, newStringP("GRPC"), nil, false),
+                               matcher.NewContainsStringMatcher("i-aint-the-one", false),
+                               matcher.NewContainsStringMatcher("2001:db8:1:1::68", false),
+                               matcher.NewContainsStringMatcher("GRPC", false),
                        },
                },
        }
@@ -248,65 +248,65 @@ func TestMatchingSANExists_Success(t *testing.T) {
                {
                        desc: "exact match dns wildcard",
                        sanMatchers: []matcher.StringMatcher{
-                               matcher.StringMatcherForTesting(nil, newStringP("192.168.1.1"), nil, nil, nil, false),
-                               matcher.StringMatcherForTesting(newStringP("https://github.com/grpc/grpc-java"), nil, nil, nil, nil, false),
-                               matcher.StringMatcherForTesting(newStringP("abc.example.com"), nil, nil, nil, nil, false),
+                               matcher.NewPrefixStringMatcher("192.168.1.1", false),
+                               matcher.NewExactStringMatcher("https://github.com/grpc/grpc-java", false),
+                               matcher.NewExactStringMatcher("abc.example.com", false),
                        },
                },
                {
                        desc: "exact match ignore case",
                        sanMatchers: []matcher.StringMatcher{
-                               matcher.StringMatcherForTesting(newStringP("FOOBAR@EXAMPLE.COM"), nil, nil, nil, nil, true),
+                               matcher.NewExactStringMatcher("FOOBAR@EXAMPLE.COM", true),
                        },
                },
                {
                        desc: "prefix match",
                        sanMatchers: []matcher.StringMatcher{
-                               matcher.StringMatcherForTesting(nil, nil, newStringP(".co.in"), nil, nil, false),
-                               matcher.StringMatcherForTesting(nil, newStringP("192.168.1.1"), nil, nil, nil, false),
-                               matcher.StringMatcherForTesting(nil, newStringP("baz.test"), nil, nil, nil, false),
+                               matcher.NewSuffixStringMatcher(".co.in", false),
+                               matcher.NewPrefixStringMatcher("192.168.1.1", false),
+                               matcher.NewPrefixStringMatcher("baz.test", false),
                        },
                },
                {
                        desc: "prefix match ignore case",
                        sanMatchers: []matcher.StringMatcher{
-                               matcher.StringMatcherForTesting(nil, newStringP("BAZ.test"), nil, nil, nil, true),
+                               matcher.NewPrefixStringMatcher("BAZ.test", true),
                        },
                },
                {
                        desc: "suffix  match",
                        sanMatchers: []matcher.StringMatcher{
-                               matcher.StringMatcherForTesting(nil, nil, nil, nil, regexp.MustCompile(`192\.[0-9]{1,3}\.1\.1`), false),
-                               matcher.StringMatcherForTesting(nil, nil, newStringP("192.168.1.1"), nil, nil, false),
-                               matcher.StringMatcherForTesting(nil, nil, newStringP("@test.com"), nil, nil, false),
+                               matcher.NewRegexStringMatcher(regexp.MustCompile(`192\.[0-9]{1,3}\.1\.1`)),
+                               matcher.NewSuffixStringMatcher("192.168.1.1", false),
+                               matcher.NewSuffixStringMatcher("@test.com", false),
                        },
                },
                {
                        desc: "suffix  match ignore case",
                        sanMatchers: []matcher.StringMatcher{
-                               matcher.StringMatcherForTesting(nil, nil, newStringP("@test.COM"), nil, nil, true),
+                               matcher.NewSuffixStringMatcher("@test.COM", true),
                        },
                },
                {
                        desc: "regex match",
                        sanMatchers: []matcher.StringMatcher{
-                               matcher.StringMatcherForTesting(nil, nil, nil, newStringP("https://github.com/grpc/grpc-java"), nil, false),
-                               matcher.StringMatcherForTesting(nil, nil, nil, nil, regexp.MustCompile(`192\.[0-9]{1,3}\.1\.1`), false),
-                               matcher.StringMatcherForTesting(nil, nil, nil, nil, regexp.MustCompile(`.*\.test\.com`), false),
+                               matcher.NewContainsStringMatcher("https://github.com/grpc/grpc-java", false),
+                               matcher.NewRegexStringMatcher(regexp.MustCompile(`192\.[0-9]{1,3}\.1\.1`)),
+                               matcher.NewRegexStringMatcher(regexp.MustCompile(`.*\.test\.com`)),
                        },
                },
                {
                        desc: "contains match",
                        sanMatchers: []matcher.StringMatcher{
-                               matcher.StringMatcherForTesting(newStringP("https://github.com/grpc/grpc-java"), nil, nil, nil, nil, false),
-                               matcher.StringMatcherForTesting(nil, nil, nil, newStringP("2001:68::db8"), nil, false),
-                               matcher.StringMatcherForTesting(nil, nil, nil, newStringP("192.0.0"), nil, false),
+                               matcher.NewExactStringMatcher("https://github.com/grpc/grpc-java", false),
+                               matcher.NewContainsStringMatcher("2001:68::db8", false),
+                               matcher.NewContainsStringMatcher("192.0.0", false),
                        },
                },
                {
                        desc: "contains match ignore case",
                        sanMatchers: []matcher.StringMatcher{
-                               matcher.StringMatcherForTesting(nil, nil, nil, newStringP("GRPC"), nil, true),
+                               matcher.NewContainsStringMatcher("GRPC", true),
                        },
                },
        }
@@ -322,10 +322,6 @@ func TestMatchingSANExists_Success(t *testing.T) {
        }
 }
 
-func newStringP(s string) *string {
-       return &s
-}
-
 func TestEqual(t *testing.T) {
        tests := []struct {
                desc      string
@@ -354,31 +350,31 @@ func TestEqual(t *testing.T) {
                {
                        desc: "same providers, same SAN matchers",
                        hi1: NewHandshakeInfo(testCertProvider{}, testCertProvider{}, []matcher.StringMatcher{
-                               matcher.StringMatcherForTesting(newStringP("foo.com"), nil, nil, nil, nil, false),
+                               matcher.NewExactStringMatcher("foo.com", false),
                        }, false),
                        hi2: NewHandshakeInfo(testCertProvider{}, testCertProvider{}, []matcher.StringMatcher{
-                               matcher.StringMatcherForTesting(newStringP("foo.com"), nil, nil, nil, nil, false),
+                               matcher.NewExactStringMatcher("foo.com", false),
                        }, false),
                        wantMatch: true,
                },
                {
                        desc: "same providers, different SAN matchers",
                        hi1: NewHandshakeInfo(testCertProvider{}, testCertProvider{}, []matcher.StringMatcher{
-                               matcher.StringMatcherForTesting(newStringP("foo.com"), nil, nil, nil, nil, false),
+                               matcher.NewExactStringMatcher("foo.com", false),
                        }, false),
                        hi2: NewHandshakeInfo(testCertProvider{}, testCertProvider{}, []matcher.StringMatcher{
-                               matcher.StringMatcherForTesting(newStringP("bar.com"), nil, nil, nil, nil, false),
+                               matcher.NewExactStringMatcher("bar.com", false),
                        }, false),
                        wantMatch: false,
                },
                {
                        desc: "same SAN matchers with different content",
                        hi1: NewHandshakeInfo(&testCertProvider{}, &testCertProvider{}, []matcher.StringMatcher{
-                               matcher.StringMatcherForTesting(newStringP("foo.com"), nil, nil, nil, nil, false),
+                               matcher.NewExactStringMatcher("foo.com", false),
                        }, false),
                        hi2: NewHandshakeInfo(&testCertProvider{}, &testCertProvider{}, []matcher.StringMatcher{
-                               matcher.StringMatcherForTesting(newStringP("foo.com"), nil, nil, nil, nil, false),
-                               matcher.StringMatcherForTesting(newStringP("bar.com"), nil, nil, nil, nil, false),
+                               matcher.NewExactStringMatcher("foo.com", false),
+                               matcher.NewExactStringMatcher("bar.com", false),
                        }, false),
                        wantMatch: false,
                },
index c138f78735bc64f58a5a5a83bed0f731fdfa6b57..a6cf05dd3d1322daeffa6087cd167735eaab8e93 100644 (file)
@@ -48,24 +48,49 @@ type StringMatcher struct {
 
 // Match returns true if input matches the criteria in the given StringMatcher.
 func (sm StringMatcher) Match(input string) bool {
-       if sm.ignoreCase {
-               input = strings.ToLower(input)
-       }
        switch {
        case sm.exactMatch != nil:
+               if sm.ignoreCase {
+                       input = strings.ToLower(input)
+               }
                return input == *sm.exactMatch
        case sm.prefixMatch != nil:
+               if sm.ignoreCase {
+                       input = strings.ToLower(input)
+               }
                return strings.HasPrefix(input, *sm.prefixMatch)
        case sm.suffixMatch != nil:
+               if sm.ignoreCase {
+                       input = strings.ToLower(input)
+               }
                return strings.HasSuffix(input, *sm.suffixMatch)
-       case sm.regexMatch != nil:
-               return grpcutil.FullMatchWithRegex(sm.regexMatch, input)
        case sm.containsMatch != nil:
+               if sm.ignoreCase {
+                       input = strings.ToLower(input)
+               }
                return strings.Contains(input, *sm.containsMatch)
+       case sm.regexMatch != nil:
+               return grpcutil.FullMatchWithRegex(sm.regexMatch, input)
        }
        return false
 }
 
+// newStrPtr allocates a new string that holds the value of input and returns a
+// pointer to it. ignoreCase controls if a lower case version of input is used.
+func newStrPtr(input *string, ignoreCase bool) *string {
+       if input == nil {
+               return nil
+       }
+
+       s := new(string)
+       if ignoreCase {
+               *s = strings.ToLower(*input)
+       } else {
+               *s = *input
+       }
+       return s
+}
+
 // StringMatcherFromProto is a helper function to create a StringMatcher from
 // the corresponding StringMatcher proto.
 //
@@ -78,26 +103,17 @@ func StringMatcherFromProto(matcherProto *v3matcherpb.StringMatcher) (StringMatc
        matcher := StringMatcher{ignoreCase: matcherProto.GetIgnoreCase()}
        switch mt := matcherProto.GetMatchPattern().(type) {
        case *v3matcherpb.StringMatcher_Exact:
-               matcher.exactMatch = &mt.Exact
-               if matcher.ignoreCase {
-                       *matcher.exactMatch = strings.ToLower(*matcher.exactMatch)
-               }
+               matcher.exactMatch = newStrPtr(&mt.Exact, matcher.ignoreCase)
        case *v3matcherpb.StringMatcher_Prefix:
                if matcherProto.GetPrefix() == "" {
                        return StringMatcher{}, errors.New("empty prefix is not allowed in StringMatcher")
                }
-               matcher.prefixMatch = &mt.Prefix
-               if matcher.ignoreCase {
-                       *matcher.prefixMatch = strings.ToLower(*matcher.prefixMatch)
-               }
+               matcher.prefixMatch = newStrPtr(&mt.Prefix, matcher.ignoreCase)
        case *v3matcherpb.StringMatcher_Suffix:
                if matcherProto.GetSuffix() == "" {
                        return StringMatcher{}, errors.New("empty suffix is not allowed in StringMatcher")
                }
-               matcher.suffixMatch = &mt.Suffix
-               if matcher.ignoreCase {
-                       *matcher.suffixMatch = strings.ToLower(*matcher.suffixMatch)
-               }
+               matcher.suffixMatch = newStrPtr(&mt.Suffix, matcher.ignoreCase)
        case *v3matcherpb.StringMatcher_SafeRegex:
                regex := matcherProto.GetSafeRegex().GetRegex()
                re, err := regexp.Compile(regex)
@@ -109,40 +125,59 @@ func StringMatcherFromProto(matcherProto *v3matcherpb.StringMatcher) (StringMatc
                if matcherProto.GetContains() == "" {
                        return StringMatcher{}, errors.New("empty contains is not allowed in StringMatcher")
                }
-               matcher.containsMatch = &mt.Contains
-               if matcher.ignoreCase {
-                       *matcher.containsMatch = strings.ToLower(*matcher.containsMatch)
-               }
+               matcher.containsMatch = newStrPtr(&mt.Contains, matcher.ignoreCase)
        default:
                return StringMatcher{}, fmt.Errorf("unrecognized string matcher: %+v", matcherProto)
        }
        return matcher, nil
 }
 
-// StringMatcherForTesting is a helper function to create a StringMatcher based
-// on the given arguments. Intended only for testing purposes.
-func StringMatcherForTesting(exact, prefix, suffix, contains *string, regex *regexp.Regexp, ignoreCase bool) StringMatcher {
-       sm := StringMatcher{
-               exactMatch:    exact,
-               prefixMatch:   prefix,
-               suffixMatch:   suffix,
-               regexMatch:    regex,
-               containsMatch: contains,
+// NewExactStringMatcher creates a string matcher that requires the input string
+// to exactly match the pattern specified here. The match will be case
+// insensitive if ignore_case is true.
+func NewExactStringMatcher(pattern string, ignoreCase bool) StringMatcher {
+       return StringMatcher{
+               exactMatch: newStrPtr(&pattern, ignoreCase),
+               ignoreCase: ignoreCase,
+       }
+}
+
+// NewPrefixStringMatcher creates a string matcher that requires the input
+// string to contain the prefix specified here. The match will be case
+// insensitive if ignore_case is true.
+func NewPrefixStringMatcher(prefix string, ignoreCase bool) StringMatcher {
+       return StringMatcher{
+               prefixMatch: newStrPtr(&prefix, ignoreCase),
+               ignoreCase:  ignoreCase,
+       }
+}
+
+// NewSuffixStringMatcher creates a string matcher that requires the input
+// string to contain the suffix specified here. The match will be case
+// insensitive if ignore_case is true.
+func NewSuffixStringMatcher(suffix string, ignoreCase bool) StringMatcher {
+       return StringMatcher{
+               suffixMatch: newStrPtr(&suffix, ignoreCase),
+               ignoreCase:  ignoreCase,
+       }
+}
+
+// NewContainsStringMatcher creates a string matcher that requires the input
+// string to contain the pattern specified here. The match will be case
+// insensitive if ignore_case is true.
+func NewContainsStringMatcher(pattern string, ignoreCase bool) StringMatcher {
+       return StringMatcher{
+               containsMatch: newStrPtr(&pattern, ignoreCase),
                ignoreCase:    ignoreCase,
        }
-       if ignoreCase {
-               switch {
-               case sm.exactMatch != nil:
-                       *sm.exactMatch = strings.ToLower(*exact)
-               case sm.prefixMatch != nil:
-                       *sm.prefixMatch = strings.ToLower(*prefix)
-               case sm.suffixMatch != nil:
-                       *sm.suffixMatch = strings.ToLower(*suffix)
-               case sm.containsMatch != nil:
-                       *sm.containsMatch = strings.ToLower(*contains)
-               }
+}
+
+// NewRegexStringMatcher creates a string matcher that requires the input string
+// to match the regular expression specified here.
+func NewRegexStringMatcher(regex *regexp.Regexp) StringMatcher {
+       return StringMatcher{
+               regexMatch: regex,
        }
-       return sm
 }
 
 // ExactMatch returns the value of the configured exact match or an empty string
index 9528b57e44a51e4f32d901c1c264eef39dbd3a30..df76af27d587d78d4ead9366fe9e213a8d5a16ec 100644 (file)
@@ -130,6 +130,19 @@ func TestStringMatcherFromProto(t *testing.T) {
                        },
                        wantMatcher: StringMatcher{regexMatch: regexp.MustCompile("good?regex?")},
                },
+               {
+                       desc: "regex with ignore case",
+                       inputProto: &v3matcherpb.StringMatcher{
+                               MatchPattern: &v3matcherpb.StringMatcher_SafeRegex{
+                                       SafeRegex: &v3matcherpb.RegexMatcher{Regex: "good?regex?"},
+                               },
+                               IgnoreCase: true,
+                       },
+                       wantMatcher: StringMatcher{
+                               regexMatch: regexp.MustCompile("good?regex?"),
+                               ignoreCase: true,
+                       },
+               },
                {
                        desc: "happy case contains",
                        inputProto: &v3matcherpb.StringMatcher{
@@ -165,27 +178,15 @@ func TestStringMatcherFromProto(t *testing.T) {
 
 func TestMatch(t *testing.T) {
        var (
-               exactMatcher, _           = StringMatcherFromProto(&v3matcherpb.StringMatcher{MatchPattern: &v3matcherpb.StringMatcher_Exact{Exact: "exact"}})
-               prefixMatcher, _          = StringMatcherFromProto(&v3matcherpb.StringMatcher{MatchPattern: &v3matcherpb.StringMatcher_Prefix{Prefix: "prefix"}})
-               suffixMatcher, _          = StringMatcherFromProto(&v3matcherpb.StringMatcher{MatchPattern: &v3matcherpb.StringMatcher_Suffix{Suffix: "suffix"}})
-               regexMatcher, _           = StringMatcherFromProto(&v3matcherpb.StringMatcher{MatchPattern: &v3matcherpb.StringMatcher_SafeRegex{SafeRegex: &v3matcherpb.RegexMatcher{Regex: "good?regex?"}}})
-               containsMatcher, _        = StringMatcherFromProto(&v3matcherpb.StringMatcher{MatchPattern: &v3matcherpb.StringMatcher_Contains{Contains: "contains"}})
-               exactMatcherIgnoreCase, _ = StringMatcherFromProto(&v3matcherpb.StringMatcher{
-                       MatchPattern: &v3matcherpb.StringMatcher_Exact{Exact: "exact"},
-                       IgnoreCase:   true,
-               })
-               prefixMatcherIgnoreCase, _ = StringMatcherFromProto(&v3matcherpb.StringMatcher{
-                       MatchPattern: &v3matcherpb.StringMatcher_Prefix{Prefix: "prefix"},
-                       IgnoreCase:   true,
-               })
-               suffixMatcherIgnoreCase, _ = StringMatcherFromProto(&v3matcherpb.StringMatcher{
-                       MatchPattern: &v3matcherpb.StringMatcher_Suffix{Suffix: "suffix"},
-                       IgnoreCase:   true,
-               })
-               containsMatcherIgnoreCase, _ = StringMatcherFromProto(&v3matcherpb.StringMatcher{
-                       MatchPattern: &v3matcherpb.StringMatcher_Contains{Contains: "contains"},
-                       IgnoreCase:   true,
-               })
+               exactMatcher              = NewExactStringMatcher("exact", false)
+               exactMatcherIgnoreCase    = NewExactStringMatcher("exact", true)
+               prefixMatcher             = NewPrefixStringMatcher("prefix", false)
+               prefixMatcherIgnoreCase   = NewPrefixStringMatcher("prefix", true)
+               suffixMatcher             = NewSuffixStringMatcher("suffix", false)
+               suffixMatcherIgnoreCase   = NewSuffixStringMatcher("suffix", true)
+               containsMatcher           = NewContainsStringMatcher("contains", false)
+               containsMatcherIgnoreCase = NewContainsStringMatcher("contains", true)
+               regexMatcher              = NewRegexStringMatcher(regexp.MustCompile("good?regex?"))
        )
 
        tests := []struct {
index 0fb70d63544764c7ef7665754bef9449dd88a570..cef43b25b50c506d81a309ed1fb3d2cabd6dc719 100644 (file)
@@ -1216,11 +1216,11 @@ func (s) TestValidateClusterWithSecurityConfig(t *testing.T) {
                                        IdentityInstanceName: identityPluginInstance,
                                        IdentityCertName:     identityCertName,
                                        SubjectAltNameMatchers: []matcher.StringMatcher{
-                                               matcher.StringMatcherForTesting(newStringP(sanExact), nil, nil, nil, nil, true),
-                                               matcher.StringMatcherForTesting(nil, newStringP(sanPrefix), nil, nil, nil, false),
-                                               matcher.StringMatcherForTesting(nil, nil, newStringP(sanSuffix), nil, nil, false),
-                                               matcher.StringMatcherForTesting(nil, nil, nil, nil, sanRE, false),
-                                               matcher.StringMatcherForTesting(nil, nil, nil, newStringP(sanContains), nil, false),
+                                               matcher.NewExactStringMatcher(sanExact, true),
+                                               matcher.NewPrefixStringMatcher(sanPrefix, false),
+                                               matcher.NewSuffixStringMatcher(sanSuffix, false),
+                                               matcher.NewRegexStringMatcher(sanRE),
+                                               matcher.NewContainsStringMatcher(sanContains, false),
                                        },
                                },
                                TelemetryLabels: xdsinternal.UnknownCSMLabels,
@@ -1283,11 +1283,11 @@ func (s) TestValidateClusterWithSecurityConfig(t *testing.T) {
                                        IdentityInstanceName: identityPluginInstance,
                                        IdentityCertName:     identityCertName,
                                        SubjectAltNameMatchers: []matcher.StringMatcher{
-                                               matcher.StringMatcherForTesting(newStringP(sanExact), nil, nil, nil, nil, true),
-                                               matcher.StringMatcherForTesting(nil, newStringP(sanPrefix), nil, nil, nil, false),
-                                               matcher.StringMatcherForTesting(nil, nil, newStringP(sanSuffix), nil, nil, false),
-                                               matcher.StringMatcherForTesting(nil, nil, nil, nil, sanRE, false),
-                                               matcher.StringMatcherForTesting(nil, nil, nil, newStringP(sanContains), nil, false),
+                                               matcher.NewExactStringMatcher(sanExact, true),
+                                               matcher.NewPrefixStringMatcher(sanPrefix, false),
+                                               matcher.NewSuffixStringMatcher(sanSuffix, false),
+                                               matcher.NewRegexStringMatcher(sanRE),
+                                               matcher.NewContainsStringMatcher(sanContains, false),
                                        },
                                },
                                TelemetryLabels: xdsinternal.UnknownCSMLabels,
@@ -1347,11 +1347,11 @@ func (s) TestValidateClusterWithSecurityConfig(t *testing.T) {
                                        IdentityInstanceName: identityPluginInstance,
                                        IdentityCertName:     identityCertName,
                                        SubjectAltNameMatchers: []matcher.StringMatcher{
-                                               matcher.StringMatcherForTesting(newStringP(sanExact), nil, nil, nil, nil, true),
-                                               matcher.StringMatcherForTesting(nil, newStringP(sanPrefix), nil, nil, nil, false),
-                                               matcher.StringMatcherForTesting(nil, nil, newStringP(sanSuffix), nil, nil, false),
-                                               matcher.StringMatcherForTesting(nil, nil, nil, nil, sanRE, false),
-                                               matcher.StringMatcherForTesting(nil, nil, nil, newStringP(sanContains), nil, false),
+                                               matcher.NewExactStringMatcher(sanExact, true),
+                                               matcher.NewPrefixStringMatcher(sanPrefix, false),
+                                               matcher.NewSuffixStringMatcher(sanSuffix, false),
+                                               matcher.NewRegexStringMatcher(sanRE),
+                                               matcher.NewContainsStringMatcher(sanContains, false),
                                        },
                                },
                                TelemetryLabels: xdsinternal.UnknownCSMLabels,