Skip to content

Commit

Permalink
dataclients/kubernetes: append filters to routes of Ingress/RouteGrou…
Browse files Browse the repository at this point in the history
…p having specific annotation (#3376)

Similar to #3328 this change adds new flags to configure filters appended
to routes created for Kubernetes resources having specific annotation.

Signed-off-by: Alexander Yastrebov <[email protected]>
  • Loading branch information
AlexanderYastrebov authored Jan 20, 2025
1 parent df9f6df commit 017f25d
Show file tree
Hide file tree
Showing 17 changed files with 810 additions and 276 deletions.
210 changes: 129 additions & 81 deletions config/config.go

Large diffs are not rendered by default.

271 changes: 172 additions & 99 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -495,117 +495,190 @@ func TestMultiFlagYamlErr(t *testing.T) {
}
}

func TestAnnotationPredicatesParsingInvalid(t *testing.T) {
for _, tc := range []struct {
name string
input []string
}{
{
name: "wrong predicate",
input: []string{`to-add-predicate=true="Fo_o("123")"`},
},
{
name: "wrong predicate and empty value",
input: []string{"", `to-add-predicate=true="Fo_o()"`},
},
{
name: "duplicate",
input: []string{`to-add-predicate=true=Foo("123")`, `to-add-predicate=true=Bar("456")`},
},
} {
t.Run(tc.name, func(t *testing.T) {
_, err := parseAnnotationPredicates(tc.input)
require.Error(t, err)
})
}
func TestParseAnnotationConfigInvalid(t *testing.T) {
t.Run("parseAnnotationPredicates", func(t *testing.T) {
for _, tc := range []struct {
name string
input []string
}{
{
name: "wrong predicate",
input: []string{`to-add-predicate=true="Fo_o("123")"`},
},
{
name: "wrong predicate and empty value",
input: []string{"", `to-add-predicate=true="Fo_o()"`},
},
{
name: "duplicate",
input: []string{`to-add-predicate=true=Foo("123")`, `to-add-predicate=true=Bar("456")`},
},
} {
t.Run(tc.name, func(t *testing.T) {
_, err := parseAnnotationPredicates(tc.input)
assert.Error(t, err)
})
}
})

t.Run("parseAnnotationFilters", func(t *testing.T) {
for _, tc := range []struct {
name string
input []string
}{
{
name: "invalid filter",
input: []string{`foo=bar=invalid-filter()`},
},
{
name: "invalid filter and empty value",
input: []string{"", `foo=bar=invalid-filter()`},
},
{
name: "duplicate",
input: []string{`foo=bar=baz("123")`, `foo=bar=qux("456")`},
},
} {
t.Run(tc.name, func(t *testing.T) {
_, err := parseAnnotationFilters(tc.input)
assert.Error(t, err)
})
}
})
}

func TestAnnotationPredicatesParsingValid(t *testing.T) {
for _, tc := range []struct {
name string
input []string
expected []kubernetes.AnnotationPredicates
}{
{
name: "empty",
input: []string{},
expected: nil,
},
{
name: "empty string",
input: []string{""},
expected: nil,
},
{
name: "empty string and a valid value",
input: []string{
"",
`to-add-predicate=true=Foo("123")`,
func TestParseAnnotationConfig(t *testing.T) {
t.Run("parseAnnotationPredicates", func(t *testing.T) {

for _, tc := range []struct {
name string
input []string
expected []kubernetes.AnnotationPredicates
}{
{
name: "empty",
input: []string{},
expected: nil,
},
expected: []kubernetes.AnnotationPredicates{
{
Key: "to-add-predicate",
Value: "true",
Predicates: []*eskip.Predicate{
{
Name: "Foo",
Args: []any{"123"},
},
{
name: "empty string",
input: []string{""},
expected: nil,
},
{
name: "empty string and a valid value",
input: []string{
"",
`to-add-predicate=true=Foo("123")`,
},
expected: []kubernetes.AnnotationPredicates{
{
Key: "to-add-predicate",
Value: "true",
Predicates: eskip.MustParsePredicates(`Foo("123")`),
},
},
},
},
{
name: "single",
input: []string{`to-add-predicate=true=Foo("123")`},
expected: []kubernetes.AnnotationPredicates{
{
Key: "to-add-predicate",
Value: "true",
Predicates: []*eskip.Predicate{
{
Name: "Foo",
Args: []any{"123"},
},
{
name: "single",
input: []string{`to-add-predicate=true=Foo("123")`},
expected: []kubernetes.AnnotationPredicates{
{
Key: "to-add-predicate",
Value: "true",
Predicates: eskip.MustParsePredicates(`Foo("123")`),
},
},
},
},
{
name: "multiple",
input: []string{`to-add-predicate=true=Foo("123")`, `to-add-predicate=false=Bar("456") && Foo("789")`},
expected: []kubernetes.AnnotationPredicates{
{
Key: "to-add-predicate",
Value: "true",
Predicates: []*eskip.Predicate{
{
Name: "Foo",
Args: []any{"123"},
},
{
name: "multiple",
input: []string{`to-add-predicate=true=Foo("123")`, `to-add-predicate=false=Bar("456") && Foo("789")`},
expected: []kubernetes.AnnotationPredicates{
{
Key: "to-add-predicate",
Value: "true",
Predicates: eskip.MustParsePredicates(`Foo("123")`),
},
{
Key: "to-add-predicate",
Value: "false",
Predicates: eskip.MustParsePredicates(`Bar("456") && Foo("789")`),
},
},
},
} {
t.Run(tc.name, func(t *testing.T) {
val, err := parseAnnotationPredicates(tc.input)
require.NoError(t, err)
assert.Equal(t, tc.expected, val)
})
}
})

t.Run("parseAnnotationFilters", func(t *testing.T) {

for _, tc := range []struct {
name string
input []string
expected []kubernetes.AnnotationFilters
}{
{
name: "empty",
input: []string{},
expected: nil,
},
{
name: "empty string",
input: []string{""},
expected: nil,
},
{
name: "empty string and a valid value",
input: []string{
"",
`foo=true=baz("123=456")`,
},
expected: []kubernetes.AnnotationFilters{
{
Key: "foo",
Value: "true",
Filters: eskip.MustParseFilters(`baz("123=456")`),
},
},
{
Key: "to-add-predicate",
Value: "false",
Predicates: []*eskip.Predicate{
{
Name: "Bar",
Args: []any{"456"},
},
{
Name: "Foo",
Args: []any{"789"},
},
},
{
name: "single",
input: []string{`foo=true=baz("123=456")`},
expected: []kubernetes.AnnotationFilters{
{
Key: "foo",
Value: "true",
Filters: eskip.MustParseFilters(`baz("123=456")`),
},
},
},
},
} {
t.Run(tc.name, func(t *testing.T) {
val, err := parseAnnotationPredicates(tc.input)
require.NoError(t, err)
assert.Equal(t, tc.expected, val)
})
}
{
name: "multiple",
input: []string{`foo=true=baz("123=456")`, `foo=false=bar("456") -> foo("789")`},
expected: []kubernetes.AnnotationFilters{
{
Key: "foo",
Value: "true",
Filters: eskip.MustParseFilters(`baz("123=456")`),
},
{
Key: "foo",
Value: "false",
Filters: eskip.MustParseFilters(`bar("456") -> foo("789")`),
},
},
},
} {
t.Run(tc.name, func(t *testing.T) {
val, err := parseAnnotationFilters(tc.input)
require.NoError(t, err)
assert.Equal(t, tc.expected, val)
})
}
})
}
16 changes: 15 additions & 1 deletion dataclients/kubernetes/annotations.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ type AnnotationPredicates struct {
Predicates []*eskip.Predicate
}

func addAnnotationPredicates(annotationPredicates []AnnotationPredicates, annotations map[string]string, r *eskip.Route) {
type AnnotationFilters struct {
Key string
Value string
Filters []*eskip.Filter
}

func appendAnnotationPredicates(annotationPredicates []AnnotationPredicates, annotations map[string]string, r *eskip.Route) {
for _, ap := range annotationPredicates {
if objAnnotationVal, ok := annotations[ap.Key]; ok && ap.Value == objAnnotationVal {
// since this annotation is managed by skipper operator, we can safely assume that the predicate is valid
Expand All @@ -19,3 +25,11 @@ func addAnnotationPredicates(annotationPredicates []AnnotationPredicates, annota
}
}
}

func appendAnnotationFilters(annotationFilters []AnnotationFilters, annotations map[string]string, r *eskip.Route) {
for _, af := range annotationFilters {
if objAnnotationVal, ok := annotations[af.Key]; ok && af.Value == objAnnotationVal {
r.Filters = append(r.Filters, af.Filters...)
}
}
}
Loading

0 comments on commit 017f25d

Please sign in to comment.