Skip to content

Commit

Permalink
Adds AuthenticationFilter Support to Kubernetes Provider (#791)
Browse files Browse the repository at this point in the history
Adds AuthenticationFilter Support to Kube Provider

Signed-off-by: danehans <daneyonhansen@gmail.com>

Signed-off-by: danehans <daneyonhansen@gmail.com>
  • Loading branch information
danehans committed Dec 19, 2022
1 parent 46b7b75 commit f420fe1
Show file tree
Hide file tree
Showing 17 changed files with 677 additions and 65 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ release-artifacts/

# Outputs
coverage.xml
cover.out

# `go mod vendor`
vendor/
Expand Down
11 changes: 8 additions & 3 deletions api/v1alpha1/authenticationfilter_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const (
// AuthenticationFilterKind is the name of the AuthenticationFilter kind.
AuthenticationFilterKind = "AuthenticationFilter"
)

//+kubebuilder:object:root=true

type AuthenticationFilter struct {
Expand Down Expand Up @@ -114,13 +119,13 @@ type RemoteJWKS struct {

//+kubebuilder:object:root=true

// AuthenticationList contains a list of Authentication.
type AuthenticationList struct {
// AuthenticationFilterList contains a list of AuthenticationFilter.
type AuthenticationFilterList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []AuthenticationFilter `json:"items"`
}

func init() {
SchemeBuilder.Register(&AuthenticationFilter{}, &AuthenticationList{})
SchemeBuilder.Register(&AuthenticationFilter{}, &AuthenticationFilterList{})
}
48 changes: 24 additions & 24 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 8 additions & 2 deletions internal/envoygateway/scheme.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import (
gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
gwapiv1b1 "sigs.k8s.io/gateway-api/apis/v1beta1"

"github.com/envoyproxy/gateway/api/config/v1alpha1"
egcfgv1a1 "github.com/envoyproxy/gateway/api/config/v1alpha1"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
)

var (
Expand All @@ -28,9 +29,14 @@ func init() {
if err := clientgoscheme.AddToScheme(scheme); err != nil {
panic(err)
}
if err := v1alpha1.AddToScheme(scheme); err != nil {
// Add Envoy Gateway types.
if err := egcfgv1a1.AddToScheme(scheme); err != nil {
panic(err)
}
if err := egv1a1.AddToScheme(scheme); err != nil {
panic(err)
}
// Add Gateway API types.
if err := gwapiv1b1.AddToScheme(scheme); err != nil {
panic(err)
}
Expand Down
30 changes: 30 additions & 0 deletions internal/gatewayapi/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@
package gatewayapi

import (
"errors"
"fmt"
"strings"

"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/gateway-api/apis/v1alpha2"
"sigs.k8s.io/gateway-api/apis/v1beta1"

egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
)

const (
Expand Down Expand Up @@ -246,3 +250,29 @@ func layer4Protocol(protocolPort *ProtocolPort) string {
return UDPProtocol
}
}

// ValidateHTTPRouteFilter validates the provided filter.
func ValidateHTTPRouteFilter(filter *v1beta1.HTTPRouteFilter) error {
switch {
case filter == nil:
return errors.New("filter is nil")
case filter.Type == v1beta1.HTTPRouteFilterRequestMirror ||
filter.Type == v1beta1.HTTPRouteFilterURLRewrite ||
filter.Type == v1beta1.HTTPRouteFilterRequestRedirect ||
filter.Type == v1beta1.HTTPRouteFilterRequestHeaderModifier:
return nil
case filter.Type == v1beta1.HTTPRouteFilterExtensionRef:
switch {
case filter.ExtensionRef == nil:
return errors.New("extensionRef field must be specified for an extended filter")
case string(filter.ExtensionRef.Group) != egv1a1.GroupVersion.Group:
return fmt.Errorf("invalid group; must be %s", egv1a1.GroupVersion.Group)
case string(filter.ExtensionRef.Kind) != egv1a1.AuthenticationFilterKind:
return fmt.Errorf("invalid kind; must be %s", egv1a1.AuthenticationFilterKind)
default:
return nil
}
}

return fmt.Errorf("unsupported filter type: %v", filter.Type)
}
125 changes: 125 additions & 0 deletions internal/gatewayapi/helpers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
// Copyright Envoy Gateway Authors
// SPDX-License-Identifier: Apache-2.0
// The full text of the Apache license is available in the LICENSE file at
// the root of the repo.

// This file contains code derived from Contour,
// https://github.com/projectcontour/contour
// and is provided here subject to the following:
// Copyright Project Contour Authors
// SPDX-License-Identifier: Apache-2.0

package gatewayapi

import (
"testing"

"github.com/stretchr/testify/require"
gwapiv1b1 "sigs.k8s.io/gateway-api/apis/v1beta1"

egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
)

func TestValidateAuthenFilterRef(t *testing.T) {
testCases := []struct {
name string
filter *gwapiv1b1.HTTPRouteFilter
expected bool
}{
{
name: "request mirror filter",
filter: &gwapiv1b1.HTTPRouteFilter{
Type: gwapiv1b1.HTTPRouteFilterRequestMirror,
},
expected: true,
},
{
name: "url rewrite filter",
filter: &gwapiv1b1.HTTPRouteFilter{
Type: gwapiv1b1.HTTPRouteFilterURLRewrite,
},
expected: true,
},
{
name: "request header modifier filter",
filter: &gwapiv1b1.HTTPRouteFilter{
Type: gwapiv1b1.HTTPRouteFilterRequestHeaderModifier,
},
expected: true,
},
{
name: "request redirect filter",
filter: &gwapiv1b1.HTTPRouteFilter{
Type: gwapiv1b1.HTTPRouteFilterRequestRedirect,
},
expected: true,
},
{
name: "unsupported extended filter",
filter: &gwapiv1b1.HTTPRouteFilter{
Type: gwapiv1b1.HTTPRouteFilterExtensionRef,
ExtensionRef: &gwapiv1b1.LocalObjectReference{
Group: "UnsupportedGroup",
Kind: "UnsupportedKind",
Name: "test",
},
},
expected: false,
},
{
name: "extended filter with missing reference",
filter: &gwapiv1b1.HTTPRouteFilter{
Type: gwapiv1b1.HTTPRouteFilterExtensionRef,
},
expected: false,
},
{
name: "invalid authenticationfilter group",
filter: &gwapiv1b1.HTTPRouteFilter{
Type: gwapiv1b1.HTTPRouteFilterExtensionRef,
ExtensionRef: &gwapiv1b1.LocalObjectReference{
Group: "UnsupportedGroup",
Kind: egv1a1.AuthenticationFilterKind,
Name: "test",
},
},
expected: false,
},
{
name: "invalid authenticationfilter kind",
filter: &gwapiv1b1.HTTPRouteFilter{
Type: gwapiv1b1.HTTPRouteFilterExtensionRef,
ExtensionRef: &gwapiv1b1.LocalObjectReference{
Group: gwapiv1b1.Group(egv1a1.GroupVersion.Group),
Kind: "UnsupportedKind",
Name: "test",
},
},
expected: false,
},
{
name: "valid authenticationfilter",
filter: &gwapiv1b1.HTTPRouteFilter{
Type: gwapiv1b1.HTTPRouteFilterExtensionRef,
ExtensionRef: &gwapiv1b1.LocalObjectReference{
Group: gwapiv1b1.Group(egv1a1.GroupVersion.Group),
Kind: egv1a1.AuthenticationFilterKind,
Name: "test",
},
},
expected: true,
},
}

for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
err := ValidateHTTPRouteFilter(tc.filter)
if tc.expected {
require.NoError(t, err)
} else {
require.Error(t, err)
}
})
}
}
15 changes: 15 additions & 0 deletions internal/gatewayapi/translator.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"sigs.k8s.io/gateway-api/apis/v1alpha2"
"sigs.k8s.io/gateway-api/apis/v1beta1"

egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/ir"
)

Expand Down Expand Up @@ -58,6 +59,20 @@ type Resources struct {
Namespaces []*v1.Namespace
Services []*v1.Service
Secrets []*v1.Secret
AuthenFilters []*egv1a1.AuthenticationFilter
}

func NewResources() *Resources {
return &Resources{
Gateways: []*v1beta1.Gateway{},
HTTPRoutes: []*v1beta1.HTTPRoute{},
TLSRoutes: []*v1alpha2.TLSRoute{},
Services: []*v1.Service{},
Secrets: []*v1.Secret{},
ReferenceGrants: []*v1alpha2.ReferenceGrant{},
Namespaces: []*v1.Namespace{},
AuthenFilters: []*egv1a1.AuthenticationFilter{},
}
}

func (r *Resources) GetNamespace(name string) *v1.Namespace {
Expand Down
12 changes: 12 additions & 0 deletions internal/gatewayapi/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions internal/provider/kubernetes/config/crd/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# It should be run by config/default
resources:
- bases/config.gateway.envoyproxy.io_envoyproxies.yaml
- bases/gateway.envoyproxy.io_authenticationfilters.yaml
#+kubebuilder:scaffold:crdkustomizeresource

patchesStrategicMerge:
Expand Down
9 changes: 9 additions & 0 deletions internal/provider/kubernetes/config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ rules:
- get
- list
- watch
- apiGroups:
- gateway.envoyproxy.io
resources:
- authenticationfilters
verbs:
- get
- list
- update
- watch
- apiGroups:
- gateway.networking.k8s.io
resources:
Expand Down
Loading

0 comments on commit f420fe1

Please sign in to comment.