Skip to content

Commit

Permalink
chore(admission): adapt admission server to controller-runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
czeslavo committed Sep 29, 2023
1 parent 2941d85 commit 7df8110
Show file tree
Hide file tree
Showing 20 changed files with 1,000 additions and 1,264 deletions.
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ require (
github.com/kong/go-kong v0.47.0
github.com/kong/kubernetes-telemetry v0.1.0
github.com/kong/kubernetes-testing-framework v0.39.1
github.com/lithammer/dedent v1.1.0
github.com/miekg/dns v1.1.56
github.com/mitchellh/mapstructure v1.5.0
github.com/moul/pb v0.0.0-20220425114252-bca18df4138c
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY=
github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a h1:N9zuLhTvBSRt0gWSiJswwQ2HqDmtX/ZCDJURnKUt1Ik=
github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE=
Expand Down
51 changes: 51 additions & 0 deletions internal/admission/custom_validator_adapter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package admission

import (
"context"
"errors"

"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
)

// CustomValidatorAdapter is an adapter for legacy validators in our codebase that makes them compatible with
// the new controller-runtime's CustomValidator interface.
type CustomValidatorAdapter struct {
validateCreate func(ctx context.Context, obj runtime.Object) (bool, string, error)
validateUpdate func(ctx context.Context, oldObj runtime.Object, newObj runtime.Object) (bool, string, error)
validateDelete func(ctx context.Context, obj runtime.Object) (bool, string, error)
}

func (c CustomValidatorAdapter) ValidateCreate(ctx context.Context, obj runtime.Object) (warnings admission.Warnings, err error) {
if c.validateCreate == nil {
return admission.Warnings{}, nil
}
return c.returnValues(c.validateCreate(ctx, obj))
}

func (c CustomValidatorAdapter) ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) (warnings admission.Warnings, err error) {
if c.validateUpdate == nil {
return admission.Warnings{}, nil
}
return c.returnValues(c.validateUpdate(ctx, oldObj, newObj))
}

func (c CustomValidatorAdapter) ValidateDelete(ctx context.Context, obj runtime.Object) (warnings admission.Warnings, err error) {
if c.validateDelete == nil {
return admission.Warnings{}, nil
}
return c.returnValues(c.validateDelete(ctx, obj))
}

func (c CustomValidatorAdapter) returnValues(ok bool, message string, err error) (admission.Warnings, error) {
if err != nil {
return admission.Warnings{message}, err
}
if !ok {
return admission.Warnings{message}, errors.New(message)
}
if message != "" {
return admission.Warnings{message}, nil
}
return admission.Warnings{}, nil
}
58 changes: 58 additions & 0 deletions internal/admission/gateway_validator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package admission

import (
"context"
"fmt"
"strings"

"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/client"

gatewaycontroller "github.com/kong/kubernetes-ingress-controller/v2/internal/controllers/gateway"
"github.com/kong/kubernetes-ingress-controller/v2/internal/gatewayapi"
)

func (validator KongHTTPValidator) Gateway() CustomValidatorAdapter {
return CustomValidatorAdapter{
validateCreate: func(ctx context.Context, obj runtime.Object) (bool, string, error) {
gateway, ok := obj.(*gatewayapi.Gateway)
if !ok {
return false, "", fmt.Errorf("unexpected type, expected *gatewayapi.Gateway, got %T", obj)
}
return validator.ValidateGateway(ctx, *gateway)
},
validateUpdate: func(ctx context.Context, oldObj runtime.Object, newObj runtime.Object) (bool, string, error) {
gateway, ok := newObj.(*gatewayapi.Gateway)
if !ok {
return false, "", fmt.Errorf("unexpected type, expected *gatewayapi.Gateway, got %T", newObj)
}
return validator.ValidateGateway(ctx, *gateway)
},
}
}

func (validator KongHTTPValidator) ValidateGateway(
ctx context.Context, gateway gatewayapi.Gateway,
) (bool, string, error) {
// check if the gateway declares a gateway class
if gateway.Spec.GatewayClassName == "" {
return true, "", nil
}

// validate the gatewayclass reference
gwc := gatewayapi.GatewayClass{}
if err := validator.ManagerClient.Get(ctx, client.ObjectKey{Name: string(gateway.Spec.GatewayClassName)}, &gwc); err != nil {
if strings.Contains(err.Error(), "not found") {
return true, "", nil // not managed by this controller
}
return false, ErrTextCantRetrieveGatewayClass, err
}

// validate whether the gatewayclass is a supported class, if not
// then this gateway belongs to another controller.
if gwc.Spec.ControllerName != gatewaycontroller.GetControllerName() {
return true, "", nil
}

return true, "", nil
}
Loading

0 comments on commit 7df8110

Please sign in to comment.