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

chore(admission): adapt admission server to controller-runtime #4763

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
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
Loading