Skip to content

Commit

Permalink
feat: introduce konghq.com/headers-separator annotation and make pars…
Browse files Browse the repository at this point in the history
…ing more robust
  • Loading branch information
programmer04 committed May 7, 2024
1 parent 641c73c commit 22af5b4
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ Adding a new version? You'll need three changes:
- Improve validation - reject `Ingresses`, `Services` or `KongConsumers` that have multiple instances
of the same type plugin attached.
[#5972](https://github.com/Kong/kubernetes-ingress-controller/pull/5972)
- Added support for `konghq.com/headers-separator` that allows to set custom separator (instead of default `,`)
for headers specified with `konghq.com/headers.*` annotations. Moreover parsing a content of `konghq.com/headers.*`
is more robust - leading and trailing whitespace characters are discarded.
[#5977](https://github.com/Kong/kubernetes-ingress-controller/pull/5977)

### Fixed

Expand Down
12 changes: 10 additions & 2 deletions internal/annotations/annotations.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"fmt"
"strings"

"github.com/samber/lo"
netv1 "k8s.io/api/networking/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

Expand Down Expand Up @@ -61,6 +62,7 @@ const (
ReadTimeoutKey = "/read-timeout"
RetriesKey = "/retries"
HeadersKey = "/headers"
HeadersSeparatorKey = "/headers-separator"
PathHandlingKey = "/path-handling"
UserTagKey = "/tags"
RewriteURIKey = "/rewrite"
Expand Down Expand Up @@ -311,14 +313,20 @@ func ExtractRetries(anns map[string]string) (string, bool) {
// ExtractHeaders extracts the parsed headers annotations values. It returns a map of header names to slices of values.
func ExtractHeaders(anns map[string]string) (map[string][]string, bool) {
headers := make(map[string][]string)
prefix := AnnotationPrefix + HeadersKey + "."
const prefix = AnnotationPrefix + HeadersKey + "."
separator, ok := anns[AnnotationPrefix+HeadersSeparatorKey]
if !ok {
separator = ","
}
for key, val := range anns {
if strings.HasPrefix(key, prefix) {
header := strings.TrimPrefix(key, prefix)
if len(header) == 0 || len(val) == 0 {
continue
}
headers[header] = strings.Split(val, ",")
headers[header] = lo.Map(strings.Split(val, separator), func(hv string, _ int) string {
return strings.TrimSpace(hv)
})
}
}
if len(headers) == 0 {
Expand Down
59 changes: 59 additions & 0 deletions internal/annotations/annotations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,15 @@ func TestExtractHeaders(t *testing.T) {
name: "empty",
want: map[string][]string{},
},
{
name: "empty with custom separator",
args: args{
anns: map[string]string{
"konghq.com/headers-separator": ";",
},
},
want: map[string][]string{},
},
{
name: "non-empty",
args: args{
Expand All @@ -863,6 +872,15 @@ func TestExtractHeaders(t *testing.T) {
},
want: map[string][]string{},
},
{
name: "separator with no header results in empty header value",
args: args{
anns: map[string]string{
"konghq.com/headers.foo": "foo,",
},
},
want: map[string][]string{"foo": {"foo", ""}},
},
{
name: "no header name",
args: args{
Expand All @@ -872,6 +890,47 @@ func TestExtractHeaders(t *testing.T) {
},
want: map[string][]string{},
},
{
name: "multiple header, multiple values, trailing spaces",
args: args{
anns: map[string]string{
"konghq.com/headers.x-example": "foo, bar, baz ",
"konghq.com/headers.x-additional": "foo",
},
},
want: map[string][]string{
"x-example": {"foo", "bar", "baz"},
"x-additional": {"foo"},
},
},
{
name: "multiple header, multiple values, custom separator",
args: args{
anns: map[string]string{
"konghq.com/headers-separator": ";",
"konghq.com/headers.x-example": "foo, bar;baz",
"konghq.com/headers.x-additional": "foo",
},
},
want: map[string][]string{
"x-example": {"foo, bar", "baz"},
"x-additional": {"foo"},
},
},
{
name: "multiple header, multiple values, custom separator, leading & trailing spaces",
args: args{
anns: map[string]string{
"konghq.com/headers-separator": ";",
"konghq.com/headers.x-example": " foo, bar;cat,dog ; baz ",
"konghq.com/headers.x-additional": "foo;",
},
},
want: map[string][]string{
"x-example": {"foo, bar", "cat,dog", "baz"},
"x-additional": {"foo", ""},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down

0 comments on commit 22af5b4

Please sign in to comment.