Skip to content

Commit

Permalink
feat(routes) add path handling annotation
Browse files Browse the repository at this point in the history
  • Loading branch information
rainest committed Nov 2, 2022
1 parent e16bca7 commit e4d6c22
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 1 deletion.
10 changes: 10 additions & 0 deletions internal/annotations/annotations.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ const (
ReadTimeoutKey = "/read-timeout"
RetriesKey = "/retries"
HeadersKey = "/headers"
PathHandlingKey = "/path-handling"

// GatewayClassUnmanagedAnnotationSuffix is an annotation used on a Gateway resource to
// indicate that the GatewayClass should be reconciled according to unmanaged
Expand Down Expand Up @@ -313,6 +314,15 @@ func ExtractHeaders(anns map[string]string) (map[string][]string, bool) {
return headers, true
}

// ExtractPathHandling extracts the path handling annotation value.
func ExtractPathHandling(anns map[string]string) (string, bool) {
val, exists := anns[AnnotationPrefix+PathHandlingKey]
if !exists {
return "", false
}
return val, true
}

// ExtractUnmanagedGatewayClassMode extracts the value of the unmanaged gateway
// mode annotation.
func ExtractUnmanagedGatewayClassMode(anns map[string]string) string {
Expand Down
38 changes: 38 additions & 0 deletions internal/annotations/annotations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -894,3 +894,41 @@ func TestExtractHeaders(t *testing.T) {
})
}
}

func TestExtractPathHandling(t *testing.T) {
type args struct {
anns map[string]string
}
tests := []struct {
name string
args args
want string
}{
{
name: "empty",
want: "",
},
{
name: "non-empty",
args: args{
anns: map[string]string{
"konghq.com/path-handling": "v1",
},
},
want: "v1",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, ok := ExtractRetries(tt.args.anns)
if tt.want == "" {
assert.False(t, ok)
} else {
assert.True(t, ok)
}
if got != tt.want {
t.Errorf("ExtractPathHandling() = %v, want %v", got, tt.want)
}
})
}
}
18 changes: 17 additions & 1 deletion internal/dataplane/kongstate/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ type Route struct {
}

var (
validMethods = regexp.MustCompile(`\A[A-Z]+$`)
validMethods = regexp.MustCompile(`\A[A-Z]+$`)
validPathHandling = regexp.MustCompile(`v\d`)

// hostnames are complicated. shamelessly cribbed from https://stackoverflow.com/a/18494710
// TODO if the Kong core adds support for wildcard SNI route match criteria, this should change.
Expand Down Expand Up @@ -229,6 +230,7 @@ func (r *Route) overrideByAnnotation(log logrus.FieldLogger) {
r.overrideResponseBuffering(log, r.Ingress.Annotations)
r.overrideHosts(log, r.Ingress.Annotations)
r.overrideHeaders(r.Ingress.Annotations)
r.overridePathHandling(log, r.Ingress.Annotations)
}

// override sets Route fields by KongIngress first, then by annotation.
Expand Down Expand Up @@ -414,3 +416,17 @@ func (r *Route) overrideHeaders(anns map[string]string) {
}
r.Headers = headers
}

func (r *Route) overridePathHandling(log logrus.FieldLogger, anns map[string]string) {
val, ok := annotations.ExtractPathHandling(anns)
if !ok {
return
}

if !validPathHandling.MatchString(val) {
log.WithField("kongroute", r.Name).Errorf("invalid path_handling value: %s", val)
return
}

r.PathHandling = kong.String(val)
}
46 changes: 46 additions & 0 deletions internal/dataplane/kongstate/route_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1137,3 +1137,49 @@ func TestOverrideHeaders(t *testing.T) {
})
}
}

func TestOverridePathHandling(t *testing.T) {
type args struct {
route Route
anns map[string]string
}
tests := []struct {
name string
args args
want Route
}{
{name: "basic empty route"},
{
name: "expected value",
args: args{
anns: map[string]string{
"konghq.com/path-handling": "v1",
},
},
want: Route{
Route: kong.Route{
PathHandling: kong.String("v1"),
},
},
},
{
name: "invalid value",
args: args{
anns: map[string]string{
"konghq.com/path-handling": "vA",
},
},
want: Route{
Route: kong.Route{},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.args.route.overridePathHandling(logrus.New(), tt.args.anns)
if !reflect.DeepEqual(tt.args.route, tt.want) {
t.Errorf("overridePathHandling() got = %v, want %v", tt.args.route, tt.want)
}
})
}
}

0 comments on commit e4d6c22

Please sign in to comment.