Skip to content

Commit 7be81e9

Browse files
authored
feat: support custom gatewayproxy namespace for ingressclass (#222)
Signed-off-by: Ashing Zheng <[email protected]>
1 parent 33d357d commit 7be81e9

File tree

5 files changed

+123
-10
lines changed

5 files changed

+123
-10
lines changed

internal/controller/ingressclass_controller.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,10 @@ func (r *IngressClassReconciler) processInfrastructure(tctx *provider.TranslateC
191191
if ingressClass.Spec.Parameters.Namespace != nil {
192192
namespace = *ingressClass.Spec.Parameters.Namespace
193193
}
194+
// Check for annotation override
195+
if annotationNamespace, exists := ingressClass.Annotations[parametersNamespaceAnnotation]; exists && annotationNamespace != "" {
196+
namespace = annotationNamespace
197+
}
194198

195199
gatewayProxy := new(v1alpha1.GatewayProxy)
196200
if err := r.Get(context.Background(), client.ObjectKey{

internal/controller/ingressclass_v1beta1_controller.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,12 +188,17 @@ func (r *IngressClassV1beta1Reconciler) processInfrastructure(tctx *provider.Tra
188188
}
189189

190190
// Since v1beta1 does not support specifying the target namespace,
191-
// and GatewayProxy is a namespace-scoped resource, we default to using
192-
// the "default" namespace for convenience.
191+
// and GatewayProxy is a namespace-scoped resource, we first check
192+
// for the annotation, then fall back to the spec field, and finally
193+
// default to "default" namespace for convenience.
193194
namespace := "default"
194195
if IngressClassV1beta1.Spec.Parameters.Namespace != nil {
195196
namespace = *IngressClassV1beta1.Spec.Parameters.Namespace
196197
}
198+
// Check for annotation override
199+
if annotationNamespace, exists := IngressClassV1beta1.Annotations[parametersNamespaceAnnotation]; exists && annotationNamespace != "" {
200+
namespace = annotationNamespace
201+
}
197202

198203
gatewayProxy := new(v1alpha1.GatewayProxy)
199204
if err := r.Get(tctx, client.ObjectKey{

internal/controller/utils.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,10 @@ const (
7777
KindApisixConsumer = "ApisixConsumer"
7878
)
7979

80-
const defaultIngressClassAnnotation = "ingressclass.kubernetes.io/is-default-class"
80+
const (
81+
defaultIngressClassAnnotation = "ingressclass.kubernetes.io/is-default-class"
82+
parametersNamespaceAnnotation = "apisix.apache.org/parameters-namespace"
83+
)
8184

8285
var (
8386
ErrNoMatchingListenerHostname = errors.New("no matching hostnames in listener")
@@ -1323,6 +1326,9 @@ func ProcessIngressClassParameters(tctx *provider.TranslateContext, c client.Cli
13231326
if parameters.Namespace != nil {
13241327
ns = *parameters.Namespace
13251328
}
1329+
if annotationNamespace, exists := ingressClass.Annotations[parametersNamespaceAnnotation]; exists && annotationNamespace != "" {
1330+
ns = annotationNamespace
1331+
}
13261332

13271333
gatewayProxy := &v1alpha1.GatewayProxy{}
13281334
if err := c.Get(tctx, client.ObjectKey{

test/e2e/crds/v2/basic.go

Lines changed: 105 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,16 @@
1818
package v2
1919

2020
import (
21+
"fmt"
22+
"net/http"
23+
"time"
24+
2125
. "github.com/onsi/ginkgo/v2"
2226
. "github.com/onsi/gomega"
27+
"k8s.io/apimachinery/pkg/types"
2328

29+
apiv2 "github.com/apache/apisix-ingress-controller/api/v2"
30+
"github.com/apache/apisix-ingress-controller/test/e2e/framework"
2431
"github.com/apache/apisix-ingress-controller/test/e2e/scaffold"
2532
)
2633

@@ -56,11 +63,14 @@ spec:
5663
`
5764

5865
var _ = Describe("APISIX Standalone Basic Tests", Label("apisix.apache.org", "v2", "basic"), func() {
59-
s := scaffold.NewScaffold(&scaffold.Options{
60-
ControllerName: "apisix.apache.org/apisix-ingress-controller",
61-
})
66+
var (
67+
s = scaffold.NewScaffold(&scaffold.Options{
68+
ControllerName: "apisix.apache.org/apisix-ingress-controller",
69+
})
70+
applier = framework.NewApplier(s.GinkgoT, s.K8sClient, s.CreateResourceFromString)
71+
)
6272

63-
Describe("APISIX HTTP Proxy", func() {
73+
Context("APISIX HTTP Proxy", func() {
6474
It("should handle basic HTTP requests", func() {
6575
httpClient := s.NewAPISIXClient()
6676
Expect(httpClient).NotTo(BeNil())
@@ -83,6 +93,97 @@ var _ = Describe("APISIX Standalone Basic Tests", Label("apisix.apache.org", "v2
8393
Expect().
8494
Status(404).Body().Contains("404 Route Not Found")
8595
})
96+
})
97+
98+
Context("IngressClass Annotations", func() {
99+
It("Basic tests", func() {
100+
const gatewayProxyYaml = `
101+
apiVersion: apisix.apache.org/v1alpha1
102+
kind: GatewayProxy
103+
metadata:
104+
name: apisix-proxy-config
105+
spec:
106+
provider:
107+
type: ControlPlane
108+
controlPlane:
109+
endpoints:
110+
- %s
111+
auth:
112+
type: AdminKey
113+
adminKey:
114+
value: "%s"
115+
`
86116

117+
const ingressClassYaml = `
118+
apiVersion: networking.k8s.io/%s
119+
kind: IngressClass
120+
metadata:
121+
name: apisix
122+
annotations:
123+
apisix.apache.org/parameters-namespace: %s
124+
spec:
125+
controller: apisix.apache.org/apisix-ingress-controller
126+
parameters:
127+
apiGroup: apisix.apache.org
128+
kind: GatewayProxy
129+
name: apisix-proxy-config
130+
`
131+
132+
By("create GatewayProxy")
133+
gatewayProxy := fmt.Sprintf(gatewayProxyYaml, s.Deployer.GetAdminEndpoint(), s.AdminKey())
134+
err := s.CreateResourceFromString(gatewayProxy)
135+
Expect(err).NotTo(HaveOccurred(), "creating GatewayProxy")
136+
time.Sleep(5 * time.Second)
137+
138+
By("create IngressClass")
139+
ingressClass := fmt.Sprintf(ingressClassYaml, framework.IngressVersion, s.Namespace())
140+
err = s.CreateResourceFromString(ingressClass)
141+
Expect(err).NotTo(HaveOccurred(), "creating IngressClass")
142+
time.Sleep(5 * time.Second)
143+
144+
const apisixRouteSpec = `
145+
apiVersion: apisix.apache.org/v2
146+
kind: ApisixRoute
147+
metadata:
148+
name: default
149+
spec:
150+
ingressClassName: apisix
151+
http:
152+
- name: rule0
153+
match:
154+
hosts:
155+
- httpbin
156+
paths:
157+
- %s
158+
backends:
159+
- serviceName: httpbin-service-e2e-test
160+
servicePort: 80
161+
`
162+
request := func(path string) int {
163+
return s.NewAPISIXClient().GET(path).WithHost("httpbin").Expect().Raw().StatusCode
164+
}
165+
166+
By("apply ApisixRoute")
167+
var apisixRoute apiv2.ApisixRoute
168+
applier.MustApplyAPIv2(types.NamespacedName{Namespace: s.Namespace(), Name: "default"}, &apisixRoute, fmt.Sprintf(apisixRouteSpec, "/get"))
169+
170+
By("verify ApisixRoute works")
171+
Eventually(request).WithArguments("/get").WithTimeout(8 * time.Second).ProbeEvery(time.Second).Should(Equal(http.StatusOK))
172+
173+
By("update ApisixRoute")
174+
applier.MustApplyAPIv2(types.NamespacedName{Namespace: s.Namespace(), Name: "default"}, &apisixRoute, fmt.Sprintf(apisixRouteSpec, "/headers"))
175+
Eventually(request).WithArguments("/get").WithTimeout(8 * time.Second).ProbeEvery(time.Second).Should(Equal(http.StatusNotFound))
176+
s.RequestAssert(&scaffold.RequestAssert{
177+
Method: "GET",
178+
Path: "/headers",
179+
Host: "httpbin",
180+
Check: scaffold.WithExpectedStatus(http.StatusOK),
181+
})
182+
183+
By("delete ApisixRoute")
184+
err = s.DeleteResource("ApisixRoute", "default")
185+
Expect(err).ShouldNot(HaveOccurred(), "deleting ApisixRoute")
186+
Eventually(request).WithArguments("/headers").WithTimeout(8 * time.Second).ProbeEvery(time.Second).Should(Equal(http.StatusNotFound))
187+
})
87188
})
88189
})

test/e2e/crds/v2/route.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,6 @@ spec:
132132
Expect(bodyStr).Should(ContainSubstring("apisix_ingress_adc_sync_total"))
133133
Expect(bodyStr).Should(ContainSubstring("apisix_ingress_status_update_queue_length"))
134134
Expect(bodyStr).Should(ContainSubstring("apisix_ingress_file_io_duration_seconds"))
135-
136-
// Log metrics for debugging
137-
fmt.Printf("Metrics endpoint response:\n%s\n", bodyStr)
138135
})
139136

140137
It("Test plugins in ApisixRoute", func() {

0 commit comments

Comments
 (0)