From 366e127f12e40c643ed164d66cf14e0fa4f580e5 Mon Sep 17 00:00:00 2001 From: Luki Boras Date: Wed, 15 Nov 2023 21:28:45 +0100 Subject: [PATCH] Add leftmost wildcard support to descriptor values Signed-off-by: Luki Boras --- src/config/config_impl.go | 24 ++++++++++++++---------- test/config/config_test.go | 16 ++++++++++++++-- test/config/wildcard.yaml | 7 ++++++- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/config/config_impl.go b/src/config/config_impl.go index 2bdbf9d4..4a0b23c4 100644 --- a/src/config/config_impl.go +++ b/src/config/config_impl.go @@ -40,9 +40,9 @@ type YamlRoot struct { } type rateLimitDescriptor struct { - descriptors map[string]*rateLimitDescriptor - limit *RateLimit - wildcardKeys []string + descriptors map[string]*rateLimitDescriptor + limit *RateLimit + wildcardValues []string } type rateLimitDomain struct { @@ -189,9 +189,9 @@ func (this *rateLimitDescriptor) loadDescriptors(config RateLimitConfigToLoad, p newDescriptor.loadDescriptors(config, newParentKey+".", descriptorConfig.Descriptors, statsManager) this.descriptors[finalKey] = newDescriptor - // Preload keys ending with "*" symbol. - if finalKey[len(finalKey)-1:] == "*" { - this.wildcardKeys = append(this.wildcardKeys, finalKey) + // Preload keys starting or ending with "*" symbol. + if strings.HasPrefix(descriptorConfig.Value, "*") || strings.HasSuffix(descriptorConfig.Value, "*") { + this.wildcardValues = append(this.wildcardValues, descriptorConfig.Value) } } } @@ -313,10 +313,14 @@ func (this *rateLimitConfigImpl) GetLimit( logger.Debugf("looking up key: %s", finalKey) nextDescriptor := descriptorsMap[finalKey] - if nextDescriptor == nil && len(prevDescriptor.wildcardKeys) > 0 { - for _, wildcardKey := range prevDescriptor.wildcardKeys { - if strings.HasPrefix(finalKey, strings.TrimSuffix(wildcardKey, "*")) { - nextDescriptor = descriptorsMap[wildcardKey] + if nextDescriptor == nil && len(prevDescriptor.wildcardValues) > 0 { + for _, wildcardValue := range prevDescriptor.wildcardValues { + if strings.HasSuffix(entry.Value, strings.TrimPrefix(wildcardValue, "*")) { + nextDescriptor = descriptorsMap[entry.Key+"_"+wildcardValue] + break + } + if strings.HasPrefix(entry.Value, strings.TrimSuffix(wildcardValue, "*")) { + nextDescriptor = descriptorsMap[entry.Key+"_"+wildcardValue] break } } diff --git a/test/config/config_test.go b/test/config/config_test.go index 3ed3984b..823fcb34 100644 --- a/test/config/config_test.go +++ b/test/config/config_test.go @@ -591,14 +591,24 @@ func TestWildcardConfig(t *testing.T) { wildcard1 := rlConfig.GetLimit( context.TODO(), "test-domain", &pb_struct.RateLimitDescriptor{ - Entries: []*pb_struct.RateLimitDescriptor_Entry{{Key: "wild", Value: "foo1"}}, + Entries: []*pb_struct.RateLimitDescriptor_Entry{{Key: "rightWild", Value: "foo1"}}, }) wildcard2 := rlConfig.GetLimit( context.TODO(), "test-domain", &pb_struct.RateLimitDescriptor{ - Entries: []*pb_struct.RateLimitDescriptor_Entry{{Key: "wild", Value: "foo2"}}, + Entries: []*pb_struct.RateLimitDescriptor_Entry{{Key: "rightWild", Value: "foo2"}}, }) wildcard3 := rlConfig.GetLimit( + context.TODO(), "test-domain", + &pb_struct.RateLimitDescriptor{ + Entries: []*pb_struct.RateLimitDescriptor_Entry{{Key: "leftWild", Value: "afoo"}}, + }) + wildcard4 := rlConfig.GetLimit( + context.TODO(), "test-domain", + &pb_struct.RateLimitDescriptor{ + Entries: []*pb_struct.RateLimitDescriptor_Entry{{Key: "leftWild", Value: "bfoo"}}, + }) + wildcard5 := rlConfig.GetLimit( context.TODO(), "test-domain", &pb_struct.RateLimitDescriptor{ Entries: []*pb_struct.RateLimitDescriptor_Entry{{Key: "nestedWild", Value: "val1"}, {Key: "wild", Value: "goo2"}}, @@ -606,6 +616,8 @@ func TestWildcardConfig(t *testing.T) { assert.NotNil(wildcard1) assert.Equal(wildcard1, wildcard2) assert.NotNil(wildcard3) + assert.Equal(wildcard3, wildcard4) + assert.NotNil(wildcard5) // Doesn't match non-matching values noMatch := rlConfig.GetLimit( diff --git a/test/config/wildcard.yaml b/test/config/wildcard.yaml index e99bac66..37cd7dda 100644 --- a/test/config/wildcard.yaml +++ b/test/config/wildcard.yaml @@ -1,11 +1,16 @@ # Basic configuration for testing. domain: test-domain descriptors: - - key: wild + - key: rightWild value: foo* rate_limit: unit: minute requests_per_unit: 20 + - key: leftWild + value: "*foo" + rate_limit: + unit: minute + requests_per_unit: 20 - key: noWild value: foo rate_limit: