This is an automated email from the ASF dual-hosted git repository.
alinsran pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix-ingress-controller.git
The following commit(s) were added to refs/heads/master by this push:
new 0a7b0402 fix: residual data issue when updating ingressClassName
(#2543)
0a7b0402 is described below
commit 0a7b0402528091e7435674a2ef42e2742e2a297e
Author: AlinsRan <[email protected]>
AuthorDate: Mon Sep 8 12:26:19 2025 +0800
fix: residual data issue when updating ingressClassName (#2543)
---
internal/controller/apisixconsumer_controller.go | 13 +---
internal/controller/apisixglobalrule_controller.go | 51 ++-------------
.../controller/apisixpluginconfig_controller.go | 2 +-
internal/controller/apisixroute_controller.go | 12 +++-
internal/controller/apisixtls_controller.go | 46 +-------------
internal/controller/apisixupstream_controller.go | 2 +-
internal/controller/httproutepolicy.go | 2 +-
internal/controller/ingress_controller.go | 31 +++------
internal/controller/utils.go | 74 +++++++++++++---------
internal/manager/controllers.go | 3 +-
internal/types/k8s.go | 7 ++
test/e2e/crds/v2/route.go | 55 ++++++++++++++++
test/e2e/framework/ingress.go | 2 +-
test/e2e/framework/manifests/ingress.yaml | 9 +++
test/e2e/ingress/ingress.go | 56 ++++++++++++++++
test/e2e/scaffold/apisix_deployer.go | 4 +-
16 files changed, 207 insertions(+), 162 deletions(-)
diff --git a/internal/controller/apisixconsumer_controller.go
b/internal/controller/apisixconsumer_controller.go
index 6f591ca5..2cb473ca 100644
--- a/internal/controller/apisixconsumer_controller.go
+++ b/internal/controller/apisixconsumer_controller.go
@@ -83,7 +83,7 @@ func (r *ApisixConsumerReconciler) Reconcile(ctx
context.Context, req ctrl.Reque
ingressClass *networkingv1.IngressClass
err error
)
- if ingressClass, err = GetIngressClass(tctx, r.Client, r.Log,
ac.Spec.IngressClassName); err != nil {
+ if ingressClass, err = FindMatchingIngressClass(tctx, r.Client, r.Log,
ac); err != nil {
r.Log.V(1).Info("no matching IngressClass available",
"ingressClassName", ac.Spec.IngressClassName,
"error", err.Error())
@@ -113,7 +113,7 @@ func (r *ApisixConsumerReconciler) SetupWithManager(mgr
ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&apiv2.ApisixConsumer{},
builder.WithPredicates(
-
predicate.NewPredicateFuncs(r.checkIngressClass),
+ MatchesIngressClassPredicate(r.Client, r.Log),
)).
WithEventFilter(
predicate.Or(
@@ -139,15 +139,6 @@ func (r *ApisixConsumerReconciler) SetupWithManager(mgr
ctrl.Manager) error {
Complete(r)
}
-func (r *ApisixConsumerReconciler) checkIngressClass(obj client.Object) bool {
- ac, ok := obj.(*apiv2.ApisixConsumer)
- if !ok {
- return false
- }
-
- return matchesIngressClass(r.Client, r.Log, ac.Spec.IngressClassName)
-}
-
func (r *ApisixConsumerReconciler) listApisixConsumerForGatewayProxy(ctx
context.Context, obj client.Object) []reconcile.Request {
return listIngressClassRequestsForGatewayProxy(ctx, r.Client, obj,
r.Log, r.listApisixConsumerForIngressClass)
}
diff --git a/internal/controller/apisixglobalrule_controller.go
b/internal/controller/apisixglobalrule_controller.go
index cd14ee30..f99eab68 100644
--- a/internal/controller/apisixglobalrule_controller.go
+++ b/internal/controller/apisixglobalrule_controller.go
@@ -35,8 +35,6 @@ import (
"github.com/apache/apisix-ingress-controller/api/v1alpha1"
apiv2 "github.com/apache/apisix-ingress-controller/api/v2"
- "github.com/apache/apisix-ingress-controller/internal/controller/config"
-
"github.com/apache/apisix-ingress-controller/internal/controller/indexer"
"github.com/apache/apisix-ingress-controller/internal/controller/status"
"github.com/apache/apisix-ingress-controller/internal/manager/readiness"
"github.com/apache/apisix-ingress-controller/internal/provider"
@@ -84,11 +82,15 @@ func (r *ApisixGlobalRuleReconciler) Reconcile(ctx
context.Context, req ctrl.Req
tctx := provider.NewDefaultTranslateContext(ctx)
// get the ingress class
- ingressClass, err := GetIngressClass(tctx, r.Client, r.Log,
globalRule.Spec.IngressClassName)
+ ingressClass, err := FindMatchingIngressClass(tctx, r.Client, r.Log,
&globalRule)
if err != nil {
r.Log.V(1).Info("no matching IngressClass available",
"ingressClassName", globalRule.Spec.IngressClassName,
"error", err.Error())
+ if err := r.Provider.Delete(ctx, &globalRule); err != nil {
+ r.Log.Error(err, "failed to delete global rule from
provider")
+ return ctrl.Result{}, err
+ }
return ctrl.Result{}, nil
}
@@ -131,7 +133,7 @@ func (r *ApisixGlobalRuleReconciler) SetupWithManager(mgr
ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&apiv2.ApisixGlobalRule{},
builder.WithPredicates(
-
predicate.NewPredicateFuncs(r.checkIngressClass),
+ MatchesIngressClassPredicate(r.Client, r.Log),
),
).
WithEventFilter(
@@ -154,47 +156,6 @@ func (r *ApisixGlobalRuleReconciler) SetupWithManager(mgr
ctrl.Manager) error {
Complete(r)
}
-// checkIngressClass checks if the ApisixGlobalRule uses the ingress class
that we control
-func (r *ApisixGlobalRuleReconciler) checkIngressClass(obj client.Object) bool
{
- globalRule, ok := obj.(*apiv2.ApisixGlobalRule)
- if !ok {
- return false
- }
-
- return r.matchesIngressClass(globalRule.Spec.IngressClassName)
-}
-
-// matchesIngressClass checks if the given ingress class name matches our
controlled classes
-func (r *ApisixGlobalRuleReconciler) matchesIngressClass(ingressClassName
string) bool {
- if ingressClassName == "" {
- // Check for default ingress class
- ingressClassList := &networkingv1.IngressClassList{}
- if err := r.List(context.Background(), ingressClassList,
client.MatchingFields{
- indexer.IngressClass: config.GetControllerName(),
- }); err != nil {
- r.Log.Error(err, "failed to list ingress classes")
- return false
- }
-
- // Find the ingress class that is marked as default
- for _, ic := range ingressClassList.Items {
- if IsDefaultIngressClass(&ic) &&
matchesController(ic.Spec.Controller) {
- return true
- }
- }
- return false
- }
-
- // Check if the specified ingress class is controlled by us
- var ingressClass networkingv1.IngressClass
- if err := r.Get(context.Background(), client.ObjectKey{Name:
ingressClassName}, &ingressClass); err != nil {
- r.Log.Error(err, "failed to get ingress class", "ingressClass",
ingressClassName)
- return false
- }
-
- return matchesController(ingressClass.Spec.Controller)
-}
-
// listGlobalRulesForIngressClass list all global rules that use a specific
ingress class
func (r *ApisixGlobalRuleReconciler) listGlobalRulesForIngressClass(ctx
context.Context, obj client.Object) []reconcile.Request {
ingressClass, ok := obj.(*networkingv1.IngressClass)
diff --git a/internal/controller/apisixpluginconfig_controller.go
b/internal/controller/apisixpluginconfig_controller.go
index 7ac25d1b..8751d107 100644
--- a/internal/controller/apisixpluginconfig_controller.go
+++ b/internal/controller/apisixpluginconfig_controller.go
@@ -58,7 +58,7 @@ func (r *ApisixPluginConfigReconciler) Reconcile(ctx
context.Context, req ctrl.R
tctx := provider.NewDefaultTranslateContext(ctx)
- _, err := GetIngressClass(tctx, r.Client, r.Log,
pc.Spec.IngressClassName)
+ _, err := FindMatchingIngressClass(tctx, r.Client, r.Log, &pc)
if err != nil {
r.Log.V(1).Info("no matching IngressClass available",
"ingressClassName", pc.Spec.IngressClassName,
diff --git a/internal/controller/apisixroute_controller.go
b/internal/controller/apisixroute_controller.go
index 4e9ff5cd..2616e595 100644
--- a/internal/controller/apisixroute_controller.go
+++ b/internal/controller/apisixroute_controller.go
@@ -64,7 +64,11 @@ type ApisixRouteReconciler struct {
// SetupWithManager sets up the controller with the Manager.
func (r *ApisixRouteReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
- For(&apiv2.ApisixRoute{}).
+ For(&apiv2.ApisixRoute{},
+ builder.WithPredicates(
+ MatchesIngressClassPredicate(r.Client, r.Log),
+ ),
+ ).
WithEventFilter(
predicate.Or(
predicate.GenerationChangedPredicate{},
@@ -125,10 +129,14 @@ func (r *ApisixRouteReconciler) Reconcile(ctx
context.Context, req ctrl.Request)
err error
)
- if ic, err = GetIngressClass(tctx, r.Client, r.Log,
ar.Spec.IngressClassName); err != nil {
+ if ic, err = FindMatchingIngressClass(tctx, r.Client, r.Log, &ar); err
!= nil {
r.Log.V(1).Info("no matching IngressClass available",
"ingressClassName", ar.Spec.IngressClassName,
"error", err.Error())
+ if err := r.Provider.Delete(ctx, &ar); err != nil {
+ r.Log.Error(err, "failed to delete apisixroute",
"apisixroute", ar)
+ return ctrl.Result{}, err
+ }
return ctrl.Result{}, nil
}
defer func() { r.updateStatus(&ar, err) }()
diff --git a/internal/controller/apisixtls_controller.go
b/internal/controller/apisixtls_controller.go
index eb4b8a66..4758f728 100644
--- a/internal/controller/apisixtls_controller.go
+++ b/internal/controller/apisixtls_controller.go
@@ -36,7 +36,6 @@ import (
"github.com/apache/apisix-ingress-controller/api/v1alpha1"
apiv2 "github.com/apache/apisix-ingress-controller/api/v2"
- "github.com/apache/apisix-ingress-controller/internal/controller/config"
"github.com/apache/apisix-ingress-controller/internal/controller/indexer"
"github.com/apache/apisix-ingress-controller/internal/controller/status"
"github.com/apache/apisix-ingress-controller/internal/manager/readiness"
@@ -59,7 +58,7 @@ func (r *ApisixTlsReconciler) SetupWithManager(mgr
ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&apiv2.ApisixTls{},
builder.WithPredicates(
-
predicate.NewPredicateFuncs(r.checkIngressClass),
+ MatchesIngressClassPredicate(r.Client, r.Log),
),
).
WithEventFilter(
@@ -115,7 +114,7 @@ func (r *ApisixTlsReconciler) Reconcile(ctx
context.Context, req ctrl.Request) (
tctx := provider.NewDefaultTranslateContext(ctx)
// get the ingress class
- ingressClass, err := GetIngressClass(tctx, r.Client, r.Log,
tls.Spec.IngressClassName)
+ ingressClass, err := FindMatchingIngressClass(tctx, r.Client, r.Log,
&tls)
if err != nil {
r.Log.V(1).Info("no matching IngressClass available, skip
processing",
"ingressClassName", tls.Spec.IngressClassName,
@@ -227,47 +226,6 @@ func (r *ApisixTlsReconciler) updateStatus(tls
*apiv2.ApisixTls, condition metav
})
}
-// checkIngressClass checks if the ApisixTls uses the ingress class that we
control
-func (r *ApisixTlsReconciler) checkIngressClass(obj client.Object) bool {
- tls, ok := obj.(*apiv2.ApisixTls)
- if !ok {
- return false
- }
-
- return r.matchesIngressClass(tls.Spec.IngressClassName)
-}
-
-// matchesIngressClass checks if the given ingress class name matches our
controlled classes
-func (r *ApisixTlsReconciler) matchesIngressClass(ingressClassName string)
bool {
- if ingressClassName == "" {
- // Check for default ingress class
- ingressClassList := &networkingv1.IngressClassList{}
- if err := r.List(context.Background(), ingressClassList,
client.MatchingFields{
- indexer.IngressClass: config.GetControllerName(),
- }); err != nil {
- r.Log.Error(err, "failed to list ingress classes")
- return false
- }
-
- // Find the ingress class that is marked as default
- for _, ic := range ingressClassList.Items {
- if IsDefaultIngressClass(&ic) &&
matchesController(ic.Spec.Controller) {
- return true
- }
- }
- return false
- }
-
- // Check if the specified ingress class is controlled by us
- var ingressClass networkingv1.IngressClass
- if err := r.Get(context.Background(), client.ObjectKey{Name:
ingressClassName}, &ingressClass); err != nil {
- r.Log.Error(err, "failed to get ingress class", "ingressClass",
ingressClassName)
- return false
- }
-
- return matchesController(ingressClass.Spec.Controller)
-}
-
func (r *ApisixTlsReconciler) listApisixTlsForSecret(ctx context.Context, obj
client.Object) []reconcile.Request {
secret, ok := obj.(*corev1.Secret)
if !ok {
diff --git a/internal/controller/apisixupstream_controller.go
b/internal/controller/apisixupstream_controller.go
index dad9d968..14dba916 100644
--- a/internal/controller/apisixupstream_controller.go
+++ b/internal/controller/apisixupstream_controller.go
@@ -57,7 +57,7 @@ func (r *ApisixUpstreamReconciler) Reconcile(ctx
context.Context, req ctrl.Reque
tctx := provider.NewDefaultTranslateContext(ctx)
- _, err := GetIngressClass(tctx, r.Client, r.Log,
au.Spec.IngressClassName)
+ _, err := FindMatchingIngressClass(tctx, r.Client, r.Log, &au)
if err != nil {
r.Log.V(1).Info("no matching IngressClass available, skip
processing",
"ingressClassName", au.Spec.IngressClassName,
diff --git a/internal/controller/httproutepolicy.go
b/internal/controller/httproutepolicy.go
index f829cb6c..260b09e5 100644
--- a/internal/controller/httproutepolicy.go
+++ b/internal/controller/httproutepolicy.go
@@ -198,7 +198,7 @@ func (r *IngressReconciler)
updateHTTPRoutePolicyStatusOnDeleting(ctx context.Co
if err := r.Get(ctx, namespacedName, &ingress);
err != nil {
continue
}
- ingressClass, err := r.getIngressClass(ctx,
&ingress)
+ ingressClass, err :=
FindMatchingIngressClass(ctx, r.Client, r.Log, &ingress)
if err != nil {
continue
}
diff --git a/internal/controller/ingress_controller.go
b/internal/controller/ingress_controller.go
index 25b52990..c86b40c2 100644
--- a/internal/controller/ingress_controller.go
+++ b/internal/controller/ingress_controller.go
@@ -70,7 +70,7 @@ func (r *IngressReconciler) SetupWithManager(mgr
ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&networkingv1.Ingress{},
builder.WithPredicates(
-
predicate.NewPredicateFuncs(r.checkIngressClass),
+ MatchesIngressClassPredicate(r.Client, r.Log),
),
).
WithEventFilter(
@@ -151,10 +151,13 @@ func (r *IngressReconciler) Reconcile(ctx
context.Context, req ctrl.Request) (ct
// create a translate context
tctx := provider.NewDefaultTranslateContext(ctx)
- ingressClass, err := r.getIngressClass(ctx, ingress)
+ ingressClass, err := FindMatchingIngressClass(tctx, r.Client, r.Log,
ingress)
if err != nil {
- r.Log.Error(err, "failed to get IngressClass")
- return ctrl.Result{}, err
+ if err := r.Provider.Delete(ctx, ingress); err != nil {
+ r.Log.Error(err, "failed to delete ingress resources",
"ingress", ingress.Name)
+ return ctrl.Result{}, nil
+ }
+ return ctrl.Result{}, nil
}
tctx.RouteParentRefs = append(tctx.RouteParentRefs,
gatewayv1.ParentReference{
@@ -207,22 +210,6 @@ func (r *IngressReconciler) Reconcile(ctx context.Context,
req ctrl.Request) (ct
return ctrl.Result{}, nil
}
-// getIngressClass get the ingress class for the ingress
-func (r *IngressReconciler) getIngressClass(ctx context.Context, obj
client.Object) (*networkingv1.IngressClass, error) {
- ingress := obj.(*networkingv1.Ingress)
- var ingressClassName string
- if ingress.Spec.IngressClassName != nil {
- ingressClassName = *ingress.Spec.IngressClassName
- }
- return GetIngressClass(ctx, r.Client, r.Log, ingressClassName)
-}
-
-// checkIngressClass check if the ingress uses the ingress class that we
control
-func (r *IngressReconciler) checkIngressClass(obj client.Object) bool {
- _, err := r.getIngressClass(context.Background(), obj)
- return err == nil
-}
-
// matchesIngressController check if the ingress class is controlled by us
func (r *IngressReconciler) matchesIngressController(obj client.Object) bool {
ingressClass, ok := obj.(*networkingv1.IngressClass)
@@ -307,7 +294,7 @@ func (r *IngressReconciler) listIngressesByService(ctx
context.Context, obj clie
requests := make([]reconcile.Request, 0, len(ingressList.Items))
for _, ingress := range ingressList.Items {
- if r.checkIngressClass(&ingress) {
+ if MatchesIngressClass(r.Client, r.Log, &ingress) {
requests = append(requests, reconcile.Request{
NamespacedName: client.ObjectKey{
Namespace: ingress.Namespace,
@@ -340,7 +327,7 @@ func (r *IngressReconciler) listIngressesBySecret(ctx
context.Context, obj clien
requests := make([]reconcile.Request, 0, len(ingressList.Items))
for _, ingress := range ingressList.Items {
- if r.checkIngressClass(&ingress) {
+ if MatchesIngressClass(r.Client, r.Log, &ingress) {
requests = append(requests, reconcile.Request{
NamespacedName: client.ObjectKey{
Namespace: ingress.Namespace,
diff --git a/internal/controller/utils.go b/internal/controller/utils.go
index bf47a1de..3d0c5018 100644
--- a/internal/controller/utils.go
+++ b/internal/controller/utils.go
@@ -40,6 +40,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
k8stypes "k8s.io/apimachinery/pkg/types"
+ "k8s.io/utils/ptr"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/event"
"sigs.k8s.io/controller-runtime/pkg/predicate"
@@ -1261,36 +1262,6 @@ func matchesIngressController(obj client.Object) bool {
return matchesController(ingressClass.Spec.Controller)
}
-func matchesIngressClass(c client.Client, log logr.Logger, ingressClassName
string) bool {
- if ingressClassName == "" {
- // Check for default ingress class
- ingressClassList := &networkingv1.IngressClassList{}
- if err := c.List(context.Background(), ingressClassList,
client.MatchingFields{
- indexer.IngressClass: config.GetControllerName(),
- }); err != nil {
- log.Error(err, "failed to list ingress classes")
- return false
- }
-
- // Find the ingress class that is marked as default
- for _, ic := range ingressClassList.Items {
- if IsDefaultIngressClass(&ic) &&
matchesController(ic.Spec.Controller) {
- return true
- }
- }
- return false
- }
-
- // Check if the specified ingress class is controlled by us
- var ingressClass networkingv1.IngressClass
- if err := c.Get(context.Background(), client.ObjectKey{Name:
ingressClassName}, &ingressClass); err != nil {
- log.Error(err, "failed to get ingress class", "ingressClass",
ingressClassName)
- return false
- }
-
- return matchesController(ingressClass.Spec.Controller)
-}
-
func ProcessIngressClassParameters(tctx *provider.TranslateContext, c
client.Client, log logr.Logger, object client.Object, ingressClass
*networkingv1.IngressClass) error {
if ingressClass == nil || ingressClass.Spec.Parameters == nil {
return nil
@@ -1368,7 +1339,12 @@ func ProcessIngressClassParameters(tctx
*provider.TranslateContext, c client.Cli
return nil
}
-func GetIngressClass(ctx context.Context, c client.Client, log logr.Logger,
ingressClassName string) (*networkingv1.IngressClass, error) {
+func FindMatchingIngressClass(ctx context.Context, c client.Client, log
logr.Logger, obj client.Object) (*networkingv1.IngressClass, error) {
+ ingressClassName := ExtractIngressClass(obj)
+ return FindMatchingIngressClassByName(ctx, c, log, ingressClassName)
+}
+
+func FindMatchingIngressClassByName(ctx context.Context, c client.Client, log
logr.Logger, ingressClassName string) (*networkingv1.IngressClass, error) {
if ingressClassName == "" {
// Check for default ingress class
ingressClassList := &networkingv1.IngressClassList{}
@@ -1533,3 +1509,39 @@ func GetGatewayProxyByGateway(ctx context.Context, r
client.Client, gateway *gat
}
return gatewayProxy, nil
}
+
+func MatchesIngressClassPredicate(c client.Client, log logr.Logger)
predicate.Funcs {
+ predicateFuncs := predicate.NewPredicateFuncs(func(obj client.Object)
bool {
+ return MatchesIngressClass(c, log, obj)
+ })
+ predicateFuncs.UpdateFunc = func(e event.UpdateEvent) bool {
+ return MatchesIngressClass(c, log, e.ObjectOld) ||
MatchesIngressClass(c, log, e.ObjectNew)
+ }
+ return predicateFuncs
+}
+
+func MatchesIngressClass(c client.Client, log logr.Logger, obj client.Object)
bool {
+ _, err := FindMatchingIngressClass(context.Background(), c, log, obj)
+ return err == nil
+}
+
+func ExtractIngressClass(obj client.Object) string {
+ switch v := obj.(type) {
+ case *networkingv1.Ingress:
+ return ptr.Deref(v.Spec.IngressClassName, "")
+ case *apiv2.ApisixConsumer:
+ return v.Spec.IngressClassName
+ case *apiv2.ApisixRoute:
+ return v.Spec.IngressClassName
+ case *apiv2.ApisixTls:
+ return v.Spec.IngressClassName
+ case *apiv2.ApisixPluginConfig:
+ return v.Spec.IngressClassName
+ case *apiv2.ApisixUpstream:
+ return v.Spec.IngressClassName
+ case *apiv2.ApisixGlobalRule:
+ return v.Spec.IngressClassName
+ default:
+ panic(fmt.Errorf("unhandled object type %T for extracting
ingress class", obj))
+ }
+}
diff --git a/internal/manager/controllers.go b/internal/manager/controllers.go
index 0688055d..6c878b21 100644
--- a/internal/manager/controllers.go
+++ b/internal/manager/controllers.go
@@ -210,10 +210,11 @@ func registerReadinessGVK(c client.Client, readier
readiness.ReadinessManager) {
types.GvkOf(&apiv2.ApisixPluginConfig{}),
types.GvkOf(&apiv2.ApisixTls{}),
types.GvkOf(&apiv2.ApisixConsumer{}),
+ types.GvkOf(&apiv2.ApisixUpstream{}),
},
Filter: readiness.GVKFilter(func(obj
*unstructured.Unstructured) bool {
icName, _, _ :=
unstructured.NestedString(obj.Object, "spec", "ingressClassName")
- ingressClass, _ :=
controller.GetIngressClass(context.Background(), c, log, icName)
+ ingressClass, _ :=
controller.FindMatchingIngressClassByName(context.Background(), c, log, icName)
return ingressClass != nil
}),
},
diff --git a/internal/types/k8s.go b/internal/types/k8s.go
index d83158fe..3f50033a 100644
--- a/internal/types/k8s.go
+++ b/internal/types/k8s.go
@@ -48,6 +48,7 @@ const (
KindBackendTrafficPolicy = "BackendTrafficPolicy"
KindConsumer = "Consumer"
KindPluginConfig = "PluginConfig"
+ KindApisixUpstream = "ApisixUpstream"
)
func KindOf(obj any) string {
@@ -132,6 +133,12 @@ func GvkOf(obj any) schema.GroupVersionKind {
Version: "v2",
Kind: KindApisixConsumer,
}
+ case *v2.ApisixUpstream:
+ return schema.GroupVersionKind{
+ Group: "apisix.apache.org",
+ Version: "v2",
+ Kind: KindApisixUpstream,
+ }
case *v1alpha1.HTTPRoutePolicy:
return schema.GroupVersionKind{
Group: "apisix.apache.org",
diff --git a/test/e2e/crds/v2/route.go b/test/e2e/crds/v2/route.go
index c60d01b0..4e593ef6 100644
--- a/test/e2e/crds/v2/route.go
+++ b/test/e2e/crds/v2/route.go
@@ -526,6 +526,61 @@ spec:
Check:
scaffold.WithExpectedStatus(http.StatusOK),
})
})
+
+ It("IngressClassName Change", func() {
+ const apisixRouteSpec = `
+apiVersion: apisix.apache.org/v2
+kind: ApisixRoute
+metadata:
+ name: default
+spec:
+ ingressClassName: %s
+ http:
+ - name: rule0
+ match:
+ hosts:
+ - httpbin
+ paths:
+ - /get
+ backends:
+ - serviceName: httpbin-service-e2e-test
+ servicePort: 80
+`
+
+ By("apply ApisixRoute")
+ var apisixRoute apiv2.ApisixRoute
+ applier.MustApplyAPIv2(types.NamespacedName{Namespace:
s.Namespace(), Name: "default"},
+ &apisixRoute, fmt.Sprintf(apisixRouteSpec,
s.Namespace()))
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin",
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
+ })
+
+ By("change IngressClassName to invalid")
+ err :=
s.CreateResourceFromString(fmt.Sprintf(apisixRouteSpec, "invalid"))
+ Expect(err).NotTo(HaveOccurred(), "creating ApisixRoute
with IngressClass")
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin",
+ Check:
scaffold.WithExpectedStatus(http.StatusNotFound),
+ })
+
+ By("change IngressClassName to default")
+ applier.MustApplyAPIv2(types.NamespacedName{Namespace:
s.Namespace(), Name: "default"},
+ &apisixRoute, fmt.Sprintf(apisixRouteSpec,
s.Namespace()))
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "httpbin",
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
+ })
+ })
})
Context("Test ApisixRoute reference ApisixUpstream", func() {
diff --git a/test/e2e/framework/ingress.go b/test/e2e/framework/ingress.go
index 11de509c..e77db052 100644
--- a/test/e2e/framework/ingress.go
+++ b/test/e2e/framework/ingress.go
@@ -49,7 +49,7 @@ type IngressDeployOpts struct {
ProviderSyncPeriod time.Duration
Namespace string
StatusAddress string
- Replicas int
+ Replicas *int
InitSyncDelay time.Duration
}
diff --git a/test/e2e/framework/manifests/ingress.yaml
b/test/e2e/framework/manifests/ingress.yaml
index c411a93d..ae0f440b 100644
--- a/test/e2e/framework/manifests/ingress.yaml
+++ b/test/e2e/framework/manifests/ingress.yaml
@@ -326,6 +326,15 @@ data:
log_level: "debug"
controller_name: {{ .ControllerName | default
"apisix.apache.org/apisix-ingress-controller" }}
leader_election_id: "apisix-ingress-controller-leader"
+ leader_election:
+ lease_duration: 10s # lease_duration is the duration
that non-leader candidates will wait
+ # after observing a leadership
renewal until attempting to acquire leadership of a
+ # leader election.
+ renew_deadline: 5s # renew_deadline is the time in
seconds that the acting controller
+ # will retry refreshing leadership
before giving up.
+ retry_period: 2s # retry_period is the time in
seconds that the acting controller
+ # will wait between tries of
actions with the controller.
+ disable: false # Whether to disable leader
election.
exec_adc_timeout: 5s
provider:
type: {{ .ProviderType | default "apisix" }}
diff --git a/test/e2e/ingress/ingress.go b/test/e2e/ingress/ingress.go
index eb93db67..b61e3109 100644
--- a/test/e2e/ingress/ingress.go
+++ b/test/e2e/ingress/ingress.go
@@ -178,6 +178,26 @@ spec:
number: 80
`
+ var ingressSpec = `
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: %s
+spec:
+ ingressClassName: %s
+ rules:
+ - host: default.example.com
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: httpbin-service-e2e-test
+ port:
+ number: 80
+`
+
var ingressWithExternalName = `
apiVersion: v1
kind: Service
@@ -322,6 +342,42 @@ spec:
Expect().
Status(404)
})
+
+ It("IngressClassName Change", func() {
+ By("create Ingress with IngressClass")
+ err :=
s.CreateResourceFromString(fmt.Sprintf(ingressSpec, s.Namespace(),
"apisix-default"))
+ Expect(err).NotTo(HaveOccurred(), "creating Ingress
with IngressClass")
+
+ By("verify default ingress")
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "default.example.com",
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
+ })
+
+ By("change IngressClassName to invalid")
+ err =
s.CreateResourceFromString(fmt.Sprintf(ingressSpec, s.Namespace(), "invalid"))
+ Expect(err).NotTo(HaveOccurred(), "creating Ingress
with IngressClass")
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "default.example.com",
+ Check:
scaffold.WithExpectedStatus(http.StatusNotFound),
+ })
+
+ By("change IngressClassName to default")
+ err =
s.CreateResourceFromString(fmt.Sprintf(ingressSpec, s.Namespace(),
"apisix-default"))
+ Expect(err).NotTo(HaveOccurred(), "creating Ingress
with IngressClass")
+
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/get",
+ Host: "default.example.com",
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
+ })
+ })
})
// Tests concerning the default ingress class need to be run serially
diff --git a/test/e2e/scaffold/apisix_deployer.go
b/test/e2e/scaffold/apisix_deployer.go
index cab432ff..57f15cb5 100644
--- a/test/e2e/scaffold/apisix_deployer.go
+++ b/test/e2e/scaffold/apisix_deployer.go
@@ -258,7 +258,7 @@ func (s *APISIXDeployer) DeployIngress() {
ProviderType: framework.ProviderType,
ProviderSyncPeriod: 1 * time.Hour,
Namespace: s.namespace,
- Replicas: 1,
+ Replicas: ptr.To(1),
})
}
@@ -268,7 +268,7 @@ func (s *APISIXDeployer) ScaleIngress(replicas int) {
ProviderType: framework.ProviderType,
ProviderSyncPeriod: 1 * time.Hour,
Namespace: s.namespace,
- Replicas: replicas,
+ Replicas: ptr.To(replicas),
})
}