Skip to content
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
60 changes: 60 additions & 0 deletions config/webhook/manifests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,46 @@ webhooks:
resources:
- gatewayproxies
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
service:
name: webhook-service
namespace: system
path: /validate-gateway-networking-k8s-io-v1-grpcroute
failurePolicy: Fail
name: vgrpcroute-v1.kb.io
rules:
- apiGroups:
- gateway.networking.k8s.io
apiVersions:
- v1
operations:
- CREATE
- UPDATE
resources:
- grpcroutes
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
service:
name: webhook-service
namespace: system
path: /validate-gateway-networking-k8s-io-v1-httproute
failurePolicy: Fail
name: vhttproute-v1.kb.io
rules:
- apiGroups:
- gateway.networking.k8s.io
apiVersions:
- v1
operations:
- CREATE
- UPDATE
resources:
- httproutes
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
Expand Down Expand Up @@ -164,3 +204,23 @@ webhooks:
resources:
- ingressclasses
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
service:
name: webhook-service
namespace: system
path: /validate-gateway-networking-k8s-io-v1alpha2-tcproute
failurePolicy: Fail
name: vtcproute-v1alpha2.kb.io
rules:
- apiGroups:
- gateway.networking.k8s.io
apiVersions:
- v1alpha2
operations:
- CREATE
- UPDATE
resources:
- tcproutes
sideEffects: None
1 change: 0 additions & 1 deletion internal/controller/grpcroute_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,6 @@ func (r *GRPCRouteReconciler) listGRPCRoutesForBackendTrafficPolicy(ctx context.
r.Log.Error(fmt.Errorf("unexpected object type"), "failed to convert object to BackendTrafficPolicy")
return nil
}

grpcRouteList := []gatewayv1.GRPCRoute{}
for _, targetRef := range policy.Spec.TargetRefs {
service := &corev1.Service{}
Expand Down
9 changes: 9 additions & 0 deletions internal/manager/webhooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ func setupWebhooks(_ context.Context, mgr manager.Manager) error {
if err := webhookv1.SetupGatewayProxyWebhookWithManager(mgr); err != nil {
return err
}
if err := webhookv1.SetupHTTPRouteWebhookWithManager(mgr); err != nil {
return err
}
if err := webhookv1.SetupGRPCRouteWebhookWithManager(mgr); err != nil {
return err
}
if err := webhookv1.SetupTCPRouteWebhookWithManager(mgr); err != nil {
return err
}
if err := webhookv1.SetupApisixConsumerWebhookWithManager(mgr); err != nil {
return err
}
Expand Down
8 changes: 8 additions & 0 deletions internal/webhook/v1/apisixconsumer_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"

apisixv2 "github.com/apache/apisix-ingress-controller/api/v2"
"github.com/apache/apisix-ingress-controller/internal/controller"
"github.com/apache/apisix-ingress-controller/internal/webhook/v1/reference"
)

Expand Down Expand Up @@ -64,6 +65,10 @@ func (v *ApisixConsumerCustomValidator) ValidateCreate(ctx context.Context, obj
}
apisixConsumerLog.Info("Validation for ApisixConsumer upon creation", "name", consumer.GetName(), "namespace", consumer.GetNamespace())

if !controller.MatchesIngressClass(v.Client, apisixConsumerLog, consumer, "") {
return nil, nil
}

return v.collectWarnings(ctx, consumer), nil
}

Expand All @@ -73,6 +78,9 @@ func (v *ApisixConsumerCustomValidator) ValidateUpdate(ctx context.Context, oldO
return nil, fmt.Errorf("expected an ApisixConsumer object for the newObj but got %T", newObj)
}
apisixConsumerLog.Info("Validation for ApisixConsumer upon update", "name", consumer.GetName(), "namespace", consumer.GetNamespace())
if !controller.MatchesIngressClass(v.Client, apisixConsumerLog, consumer, "") {
return nil, nil
}

return v.collectWarnings(ctx, consumer), nil
}
Expand Down
23 changes: 20 additions & 3 deletions internal/webhook/v1/apisixconsumer_webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,39 @@ import (

"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
"sigs.k8s.io/controller-runtime/pkg/client/fake"

apisixv2 "github.com/apache/apisix-ingress-controller/api/v2"
"github.com/apache/apisix-ingress-controller/internal/controller/config"
)

func buildApisixConsumerValidator(t *testing.T, objects ...runtime.Object) *ApisixConsumerCustomValidator {
t.Helper()

scheme := runtime.NewScheme()
require.NoError(t, clientgoscheme.AddToScheme(scheme))
require.NoError(t, networkingv1.AddToScheme(scheme))
require.NoError(t, apisixv2.AddToScheme(scheme))

builder := fake.NewClientBuilder().WithScheme(scheme)
if len(objects) > 0 {
builder = builder.WithRuntimeObjects(objects...)
managed := []runtime.Object{
&networkingv1.IngressClass{
ObjectMeta: metav1.ObjectMeta{
Name: "apisix",
Annotations: map[string]string{
"ingressclass.kubernetes.io/is-default-class": "true",
},
},
Spec: networkingv1.IngressClassSpec{
Controller: config.ControllerConfig.ControllerName,
},
},
}
allObjects := append(managed, objects...)
builder := fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(allObjects...)

return NewApisixConsumerCustomValidator(builder.Build())
}
Expand All @@ -51,6 +65,7 @@ func TestApisixConsumerValidator_MissingBasicAuthSecret(t *testing.T) {
Namespace: "default",
},
Spec: apisixv2.ApisixConsumerSpec{
IngressClassName: "apisix",
AuthParameter: apisixv2.ApisixConsumerAuthParameter{
BasicAuth: &apisixv2.ApisixConsumerBasicAuth{
SecretRef: &corev1.LocalObjectReference{Name: "basic-auth"},
Expand All @@ -74,6 +89,7 @@ func TestApisixConsumerValidator_MultipleSecretWarnings(t *testing.T) {
Namespace: "default",
},
Spec: apisixv2.ApisixConsumerSpec{
IngressClassName: "apisix",
AuthParameter: apisixv2.ApisixConsumerAuthParameter{
BasicAuth: &apisixv2.ApisixConsumerBasicAuth{
SecretRef: &corev1.LocalObjectReference{Name: "basic-auth"},
Expand Down Expand Up @@ -113,6 +129,7 @@ func TestApisixConsumerValidator_NoWarningsWhenSecretsExist(t *testing.T) {
Namespace: "default",
},
Spec: apisixv2.ApisixConsumerSpec{
IngressClassName: "apisix",
AuthParameter: apisixv2.ApisixConsumerAuthParameter{
KeyAuth: &apisixv2.ApisixConsumerKeyAuth{
SecretRef: &corev1.LocalObjectReference{Name: "key-auth"},
Expand Down
7 changes: 7 additions & 0 deletions internal/webhook/v1/apisixroute_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"

apisixv2 "github.com/apache/apisix-ingress-controller/api/v2"
"github.com/apache/apisix-ingress-controller/internal/controller"
"github.com/apache/apisix-ingress-controller/internal/webhook/v1/reference"
)

Expand Down Expand Up @@ -62,6 +63,9 @@ func (v *ApisixRouteCustomValidator) ValidateCreate(ctx context.Context, obj run
return nil, fmt.Errorf("expected an ApisixRoute object but got %T", obj)
}
apisixRouteLog.Info("Validation for ApisixRoute upon creation", "name", route.GetName(), "namespace", route.GetNamespace())
if !controller.MatchesIngressClass(v.Client, apisixRouteLog, route, "") {
return nil, nil
}

return v.collectWarnings(ctx, route), nil
}
Expand All @@ -72,6 +76,9 @@ func (v *ApisixRouteCustomValidator) ValidateUpdate(ctx context.Context, oldObj,
return nil, fmt.Errorf("expected an ApisixRoute object for the newObj but got %T", newObj)
}
apisixRouteLog.Info("Validation for ApisixRoute upon update", "name", route.GetName(), "namespace", route.GetNamespace())
if !controller.MatchesIngressClass(v.Client, apisixRouteLog, route, "") {
return nil, nil
}

return v.collectWarnings(ctx, route), nil
}
Expand Down
24 changes: 21 additions & 3 deletions internal/webhook/v1/apisixroute_webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,39 @@ import (

"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
"sigs.k8s.io/controller-runtime/pkg/client/fake"

apisixv2 "github.com/apache/apisix-ingress-controller/api/v2"
"github.com/apache/apisix-ingress-controller/internal/controller/config"
)

func buildApisixRouteValidator(t *testing.T, objects ...runtime.Object) *ApisixRouteCustomValidator {
t.Helper()

scheme := runtime.NewScheme()
require.NoError(t, clientgoscheme.AddToScheme(scheme))
require.NoError(t, networkingv1.AddToScheme(scheme))
require.NoError(t, apisixv2.AddToScheme(scheme))

builder := fake.NewClientBuilder().WithScheme(scheme)
if len(objects) > 0 {
builder = builder.WithRuntimeObjects(objects...)
managed := []runtime.Object{
&networkingv1.IngressClass{
ObjectMeta: metav1.ObjectMeta{
Name: "apisix",
Annotations: map[string]string{
"ingressclass.kubernetes.io/is-default-class": "true",
},
},
Spec: networkingv1.IngressClassSpec{
Controller: config.ControllerConfig.ControllerName,
},
},
}
allObjects := append(managed, objects...)
builder := fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(allObjects...)

return NewApisixRouteCustomValidator(builder.Build())
}
Expand All @@ -51,6 +65,7 @@ func TestApisixRouteValidator_MissingHTTPService(t *testing.T) {
Namespace: "default",
},
Spec: apisixv2.ApisixRouteSpec{
IngressClassName: "apisix",
HTTP: []apisixv2.ApisixRouteHTTP{{
Name: "rule",
Backends: []apisixv2.ApisixRouteHTTPBackend{{
Expand All @@ -75,6 +90,7 @@ func TestApisixRouteValidator_MissingPluginSecret(t *testing.T) {
Namespace: "default",
},
Spec: apisixv2.ApisixRouteSpec{
IngressClassName: "apisix",
HTTP: []apisixv2.ApisixRouteHTTP{{
Name: "rule",
Backends: []apisixv2.ApisixRouteHTTPBackend{{
Expand Down Expand Up @@ -106,6 +122,7 @@ func TestApisixRouteValidator_MissingStreamService(t *testing.T) {
Namespace: "default",
},
Spec: apisixv2.ApisixRouteSpec{
IngressClassName: "apisix",
Stream: []apisixv2.ApisixRouteStream{{
Name: "stream",
Protocol: "TCP",
Expand All @@ -131,6 +148,7 @@ func TestApisixRouteValidator_NoWarnings(t *testing.T) {
Namespace: "default",
},
Spec: apisixv2.ApisixRouteSpec{
IngressClassName: "apisix",
HTTP: []apisixv2.ApisixRouteHTTP{{
Name: "rule",
Backends: []apisixv2.ApisixRouteHTTPBackend{{
Expand Down
7 changes: 7 additions & 0 deletions internal/webhook/v1/apisixtls_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"

apisixv2 "github.com/apache/apisix-ingress-controller/api/v2"
"github.com/apache/apisix-ingress-controller/internal/controller"
"github.com/apache/apisix-ingress-controller/internal/webhook/v1/reference"
)

Expand Down Expand Up @@ -62,6 +63,9 @@ func (v *ApisixTlsCustomValidator) ValidateCreate(ctx context.Context, obj runti
return nil, fmt.Errorf("expected an ApisixTls object but got %T", obj)
}
apisixTlsLog.Info("Validation for ApisixTls upon creation", "name", tls.GetName(), "namespace", tls.GetNamespace())
if !controller.MatchesIngressClass(v.Client, apisixTlsLog, tls, "") {
return nil, nil
}

return v.collectWarnings(ctx, tls), nil
}
Expand All @@ -72,6 +76,9 @@ func (v *ApisixTlsCustomValidator) ValidateUpdate(ctx context.Context, oldObj, n
return nil, fmt.Errorf("expected an ApisixTls object for the newObj but got %T", newObj)
}
apisixTlsLog.Info("Validation for ApisixTls upon update", "name", tls.GetName(), "namespace", tls.GetNamespace())
if !controller.MatchesIngressClass(v.Client, apisixTlsLog, tls, "") {
return nil, nil
}

return v.collectWarnings(ctx, tls), nil
}
Expand Down
23 changes: 19 additions & 4 deletions internal/webhook/v1/apisixtls_webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,39 @@ import (

"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
"sigs.k8s.io/controller-runtime/pkg/client/fake"

apisixv2 "github.com/apache/apisix-ingress-controller/api/v2"
"github.com/apache/apisix-ingress-controller/internal/controller/config"
)

func buildApisixTlsValidator(t *testing.T, objects ...runtime.Object) *ApisixTlsCustomValidator {
t.Helper()

scheme := runtime.NewScheme()
require.NoError(t, clientgoscheme.AddToScheme(scheme))
require.NoError(t, networkingv1.AddToScheme(scheme))
require.NoError(t, apisixv2.AddToScheme(scheme))

builder := fake.NewClientBuilder().WithScheme(scheme)
if len(objects) > 0 {
builder = builder.WithRuntimeObjects(objects...)
managed := []runtime.Object{
&networkingv1.IngressClass{
ObjectMeta: metav1.ObjectMeta{
Name: "apisix",
Annotations: map[string]string{
"ingressclass.kubernetes.io/is-default-class": "true",
},
},
Spec: networkingv1.IngressClassSpec{
Controller: config.ControllerConfig.ControllerName,
},
},
}
allObjects := append(managed, objects...)
builder := fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(allObjects...)

return NewApisixTlsCustomValidator(builder.Build())
}
Expand All @@ -51,7 +65,8 @@ func newApisixTls() *apisixv2.ApisixTls {
Namespace: "default",
},
Spec: apisixv2.ApisixTlsSpec{
Hosts: []apisixv2.HostType{"example.com"},
IngressClassName: "apisix",
Hosts: []apisixv2.HostType{"example.com"},
Secret: apisixv2.ApisixSecret{
Name: "server-cert",
Namespace: "default",
Expand Down
Loading
Loading