This is an automated email from the ASF dual-hosted git repository.
ronething 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 b52c26c8 feat: support custom gatewayproxy namespace for ingressclass
(#2701)
b52c26c8 is described below
commit b52c26c8519389600c968c497533c6a6cf9d485d
Author: Ashing Zheng <[email protected]>
AuthorDate: Mon Jan 12 14:26:13 2026 +0800
feat: support custom gatewayproxy namespace for ingressclass (#2701)
Signed-off-by: Ashing Zheng <[email protected]>
---
internal/controller/indexer/indexer.go | 8 +--
internal/controller/ingressclass_controller.go | 5 +-
internal/controller/utils.go | 10 +--
internal/utils/k8s.go | 12 ++++
internal/webhook/v1/ingressclass_webhook.go | 6 +-
test/e2e/crds/v2/basic.go | 91 +++++++++++++++++++++++++-
6 files changed, 109 insertions(+), 23 deletions(-)
diff --git a/internal/controller/indexer/indexer.go
b/internal/controller/indexer/indexer.go
index 91bec714..6f0d66a4 100644
--- a/internal/controller/indexer/indexer.go
+++ b/internal/controller/indexer/indexer.go
@@ -34,6 +34,7 @@ import (
apiv2 "github.com/apache/apisix-ingress-controller/api/v2"
"github.com/apache/apisix-ingress-controller/internal/adc/translator/annotations"
internaltypes
"github.com/apache/apisix-ingress-controller/internal/types"
+ k8sutils "github.com/apache/apisix-ingress-controller/internal/utils"
"github.com/apache/apisix-ingress-controller/pkg/utils"
)
@@ -859,11 +860,8 @@ func IngressClassParametersRefIndexFunc(rawObj
client.Object) []string {
ingressClass.Spec.Parameters.APIGroup != nil &&
*ingressClass.Spec.Parameters.APIGroup ==
v1alpha1.GroupVersion.Group &&
ingressClass.Spec.Parameters.Kind ==
internaltypes.KindGatewayProxy {
- ns := ingressClass.GetNamespace()
- if ingressClass.Spec.Parameters.Namespace != nil {
- ns = *ingressClass.Spec.Parameters.Namespace
- }
- return []string{GenIndexKey(ns,
ingressClass.Spec.Parameters.Name)}
+ namespace :=
k8sutils.GetIngressClassParametersNamespace(*ingressClass)
+ return []string{GenIndexKey(namespace,
ingressClass.Spec.Parameters.Name)}
}
return nil
}
diff --git a/internal/controller/ingressclass_controller.go
b/internal/controller/ingressclass_controller.go
index 5594ee6c..0afbf6f2 100644
--- a/internal/controller/ingressclass_controller.go
+++ b/internal/controller/ingressclass_controller.go
@@ -187,10 +187,7 @@ func (r *IngressClassReconciler)
processInfrastructure(tctx *provider.TranslateC
return nil
}
- namespace := ingressClass.Namespace
- if ingressClass.Spec.Parameters.Namespace != nil {
- namespace = *ingressClass.Spec.Parameters.Namespace
- }
+ namespace := utils.GetIngressClassParametersNamespace(*ingressClass)
gatewayProxy := new(v1alpha1.GatewayProxy)
if err := r.Get(context.Background(), client.ObjectKey{
diff --git a/internal/controller/utils.go b/internal/controller/utils.go
index 892d027c..a00ef916 100644
--- a/internal/controller/utils.go
+++ b/internal/controller/utils.go
@@ -1354,10 +1354,7 @@ func ProcessIngressClassParameters(tctx
*provider.TranslateContext, c client.Cli
parameters := ingressClass.Spec.Parameters
// check if the parameters reference GatewayProxy
if parameters.APIGroup != nil && *parameters.APIGroup ==
v1alpha1.GroupVersion.Group && parameters.Kind == KindGatewayProxy {
- ns := object.GetNamespace()
- if parameters.Namespace != nil {
- ns = *parameters.Namespace
- }
+ ns := utils.GetIngressClassParametersNamespace(*ingressClass)
gatewayProxy := &v1alpha1.GatewayProxy{}
if err := c.Get(tctx, client.ObjectKey{
@@ -1553,10 +1550,7 @@ func GetGatewayProxyByIngressClass(ctx context.Context,
r client.Client, ingress
return nil, nil
}
- namespace := ingressClass.Namespace
- if ingressClass.Spec.Parameters.Namespace != nil {
- namespace = *ingressClass.Spec.Parameters.Namespace
- }
+ namespace := utils.GetIngressClassParametersNamespace(*ingressClass)
gatewayProxy := new(v1alpha1.GatewayProxy)
if err := r.Get(ctx, client.ObjectKey{
diff --git a/internal/utils/k8s.go b/internal/utils/k8s.go
index 0bca19d0..0d58f301 100644
--- a/internal/utils/k8s.go
+++ b/internal/utils/k8s.go
@@ -21,6 +21,7 @@ import (
"net"
"regexp"
+ networkingv1 "k8s.io/api/networking/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8stypes "k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -99,3 +100,14 @@ func ConditionStatus(status bool) metav1.ConditionStatus {
}
return metav1.ConditionFalse
}
+
+func GetIngressClassParametersNamespace(ingressClass
networkingv1.IngressClass) string {
+ namespace := "default"
+ if ingressClass.Spec.Parameters.Namespace != nil {
+ namespace = *ingressClass.Spec.Parameters.Namespace
+ }
+ if annotationNamespace, exists :=
ingressClass.Annotations["apisix.apache.org/parameters-namespace"]; exists &&
annotationNamespace != "" {
+ namespace = annotationNamespace
+ }
+ return namespace
+}
diff --git a/internal/webhook/v1/ingressclass_webhook.go
b/internal/webhook/v1/ingressclass_webhook.go
index 4d77fe8a..67d2c360 100644
--- a/internal/webhook/v1/ingressclass_webhook.go
+++ b/internal/webhook/v1/ingressclass_webhook.go
@@ -31,6 +31,7 @@ import (
v1alpha1 "github.com/apache/apisix-ingress-controller/api/v1alpha1"
"github.com/apache/apisix-ingress-controller/internal/controller/config"
internaltypes
"github.com/apache/apisix-ingress-controller/internal/types"
+ "github.com/apache/apisix-ingress-controller/internal/utils"
)
// nolint:unused
@@ -106,10 +107,7 @@ func (v *IngressClassCustomValidator)
warnIfMissingGatewayProxyForIngressClass(c
return nil
}
- ns := ingressClass.GetNamespace()
- if params.Namespace != nil && *params.Namespace != "" {
- ns = *params.Namespace
- }
+ ns := utils.GetIngressClassParametersNamespace(*ingressClass)
name := params.Name
var gp v1alpha1.GatewayProxy
diff --git a/test/e2e/crds/v2/basic.go b/test/e2e/crds/v2/basic.go
index 36205d5c..65415340 100644
--- a/test/e2e/crds/v2/basic.go
+++ b/test/e2e/crds/v2/basic.go
@@ -18,16 +18,26 @@
package v2
import (
+ "fmt"
+ "net/http"
+ "time"
+
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
+ "k8s.io/apimachinery/pkg/types"
+ apiv2 "github.com/apache/apisix-ingress-controller/api/v2"
+ "github.com/apache/apisix-ingress-controller/test/e2e/framework"
"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
)
var _ = Describe("APISIX Standalone Basic Tests", Label("apisix.apache.org",
"v2", "basic"), func() {
- s := scaffold.NewDefaultScaffold()
+ var (
+ s = scaffold.NewDefaultScaffold()
+ applier = framework.NewApplier(s.GinkgoT, s.K8sClient,
s.CreateResourceFromString)
+ )
- Describe("APISIX HTTP Proxy", func() {
+ Context("APISIX HTTP Proxy", func() {
It("should handle basic HTTP requests", func() {
httpClient := s.NewAPISIXClient()
Expect(httpClient).NotTo(BeNil())
@@ -52,4 +62,81 @@ var _ = Describe("APISIX Standalone Basic Tests",
Label("apisix.apache.org", "v2
})
})
+
+ Context("IngressClass Annotations", func() {
+ It("Basic tests", func() {
+ const ingressClassYaml = `
+apiVersion: networking.k8s.io/v1
+kind: IngressClass
+metadata:
+ name: %s
+ annotations:
+ apisix.apache.org/parameters-namespace: %s
+spec:
+ controller: %s
+ parameters:
+ apiGroup: apisix.apache.org
+ kind: GatewayProxy
+ name: apisix-proxy-config
+`
+
+ By("create GatewayProxy")
+
+ err :=
s.CreateResourceFromString(s.GetGatewayProxySpec())
+ Expect(err).NotTo(HaveOccurred(), "creating
GatewayProxy")
+ time.Sleep(5 * time.Second)
+
+ By("create IngressClass")
+ ingressClass := fmt.Sprintf(ingressClassYaml,
s.Namespace(), s.Namespace(), s.GetControllerName())
+ err = s.CreateResourceFromString(ingressClass)
+ Expect(err).NotTo(HaveOccurred(), "creating
IngressClass")
+ time.Sleep(5 * time.Second)
+
+ const apisixRouteSpec = `
+apiVersion: apisix.apache.org/v2
+kind: ApisixRoute
+metadata:
+ name: default
+spec:
+ ingressClassName: %s
+ http:
+ - name: rule0
+ match:
+ hosts:
+ - httpbin
+ paths:
+ - %s
+ backends:
+ - serviceName: httpbin-service-e2e-test
+ servicePort: 80
+`
+ request := func(path string) int {
+ return
s.NewAPISIXClient().GET(path).WithHost("httpbin").Expect().Raw().StatusCode
+ }
+
+ By("apply ApisixRoute")
+ var apisixRoute apiv2.ApisixRoute
+ applier.MustApplyAPIv2(types.NamespacedName{Namespace:
s.Namespace(), Name: "default"}, &apisixRoute,
+ fmt.Sprintf(apisixRouteSpec, s.Namespace(),
"/get"))
+
+ By("verify ApisixRoute works")
+ Eventually(request).WithArguments("/get").WithTimeout(8
* time.Second).ProbeEvery(time.Second).Should(Equal(http.StatusOK))
+
+ By("update ApisixRoute")
+ applier.MustApplyAPIv2(types.NamespacedName{Namespace:
s.Namespace(), Name: "default"}, &apisixRoute,
+ fmt.Sprintf(apisixRouteSpec, s.Namespace(),
"/headers"))
+ Eventually(request).WithArguments("/get").WithTimeout(8
* time.Second).ProbeEvery(time.Second).Should(Equal(http.StatusNotFound))
+ s.RequestAssert(&scaffold.RequestAssert{
+ Method: "GET",
+ Path: "/headers",
+ Host: "httpbin",
+ Check:
scaffold.WithExpectedStatus(http.StatusOK),
+ })
+
+ By("delete ApisixRoute")
+ err = s.DeleteResource("ApisixRoute", "default")
+ Expect(err).ShouldNot(HaveOccurred(), "deleting
ApisixRoute")
+
Eventually(request).WithArguments("/headers").WithTimeout(8 *
time.Second).ProbeEvery(time.Second).Should(Equal(http.StatusNotFound))
+ })
+ })
})