Skip to content

Commit 8ba5d71

Browse files
authored
chore: Add e2e tests for GatewayProxy referencing Secret (#123)
1 parent 4248014 commit 8ba5d71

File tree

12 files changed

+236
-37
lines changed

12 files changed

+236
-37
lines changed

.golangci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ linters:
2424
revive:
2525
rules:
2626
- name: comment-spacings
27+
lll:
28+
line-length: 160
2729
exclusions:
2830
generated: lax
2931
rules:

internal/controller/consumer_controller.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,15 @@ func (r *ConsumerReconciler) SetupWithManager(mgr ctrl.Manager) error {
4040
predicate.NewPredicateFuncs(r.checkGatewayRef),
4141
),
4242
).
43-
WithEventFilter(predicate.GenerationChangedPredicate{}).
43+
WithEventFilter(
44+
predicate.Or(
45+
predicate.GenerationChangedPredicate{},
46+
predicate.NewPredicateFuncs(func(obj client.Object) bool {
47+
_, ok := obj.(*corev1.Secret)
48+
return ok
49+
}),
50+
),
51+
).
4452
Watches(&gatewayv1.Gateway{},
4553
handler.EnqueueRequestsFromMapFunc(r.listConsumersForGateway),
4654
builder.WithPredicates(

internal/controller/ingress_controller.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,31 @@ func (r *IngressReconciler) listIngressesBySecret(ctx context.Context, obj clien
356356
})
357357
}
358358
}
359-
return requests
359+
360+
gatewayProxyList := &v1alpha1.GatewayProxyList{}
361+
if err := r.List(ctx, gatewayProxyList, client.MatchingFields{
362+
indexer.SecretIndexRef: indexer.GenIndexKey(secret.GetNamespace(), secret.GetName()),
363+
}); err != nil {
364+
r.Log.Error(err, "failed to list gateway proxies by secret", "secret", secret.GetName())
365+
return nil
366+
}
367+
368+
for _, gatewayProxy := range gatewayProxyList.Items {
369+
var (
370+
ingressClassList networkingv1.IngressClassList
371+
indexKey = indexer.GenIndexKey(gatewayProxy.GetNamespace(), gatewayProxy.GetName())
372+
matchingFields = client.MatchingFields{indexer.IngressClassParametersRef: indexKey}
373+
)
374+
if err := r.List(ctx, &ingressClassList, matchingFields); err != nil {
375+
r.Log.Error(err, "failed to list ingress classes for gateway proxy", "gatewayproxy", indexKey)
376+
continue
377+
}
378+
for _, ingressClass := range ingressClassList.Items {
379+
requests = append(requests, r.listIngressForIngressClass(ctx, &ingressClass)...)
380+
}
381+
}
382+
383+
return distinctRequests(requests)
360384
}
361385

362386
func (r *IngressReconciler) listIngressForBackendTrafficPolicy(ctx context.Context, obj client.Object) (requests []reconcile.Request) {

internal/controller/ingressclass_controller.go

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,15 @@ func (r *IngressClassReconciler) SetupWithManager(mgr ctrl.Manager) error {
4040
predicate.NewPredicateFuncs(r.matchesController),
4141
),
4242
).
43-
WithEventFilter(predicate.GenerationChangedPredicate{}).
43+
WithEventFilter(
44+
predicate.Or(
45+
predicate.GenerationChangedPredicate{},
46+
predicate.NewPredicateFuncs(func(obj client.Object) bool {
47+
_, ok := obj.(*corev1.Secret)
48+
return ok
49+
}),
50+
),
51+
).
4452
Watches(
4553
&v1alpha1.GatewayProxy{},
4654
handler.EnqueueRequestsFromMapFunc(r.listIngressClassesForGatewayProxy),
@@ -146,29 +154,10 @@ func (r *IngressClassReconciler) listIngressClassesForSecret(ctx context.Context
146154
// 2. list ingress classes by gateway proxies
147155
requests := make([]reconcile.Request, 0)
148156
for _, gatewayProxy := range gatewayProxyList.Items {
149-
ingressClassList := &networkingv1.IngressClassList{}
150-
if err := r.List(ctx, ingressClassList, client.MatchingFields{
151-
indexer.IngressClassParametersRef: indexer.GenIndexKey(gatewayProxy.GetNamespace(), gatewayProxy.GetName()),
152-
}); err != nil {
153-
r.Log.Error(err, "failed to list ingress classes by secret", "secret", secret.GetName())
154-
return nil
155-
}
156-
for _, ingressClass := range ingressClassList.Items {
157-
if !r.matchesController(&ingressClass) {
158-
continue
159-
}
160-
requests = append(requests, reconcile.Request{
161-
NamespacedName: client.ObjectKey{
162-
Name: ingressClass.GetName(),
163-
Namespace: ingressClass.GetNamespace(),
164-
},
165-
})
166-
}
157+
requests = append(requests, r.listIngressClassesForGatewayProxy(ctx, &gatewayProxy)...)
167158
}
168159

169-
requests = distinctRequests(requests)
170-
171-
return requests
160+
return distinctRequests(requests)
172161
}
173162

174163
func (r *IngressClassReconciler) processInfrastructure(tctx *provider.TranslateContext, ingressClass *networkingv1.IngressClass) error {

test/e2e/crds/consumer.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package gatewayapi
22

33
import (
44
"fmt"
5+
"net/http"
56
"time"
67

78
. "github.com/onsi/ginkgo/v2"
@@ -310,6 +311,15 @@ metadata:
310311
data:
311312
username: c2FtcGxlLXVzZXI=
312313
password: c2FtcGxlLXBhc3N3b3Jk
314+
`
315+
const basicAuthSecret2 = `
316+
apiVersion: v1
317+
kind: Secret
318+
metadata:
319+
name: basic-auth-secret
320+
data:
321+
username: c2FtcGxlLXVzZXI=
322+
password: c2FtcGxlLXBhc3N3b3JkLW5ldw==
313323
`
314324
var defaultConsumer = `
315325
apiVersion: apisix.apache.org/v1alpha1
@@ -358,6 +368,29 @@ spec:
358368
Expect().
359369
Status(200)
360370

371+
// update basic-auth password
372+
err = s.CreateResourceFromString(basicAuthSecret2)
373+
Expect(err).NotTo(HaveOccurred(), "creating basic-auth secret")
374+
375+
// use the old password will get 401
376+
Eventually(func() int {
377+
return s.NewAPISIXClient().
378+
GET("/get").
379+
WithBasicAuth("sample-user", "sample-password").
380+
WithHost("httpbin.org").
381+
Expect().
382+
Raw().StatusCode
383+
}).WithTimeout(8 * time.Second).ProbeEvery(time.Second).
384+
Should(Equal(http.StatusUnauthorized))
385+
386+
// use the new password will get 200
387+
s.NewAPISIXClient().
388+
GET("/get").
389+
WithBasicAuth("sample-user", "sample-password-new").
390+
WithHost("httpbin.org").
391+
Expect().
392+
Status(http.StatusOK)
393+
361394
By("delete consumer")
362395
err = s.DeleteResourceFromString(defaultConsumer)
363396
Expect(err).NotTo(HaveOccurred(), "deleting consumer")

test/e2e/gatewayapi/gateway.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ spec:
112112
Expect(gcyaml).To(ContainSubstring("message: the gatewayclass has been accepted by the api7-ingress-controller"), "checking GatewayClass condition message")
113113

114114
By("create Gateway")
115-
err = s.CreateResourceFromStringWithNamespace(defaultGateway, s.CurrentNamespace())
115+
err = s.CreateResourceFromStringWithNamespace(defaultGateway, s.
116+
Namespace())
116117
Expect(err).NotTo(HaveOccurred(), "creating Gateway")
117118
time.Sleep(5 * time.Second)
118119

@@ -123,7 +124,7 @@ spec:
123124
Expect(gwyaml).To(ContainSubstring("message: the gateway has been accepted by the api7-ingress-controller"), "checking Gateway condition message")
124125

125126
By("create Gateway with not accepted GatewayClass")
126-
err = s.CreateResourceFromStringWithNamespace(noClassGateway, s.CurrentNamespace())
127+
err = s.CreateResourceFromStringWithNamespace(noClassGateway, s.Namespace())
127128
Expect(err).NotTo(HaveOccurred(), "creating Gateway")
128129
time.Sleep(5 * time.Second)
129130

@@ -184,7 +185,7 @@ spec:
184185
time.Sleep(5 * time.Second)
185186

186187
By("create Gateway")
187-
err = s.CreateResourceFromStringWithNamespace(defaultGateway, s.CurrentNamespace())
188+
err = s.CreateResourceFromStringWithNamespace(defaultGateway, s.Namespace())
188189
Expect(err).NotTo(HaveOccurred(), "creating Gateway")
189190
time.Sleep(10 * time.Second)
190191

@@ -257,7 +258,7 @@ spec:
257258
time.Sleep(5 * time.Second)
258259

259260
By("create Gateway")
260-
err = s.CreateResourceFromStringWithNamespace(defaultGateway, s.CurrentNamespace())
261+
err = s.CreateResourceFromStringWithNamespace(defaultGateway, s.Namespace())
261262
Expect(err).NotTo(HaveOccurred(), "creating Gateway")
262263
time.Sleep(10 * time.Second)
263264

test/e2e/gatewayapi/gatewayclass.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ spec:
7777
}).WithTimeout(8 * time.Second).ProbeEvery(time.Second).Should(ContainSubstring(`status: "True"`))
7878

7979
By("create a Gateway")
80-
err = s.CreateResourceFromStringWithNamespace(defaultGateway, s.CurrentNamespace())
80+
err = s.CreateResourceFromStringWithNamespace(defaultGateway, s.Namespace())
8181
Expect(err).NotTo(HaveOccurred(), "creating Gateway")
8282
time.Sleep(time.Second)
8383

test/e2e/gatewayapi/gatewayproxy.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ spec:
207207
time.Sleep(5 * time.Second)
208208

209209
By("Create Gateway with GatewayProxy")
210-
err = s.CreateResourceFromStringWithNamespace(fmt.Sprintf(gatewayWithProxy, gatewayClassName), s.CurrentNamespace())
210+
err = s.CreateResourceFromStringWithNamespace(fmt.Sprintf(gatewayWithProxy, gatewayClassName), s.Namespace())
211211
Expect(err).NotTo(HaveOccurred(), "creating Gateway with GatewayProxy")
212212
time.Sleep(5 * time.Second)
213213

test/e2e/gatewayapi/httproute.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ spec:
125125
Expect(gcyaml).To(ContainSubstring("message: the gatewayclass has been accepted by the api7-ingress-controller"), "checking GatewayClass condition message")
126126

127127
By("create Gateway")
128-
err = s.CreateResourceFromStringWithNamespace(fmt.Sprintf(defaultGateway, gatewayClassName), s.CurrentNamespace())
128+
err = s.CreateResourceFromStringWithNamespace(fmt.Sprintf(defaultGateway, gatewayClassName), s.Namespace())
129129
Expect(err).NotTo(HaveOccurred(), "creating Gateway")
130130
time.Sleep(5 * time.Second)
131131

@@ -158,7 +158,7 @@ spec:
158158
Expect(gcyaml).To(ContainSubstring("message: the gatewayclass has been accepted by the api7-ingress-controller"), "checking GatewayClass condition message")
159159

160160
By("create Gateway")
161-
err = s.CreateResourceFromStringWithNamespace(fmt.Sprintf(defaultGatewayHTTPS, gatewayClassName), s.CurrentNamespace())
161+
err = s.CreateResourceFromStringWithNamespace(fmt.Sprintf(defaultGatewayHTTPS, gatewayClassName), s.Namespace())
162162
Expect(err).NotTo(HaveOccurred(), "creating Gateway")
163163
time.Sleep(5 * time.Second)
164164

test/e2e/ingress/ingress.go

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package ingress
22

33
import (
44
"context"
5+
"encoding/base64"
56
"fmt"
67
"net/http"
78
"strings"
@@ -805,4 +806,145 @@ spec:
805806
Status(200)
806807
})
807808
})
809+
810+
Context("GatewayProxy reference Secret", func() {
811+
const secretSpec = `
812+
apiVersion: v1
813+
kind: Secret
814+
metadata:
815+
name: control-plane-secret
816+
data:
817+
admin-key: %s
818+
`
819+
const gatewayProxySpec = `
820+
apiVersion: apisix.apache.org/v1alpha1
821+
kind: GatewayProxy
822+
metadata:
823+
name: api7-proxy-config
824+
spec:
825+
provider:
826+
type: ControlPlane
827+
controlPlane:
828+
endpoints:
829+
- %s
830+
auth:
831+
type: AdminKey
832+
adminKey:
833+
valueFrom:
834+
secretKeyRef:
835+
name: control-plane-secret
836+
key: admin-key
837+
plugins:
838+
- name: response-rewrite
839+
enabled: true
840+
config:
841+
headers:
842+
X-Proxy-Test: "enabled"
843+
`
844+
const ingressClassSpec = `
845+
apiVersion: networking.k8s.io/v1
846+
kind: IngressClass
847+
metadata:
848+
name: api7-ingress-class
849+
spec:
850+
controller: "apisix.apache.org/api7-ingress-controller"
851+
parameters:
852+
apiGroup: "apisix.apache.org"
853+
kind: "GatewayProxy"
854+
name: "api7-proxy-config"
855+
namespace: %s
856+
scope: "Namespace"
857+
`
858+
const ingressSpec = `
859+
apiVersion: networking.k8s.io/v1
860+
kind: Ingress
861+
metadata:
862+
name: api7-ingress
863+
spec:
864+
ingressClassName: api7-ingress-class
865+
rules:
866+
- host: ingress.example.com
867+
http:
868+
paths:
869+
- path: /get
870+
pathType: Prefix
871+
backend:
872+
service:
873+
name: httpbin-service-e2e-test
874+
port:
875+
number: 80
876+
`
877+
var (
878+
additionalGatewayGroupID string
879+
err error
880+
)
881+
882+
It("GatewayProxy reference Secret", func() {
883+
By("create Secret")
884+
err = s.CreateResourceFromStringWithNamespace(fmt.Sprintf(secretSpec, base64.StdEncoding.EncodeToString([]byte(s.AdminKey()))), s.Namespace())
885+
Expect(err).NotTo(HaveOccurred(), "creating secret")
886+
887+
By("create GatewayProxy")
888+
err = s.CreateResourceFromStringWithNamespace(fmt.Sprintf(gatewayProxySpec, framework.DashboardTLSEndpoint), s.Namespace())
889+
Expect(err).NotTo(HaveOccurred(), "creating gateway proxy")
890+
891+
By("create IngressClass")
892+
err = s.CreateResourceFromStringWithNamespace(fmt.Sprintf(ingressClassSpec, s.Namespace()), s.Namespace())
893+
Expect(err).NotTo(HaveOccurred(), "creating IngressClass")
894+
895+
By("creat Ingress")
896+
err = s.CreateResourceFromStringWithNamespace(ingressSpec, s.Namespace())
897+
Expect(err).NotTo(HaveOccurred(), "creating Ingress")
898+
899+
By("verify Ingress works")
900+
Eventually(func() int {
901+
return s.NewAPISIXClient().
902+
GET("/get").
903+
WithHost("ingress.example.com").
904+
Expect().Raw().StatusCode
905+
}).WithTimeout(8 * time.Second).ProbeEvery(time.Second).
906+
Should(Equal(http.StatusOK))
907+
s.NewAPISIXClient().
908+
GET("/get").
909+
WithHost("ingress.example.com").
910+
Expect().Header("X-Proxy-Test").IsEqual("enabled")
911+
912+
By("create additional gateway group to get new admin key")
913+
additionalGatewayGroupID, _, err = s.CreateAdditionalGatewayGroup("gateway-proxy-update")
914+
Expect(err).NotTo(HaveOccurred(), "creating additional gateway group")
915+
916+
client, err := s.NewAPISIXClientForGatewayGroup(additionalGatewayGroupID)
917+
Expect(err).NotTo(HaveOccurred(), "creating APISIX client for additional gateway group")
918+
919+
By("Ingress not found for additional gateway group")
920+
client.
921+
GET("/get").
922+
WithHost("ingress.example.com").
923+
Expect().
924+
Status(http.StatusNotFound)
925+
926+
resources, exists := s.GetAdditionalGatewayGroup(additionalGatewayGroupID)
927+
Expect(exists).To(BeTrue(), "additional gateway group should exist")
928+
929+
By("update secret")
930+
err = s.CreateResourceFromStringWithNamespace(fmt.Sprintf(secretSpec, base64.StdEncoding.EncodeToString([]byte(resources.AdminAPIKey))), s.Namespace())
931+
Expect(err).NotTo(HaveOccurred(), "creating secret")
932+
933+
By("verify Ingress works for additional gateway group")
934+
Eventually(func() int {
935+
return client.
936+
GET("/get").
937+
WithHost("ingress.example.com").
938+
Expect().Raw().StatusCode
939+
}).WithTimeout(8 * time.Second).ProbeEvery(time.Second).
940+
Should(Equal(http.StatusOK))
941+
Eventually(func() string {
942+
return client.
943+
GET("/get").
944+
WithHost("ingress.example.com").
945+
Expect().Raw().Header.Get("X-Proxy-Test")
946+
}).WithTimeout(8 * time.Second).ProbeEvery(time.Second).
947+
Should(Equal("enabled"))
948+
})
949+
})
808950
})

0 commit comments

Comments
 (0)