Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support regular expression header matches for HTTPRoute #2302

Merged
merged 7 commits into from
Mar 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,23 @@

> Release date: TBD

#### Breaking changes

- HTTPRoute header matches no longer interpret CSV values as multiple match
values, as this was not part of the HTTPRoute specification. Multiple values
should use regular expressions instead.
[#2302](https://github.com/Kong/kubernetes-ingress-controller/pull/2302)

#### Added

- Deployment manifests now include an IngressClass resource and permissions to
read IngressClass resources.
[#2292](https://github.com/Kong/kubernetes-ingress-controller/pull/2292)
- HTTPRoute header matches now support regular expressions.
[#2302](https://github.com/Kong/kubernetes-ingress-controller/pull/2302)
- HTTPRoutes that define multiple matches for the same header are rejected to
comply with the HTTPRoute specification.
[#2302](https://github.com/Kong/kubernetes-ingress-controller/pull/2302)

#### Fixed

Expand Down
5 changes: 3 additions & 2 deletions internal/dataplane/kongstate/consumer.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/blang/semver/v4"
"github.com/kong/go-kong/kong"

"github.com/kong/kubernetes-ingress-controller/v2/internal/util"
configurationv1 "github.com/kong/kubernetes-ingress-controller/v2/pkg/apis/configuration/v1"
)

Expand Down Expand Up @@ -70,7 +71,7 @@ func (c *Consumer) SanitizedCopy() *Consumer {
}
}

func (c *Consumer) SetCredential(credType string, credConfig interface{}, version semver.Version) error {
func (c *Consumer) SetCredential(credType string, credConfig interface{}) error {
switch credType {
case "key-auth", "keyauth_credential":
cred, err := NewKeyAuth(credConfig)
Expand Down Expand Up @@ -109,7 +110,7 @@ func (c *Consumer) SetCredential(credType string, credConfig interface{}, versio
}
c.ACLGroups = append(c.ACLGroups, cred)
case "mtls-auth":
if version.LT(minMTLSCredentialVersion) {
if util.GetKongVersion().LT(minMTLSCredentialVersion) {
return fmt.Errorf("controller cannot support mtls-auth below version %v", minMTLSCredentialVersion)
}
cred, err := NewMTLSAuth(credConfig)
Expand Down
76 changes: 31 additions & 45 deletions internal/dataplane/kongstate/consumer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/kong/go-kong/kong"
"github.com/stretchr/testify/assert"

"github.com/kong/kubernetes-ingress-controller/v2/internal/util"
configurationv1 "github.com/kong/kubernetes-ingress-controller/v2/pkg/apis/configuration/v1"
)

Expand Down Expand Up @@ -73,27 +74,24 @@ func TestConsumer_SanitizedCopy(t *testing.T) {

func TestConsumer_SetCredential(t *testing.T) {
username := "example"
standardVersion := semver.MustParse("2.3.2")
mtlsUnsupportedVersion := semver.MustParse("1.3.2")
type args struct {
credType string
consumer *Consumer
credConfig interface{}
version semver.Version
}
tests := []struct {
type Case struct {
name string
args args
result *Consumer
wantErr bool
}{
}
tests := []Case{
{
name: "invalid cred type errors",
args: args{
credType: "invalid-type",
consumer: &Consumer{},
credConfig: nil,
version: standardVersion,
},
result: &Consumer{},
wantErr: true,
Expand All @@ -104,7 +102,6 @@ func TestConsumer_SetCredential(t *testing.T) {
credType: "key-auth",
consumer: &Consumer{},
credConfig: map[string]string{"key": "foo"},
version: standardVersion,
},
result: &Consumer{
KeyAuths: []*KeyAuth{
Expand All @@ -121,7 +118,6 @@ func TestConsumer_SetCredential(t *testing.T) {
credType: "key-auth",
consumer: &Consumer{Consumer: kong.Consumer{Username: &username}},
credConfig: map[string]string{},
version: standardVersion,
},
result: &Consumer{Consumer: kong.Consumer{Username: &username}},
wantErr: true,
Expand All @@ -132,7 +128,6 @@ func TestConsumer_SetCredential(t *testing.T) {
credType: "key-auth",
consumer: &Consumer{Consumer: kong.Consumer{Username: &username}},
credConfig: map[string]interface{}{"key": true},
version: standardVersion,
},
result: &Consumer{Consumer: kong.Consumer{Username: &username}},
wantErr: true,
Expand All @@ -143,7 +138,6 @@ func TestConsumer_SetCredential(t *testing.T) {
credType: "keyauth_credential",
consumer: &Consumer{},
credConfig: map[string]string{"key": "foo"},
version: standardVersion,
},
result: &Consumer{
KeyAuths: []*KeyAuth{
Expand All @@ -163,7 +157,6 @@ func TestConsumer_SetCredential(t *testing.T) {
"username": "foo",
"password": "bar",
},
version: standardVersion,
},
result: &Consumer{
BasicAuths: []*BasicAuth{
Expand All @@ -181,7 +174,6 @@ func TestConsumer_SetCredential(t *testing.T) {
credType: "basic-auth",
consumer: &Consumer{Consumer: kong.Consumer{Username: &username}},
credConfig: map[string]string{},
version: standardVersion,
},
result: &Consumer{Consumer: kong.Consumer{Username: &username}},
wantErr: true,
Expand All @@ -192,7 +184,6 @@ func TestConsumer_SetCredential(t *testing.T) {
credType: "basic-auth",
consumer: &Consumer{Consumer: kong.Consumer{Username: &username}},
credConfig: map[string]interface{}{"username": true},
version: standardVersion,
},
result: &Consumer{Consumer: kong.Consumer{Username: &username}},
wantErr: true,
Expand All @@ -206,7 +197,6 @@ func TestConsumer_SetCredential(t *testing.T) {
"username": "foo",
"password": "bar",
},
version: standardVersion,
},
result: &Consumer{
BasicAuths: []*BasicAuth{
Expand All @@ -227,7 +217,6 @@ func TestConsumer_SetCredential(t *testing.T) {
"username": "foo",
"secret": "bar",
},
version: standardVersion,
},
result: &Consumer{
HMACAuths: []*HMACAuth{
Expand All @@ -245,7 +234,6 @@ func TestConsumer_SetCredential(t *testing.T) {
credType: "hmac-auth",
consumer: &Consumer{Consumer: kong.Consumer{Username: &username}},
credConfig: map[string]string{},
version: standardVersion,
},
result: &Consumer{Consumer: kong.Consumer{Username: &username}},
wantErr: true,
Expand All @@ -256,7 +244,6 @@ func TestConsumer_SetCredential(t *testing.T) {
credType: "hmac-auth",
consumer: &Consumer{Consumer: kong.Consumer{Username: &username}},
credConfig: map[string]interface{}{"username": true},
version: standardVersion,
},
result: &Consumer{Consumer: kong.Consumer{Username: &username}},
wantErr: true,
Expand All @@ -270,7 +257,6 @@ func TestConsumer_SetCredential(t *testing.T) {
"username": "foo",
"secret": "bar",
},
version: standardVersion,
},
result: &Consumer{
HMACAuths: []*HMACAuth{
Expand All @@ -293,7 +279,6 @@ func TestConsumer_SetCredential(t *testing.T) {
"client_secret": "baz",
"redirect_uris": []string{"example.com"},
},
version: standardVersion,
},
result: &Consumer{
Oauth2Creds: []*Oauth2Credential{
Expand All @@ -315,7 +300,6 @@ func TestConsumer_SetCredential(t *testing.T) {
credConfig: map[string]interface{}{
"client_id": "bar",
},
version: standardVersion,
},
result: &Consumer{Consumer: kong.Consumer{Username: &username}},
wantErr: true,
Expand All @@ -328,7 +312,6 @@ func TestConsumer_SetCredential(t *testing.T) {
credConfig: map[string]interface{}{
"name": "bar",
},
version: standardVersion,
},
result: &Consumer{Consumer: kong.Consumer{Username: &username}},
wantErr: true,
Expand All @@ -339,7 +322,6 @@ func TestConsumer_SetCredential(t *testing.T) {
credType: "oauth2",
consumer: &Consumer{Consumer: kong.Consumer{Username: &username}},
credConfig: map[string]interface{}{"client_id": true},
version: standardVersion,
},
result: &Consumer{Consumer: kong.Consumer{Username: &username}},
wantErr: true,
Expand All @@ -354,7 +336,6 @@ func TestConsumer_SetCredential(t *testing.T) {
"rsa_public_key": "bar",
"secret": "baz",
},
version: standardVersion,
},
result: &Consumer{
JWTAuths: []*JWTAuth{
Expand All @@ -375,7 +356,6 @@ func TestConsumer_SetCredential(t *testing.T) {
credType: "jwt",
consumer: &Consumer{Consumer: kong.Consumer{Username: &username}},
credConfig: map[string]string{},
version: standardVersion,
},
result: &Consumer{Consumer: kong.Consumer{Username: &username}},
wantErr: true,
Expand All @@ -386,7 +366,6 @@ func TestConsumer_SetCredential(t *testing.T) {
credType: "jwt",
consumer: &Consumer{Consumer: kong.Consumer{Username: &username}},
credConfig: map[string]interface{}{"key": true},
version: standardVersion,
},
result: &Consumer{Consumer: kong.Consumer{Username: &username}},
wantErr: true,
Expand All @@ -401,7 +380,6 @@ func TestConsumer_SetCredential(t *testing.T) {
"rsa_public_key": "bar",
"secret": "baz",
},
version: standardVersion,
},
result: &Consumer{
JWTAuths: []*JWTAuth{
Expand All @@ -422,7 +400,6 @@ func TestConsumer_SetCredential(t *testing.T) {
credType: "acl",
consumer: &Consumer{},
credConfig: map[string]string{"group": "group-foo"},
version: standardVersion,
},
result: &Consumer{
ACLGroups: []*ACLGroup{
Expand All @@ -439,7 +416,6 @@ func TestConsumer_SetCredential(t *testing.T) {
credType: "acl",
consumer: &Consumer{Consumer: kong.Consumer{Username: &username}},
credConfig: map[string]string{},
version: standardVersion,
},
result: &Consumer{Consumer: kong.Consumer{Username: &username}},
wantErr: true,
Expand All @@ -450,18 +426,40 @@ func TestConsumer_SetCredential(t *testing.T) {
credType: "acl",
consumer: &Consumer{Consumer: kong.Consumer{Username: &username}},
credConfig: map[string]interface{}{"group": true},
version: standardVersion,
},
result: &Consumer{Consumer: kong.Consumer{Username: &username}},
wantErr: true,
},
{
name: "mtls-auth on unsupported version",
args: args{
credType: "mtls-auth",
consumer: &Consumer{Consumer: kong.Consumer{Username: &username}},
credConfig: map[string]string{"subject_name": "foo@example.com"},
},
result: &Consumer{Consumer: kong.Consumer{Username: &username}},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := tt.args.consumer.SetCredential(tt.args.credType,
tt.args.credConfig); (err != nil) != tt.wantErr {
t.Errorf("processCredential() error = %v, wantErr %v",
err, tt.wantErr)
}
assert.Equal(t, tt.result, tt.args.consumer)
})
}

util.SetKongVersion(semver.MustParse("2.3.2")) // minimum version for mtls-auths with tags
mtlsSupportedTests := []Case{
{
name: "mtls-auth",
args: args{
credType: "mtls-auth",
consumer: &Consumer{Consumer: kong.Consumer{Username: &username}},
credConfig: map[string]string{"subject_name": "foo@example.com"},
version: standardVersion,
},
result: &Consumer{
Consumer: kong.Consumer{Username: &username},
Expand All @@ -479,18 +477,6 @@ func TestConsumer_SetCredential(t *testing.T) {
credType: "mtls-auth",
consumer: &Consumer{Consumer: kong.Consumer{Username: &username}},
credConfig: map[string]string{},
version: standardVersion,
},
result: &Consumer{Consumer: kong.Consumer{Username: &username}},
wantErr: true,
},
{
name: "mtls-auth on unsupported version",
args: args{
credType: "mtls-auth",
consumer: &Consumer{Consumer: kong.Consumer{Username: &username}},
credConfig: map[string]string{"subject_name": "foo@example.com"},
version: mtlsUnsupportedVersion,
},
result: &Consumer{Consumer: kong.Consumer{Username: &username}},
wantErr: true,
Expand All @@ -501,16 +487,16 @@ func TestConsumer_SetCredential(t *testing.T) {
credType: "mtls-auth",
consumer: &Consumer{Consumer: kong.Consumer{Username: &username}},
credConfig: map[string]interface{}{"subject_name": true},
version: standardVersion,
},
result: &Consumer{Consumer: kong.Consumer{Username: &username}},
wantErr: true,
},
}
for _, tt := range tests {

for _, tt := range mtlsSupportedTests {
t.Run(tt.name, func(t *testing.T) {
if err := tt.args.consumer.SetCredential(tt.args.credType,
tt.args.credConfig, tt.args.version); (err != nil) != tt.wantErr {
tt.args.credConfig); (err != nil) != tt.wantErr {
t.Errorf("processCredential() error = %v, wantErr %v",
err, tt.wantErr)
}
Expand Down
2 changes: 1 addition & 1 deletion internal/dataplane/kongstate/kongstate.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func (ks *KongState) FillConsumersAndCredentials(log logrus.FieldLogger, s store
log.Errorf("failed to provision credential: empty secret")
continue
}
err = c.SetCredential(credType, credConfig, ks.Version)
err = c.SetCredential(credType, credConfig)
if err != nil {
log.Errorf("failed to provision credential: %v", err)
continue
Expand Down
Loading