Skip to content

Commit

Permalink
e2e test
Browse files Browse the repository at this point in the history
Signed-off-by: Huabing Zhao <[email protected]>
  • Loading branch information
zhaohuabing committed Jan 7, 2025
1 parent b65eb93 commit 0f7096f
Show file tree
Hide file tree
Showing 3 changed files with 289 additions and 62 deletions.
194 changes: 194 additions & 0 deletions test/e2e/testdata/jwt-backend-remote-jwks.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
---
apiVersion: v1
kind: Secret
metadata:
name: remote-jwks-server-secret
namespace: gateway-conformance-infra
type: kubernetes.io/tls
data:
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURmekNDQW1lZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREJETVNBd0hnWURWUVFLREJkeVpXMXYKZEdVdGFuZHJjeTF6WlhKMlpYSWdTVzVqTGpFZk1CMEdBMVVFQXd3V2NtVnRiM1JsTFdwM2EzTXRjMlZ5ZG1WeQpMbU52YlRBZUZ3MHlOVEF4TURjd056UXhNamxhRncwek5UQXhNRFV3TnpReE1qbGFNRHd4R3pBWkJnTlZCQU1NCkVuSmxiVzkwWlMxcWQydHpMWE5sY25abGNqRWRNQnNHQTFVRUNnd1VaWGhoYlhCc1pTQnZjbWRoYm1sNllYUnAKYjI0d2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUM5STk4bjZwMmZNYTZwRkRPTgpneDFzNkMvUmI2SU1leGZBQTR5T1VkL0EvaU1mN0haRGMzR3Q4T29oYmhQY0F5MmF0QS9mbEJ2Z1RNdHNJZ2JMCjVGUXFvQ1U1bW92OStMYW41dGp4bCttUnY4RzVqSFltWklYS29yMTg2Ly8yOFdXWVp4Rm53ZGlRMlR3SGIzSzYKaUROOWllVysrck5LOUVWVW54R2dRdENGaHVHYXNHZkE2QkxuTHBERjg3bzdSZ2ViSlo0TFpud0FzSjdyM25WMwpQa0dXMWQxcDBGNjZ0UW4xMzF3UGVhcEdJbnpaQnhhT0tZTGt6cjJIdmNnUjNvVk9SdktMcWpwK2U2MGFxd0ovCll6TFNyMkJsZlVaVEZZS2t2Qmpuc3BseFAxbWtDc2pIRndSdHdSK1llbkN0a29sb3NkbHlVdUNoMEhJZXBCQUIKWmp4WkFnTUJBQUdqZ1lRd2dZRXdDd1lEVlIwUEJBUURBZ1dnTUJNR0ExVWRKUVFNTUFvR0NDc0dBUVVGQndNQgpNQjBHQTFVZEVRUVdNQlNDRW5KbGJXOTBaUzFxZDJ0ekxYTmxjblpsY2pBZEJnTlZIUTRFRmdRVUo4M3dTdmI4Ci84c0lNZ29FSllBMWNKV1pQYWN3SHdZRFZSMGpCQmd3Rm9BVVpuUzFqWWdSVnI1WHMrZHF0TWV4RzRBNmtWa3cKRFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUt4VXJ6OUh6R0cyT3M5UkFtaXNNTUU4di95MEhocVNCSUo5U3Y3OQo3WGF1R01nYVg0NWVMNlN2MHRsa21hcW05UHQ5NmppQis5ZkR4S1NHV2xLMk03aUl5aVFyWDVsaGt4czZ1U3NJCkMyRjlUcmVFUjNCSk5uaGFDaVhXdTRQL2MvdzA4WEpmWU51WEJMVFpSc3RkNTFxMHJzMnR5cU1QQ3EyZXBvSWsKZ3duRUxVZkM3SGpoSVB1M1BoeXdxYngzY0F3MUJ5aVdnTUtkR3FFMUw2NkhmdDRlTFdNQzBnUURPUWZnQmZjRQpWbUlnVVNXYWFIbU5VUDdzQk03S1NTTnRJOFVvNjF6SVl4R2dwVnRPOXc0YjBneVV5MTJQRXgreW1RN0FiTWRHCmFMNUJZUDhGY1dRMjlsd1Vua2RXR1VoNnFNNmd1cXJ6WFBiTXpKL3hnaERtMlVJPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQzlJOThuNnAyZk1hNnAKRkRPTmd4MXM2Qy9SYjZJTWV4ZkFBNHlPVWQvQS9pTWY3SFpEYzNHdDhPb2hiaFBjQXkyYXRBL2ZsQnZnVE10cwpJZ2JMNUZRcW9DVTVtb3Y5K0xhbjV0anhsK21SdjhHNWpIWW1aSVhLb3IxODYvLzI4V1dZWnhGbndkaVEyVHdICmIzSzZpRE45aWVXKytyTks5RVZVbnhHZ1F0Q0ZodUdhc0dmQTZCTG5McERGODdvN1JnZWJKWjRMWm53QXNKN3IKM25WM1BrR1cxZDFwMEY2NnRRbjEzMXdQZWFwR0luelpCeGFPS1lMa3pyMkh2Y2dSM29WT1J2S0xxanArZTYwYQpxd0ovWXpMU3IyQmxmVVpURllLa3ZCam5zcGx4UDFta0NzakhGd1J0d1IrWWVuQ3Rrb2xvc2RseVV1Q2gwSEllCnBCQUJaanhaQWdNQkFBRUNnZ0VBRmdMZUVpQkR5RzVnMmhDdHFMVDI2RkVUbW9za0o5RnQ2OFRGOTF5WUhuYTgKNmZiTDh4RFU3SllXT3o1N0hXNDV3UkNlTGNubjNoZzF6cjlkZk40MVBOSXZEdGQ1WGZ5ekxoSkhra01ZZGFPawpKUWF2aTh1RVJmY2ZOL0hqazQ2WGdROVNsMWwzN1hCNGc5R0FuNnhnMktYakNMRVdpejBtOGVDQ3JiekUxVnNRCkc1NzhGbmtQYmZBZ1Q3a2dWRjFzekRzS2p6Si9yREtkTVg0dXpvY2NlTzJoTUJrU0hYMU1BbmFsUkxBampGTFkKcGJkN2ZZK0xlR2Z5ZXQ3ZDZGMDdaUDNBUzFRVkVGczVHRVYwSHFHS3paS2JkSHF6dG1XeW9xd3ZvQmJVd2lVLwo5elRtQktQcFNoZW9SakJudVhJTFBILzE1cTFodHNSak4wczRTc0dxUVFLQmdRRHRGanNZSUNENXgrY1BDYm1pCmpQK2U3YVZJRkw3K3hsWDdReUZxSWc3eXVzRlYyUGtyOXhXT2pjS0owcVlmU2UxaWlIaU4wQUJJcUFjMDRmUm0KbXUvMmhtRU85RVdJaUhTQk44VXkzRmh3Zk1tUnpWRWZEemljT2NJZ1gxRWFudlZmMnlOMWtxblc2VWRtcDlJYgpKejQ5RzliM2s3NDdhS3NxTWZMR2Z1dmhHUUtCZ1FETU9ub0xrQkxyOWJnYU1lU1hTZXdoQkw1VmkxZmxxUk83ClNqU1FzYTU0azN1aWZZTEM0MlZMMkJDdDlYZ2JVWE5hNzBBTC9KcXovRUxKTm5uWGt1bVUwK2F6cVU0QUJoOFcKcUFTWk9GdGowTHptL1V6VHdVUkVwemxpQkFacnBNdDU1S3EzQmV4L2xMS2pJYi9lNENtZkxSdW1lWTlYYlFyNwpvZWtrT0J4ZFFRS0JnQW5PckowZjN4MVdCcG5acGlNeVAvUzhFZVU4Ym5ZdGtDcjNxTzh4LzNwTS9XaG10RS84ClJaa0RCalFiVWFIanRmMG9kZ3d2dVlOSDZCeG82R3BDS0lFREtBcXRVaDhHdmdNR1lwTHJDSUdHdC9QZkVXYisKZ3pIN05hdVBKZFM3RkoxbGZEOEYxUjY5d2FWZWRkT0h1UXhnRlhGaVhERXE4RUdybFVaZXc3VXBBb0dBRE4waQpFdGhnV0x5QmZDVG9ZUjhtNEcyTUQ1ZFhVZi8wWGpldVYrN1pMbjhicW9COVhBazJ1REJEM0xFNWYzOEI1UmhzCjBGUjQ2aDFabDVMMjJiMUhPVGlmcjNGYW1HWEtUNE1GeHlEbG9NUGxJaWVTVDBROUtKWGY1MnlaZXU1R1lzY2sKZWFMRjRzTmEvU3VEQ21iVU9GSi9DMTFjeWdUMFRDVkdxaUZlcUFFQ2dZRUFsckUxVFVCeDRDbGQvNU9SemVkOApnK1g3S2RORXhtOCtjTkdDM3g0bUpzOWpybXFXN01wKzlab1RSR2ROemdBY1luRjMvZkZVV1ZkbEo1bkczVzZVCk44blJvVWtneSs2a1lzTExUT2NXOGxHMHlyRXZ0WVA5Ujk0aStqaCtzd3NPUEUvb0FsMG9EbklldE1WUmpQaXYKWEVJRWNrSUdMbHhQTmtwZmNBMEp2UU09Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
---
apiVersion: v1
kind: ConfigMap
metadata:
name: remote-jwks-server-ca
namespace: gateway-conformance-infra
data:
ca.crt: |
-----BEGIN CERTIFICATE-----
MIIDZzCCAk+gAwIBAgIUdKqpVkYMQWraGhwBrL26NPO2ocYwDQYJKoZIhvcNAQEL
BQAwQzEgMB4GA1UECgwXcmVtb3RlLWp3a3Mtc2VydmVyIEluYy4xHzAdBgNVBAMM
FnJlbW90ZS1qd2tzLXNlcnZlci5jb20wHhcNMjUwMTA3MDc0MTI5WhcNMzUwMTA1
MDc0MTI5WjBDMSAwHgYDVQQKDBdyZW1vdGUtandrcy1zZXJ2ZXIgSW5jLjEfMB0G
A1UEAwwWcmVtb3RlLWp3a3Mtc2VydmVyLmNvbTCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBAMA7NXKfnnEthULdenoA+AJzSRuPZaiHyrwGqVGm8gEKJ02U
8IIj5ztcurooBtuDZQvuKRjMFOFPGuG3UGdzR+rRQ7Wenp9qy0E7C0q6WXxS9B/W
mGJ/JcttZO0JvNTWm1fByKrvM4OmokFkEKQX7pnwQyRV2gkckOuAwyWUsD1eHp/b
/ke4uZB0M9M1Ll+TBw8l1qG7GclcjOE41kW2Y1S6h5umGBn/g2SqN47sWj4G0ork
No4JICik4FXO3h1UBnnEgbsgHplnyT3i9OZydfgToOEXjW+w8EE8JwRVNpIiYLTE
lwrq7FhrhvnVZ+hQ9u0Pu+8p9CmdA91dKuqGq8kCAwEAAaNTMFEwHQYDVR0OBBYE
FGZ0tY2IEVa+V7PnarTHsRuAOpFZMB8GA1UdIwQYMBaAFGZ0tY2IEVa+V7PnarTH
sRuAOpFZMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAB3aGMrx
7aAmUEuEcYibbUbMYKXis94hh2rOqREZDTWsH91JAdqfDpoIkjjgpTusK67Jgr7z
YV1v2f5qFMSoRHd7aKJr5zsBpl616kdya4a3hv7iqBypldXekNo8zteJHjC9ryyZ
znDcuxPKGkib2Nitck/rWhq+T1ncKTz2QU1oI/EqUwPe4IBThdMnHIPxa4EvABv0
d1EPZUtZdOr8/fet4Z4KF9zIHrJiBwApw6AFs6x84XyRKCQwpwMZdxDNWa/tZ7A3
x82ma7q4/PV/IuP+wOJx1B1JNO1vqlM/STbQf0JFw1/C7KHLDQjZGMV53Fcrj4J8
POACnSGEb+8C9Sw=
-----END CERTIFICATE-----
---
apiVersion: v1
kind: Service
metadata:
name: remote-jwks-server
namespace: gateway-conformance-infra
spec:
selector:
app: remote-jwks-server
ports:
- protocol: TCP
port: 443
targetPort: 8443
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: remote-jwks-server
namespace: gateway-conformance-infra
labels:
app: remote-jwks-server
spec:
replicas: 1
selector:
matchLabels:
app: remote-jwks-server
template:
metadata:
labels:
app: remote-jwks-server
spec:
containers:
- name: remote-jwks-server
image: envoyproxy/gateway-static-file-server
imagePullPolicy: IfNotPresent
args:
- --port=8443
- --certPath=/etc/certs
volumeMounts:
- name: remote-jwks-server-secret
mountPath: /etc/certs
volumes:
- name: remote-jwks-server-secret
secret:
secretName: remote-jwks-server-secret
items:
- key: tls.crt
path: server.crt
- key: tls.key
path: server.key
---
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
name: remote-jwks
namespace: gateway-conformance-infra
spec:
endpoints:
- fqdn:
hostname: 'remote-jwks-server'
port: 443
---
apiVersion: gateway.networking.k8s.io/v1alpha3
kind: BackendTLSPolicy
metadata:
name: remote-jwks-btls
namespace: gateway-conformance-infra
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: Backend
name: remote-jwks
sectionName: 443
validation:
caCertificateRefs:
- name: remote-jwks-server-ca
group: ''
kind: ConfigMap
hostname: remote-jwks-server
---
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
name: jwt-example
namespace: gateway-conformance-infra
spec:
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute
name: jwt-claim-routing
jwt:
providers:
- name: example
recomputeRoute: true
claimToHeaders:
- claim: sub
header: x-sub
- claim: admin
header: x-admin
- claim: name
header: x-name
remoteJWKS:
backendRefs:
- group: gateway.envoyproxy.io
kind: Backend
name: remote-jwks
port: 443
backendSettings:
retry:
numRetries: 3
perRetry:
backOff:
baseInterval: 1s
maxInterval: 5s
retryOn:
triggers: ["5xx", "gateway-error", "reset"]
uri: https://remote-jwks-server/jwt/jwks.json
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: jwt-claim-routing
namespace: gateway-conformance-infra
spec:
parentRefs:
- name: same-namespace
rules:
- backendRefs:
- kind: Service
name: infra-backend-v1
port: 8080
weight: 1
matches:
- headers:
- name: x-name
value: John Doe
- backendRefs:
- kind: Service
name: infra-backend-v2
port: 8080
weight: 1
matches:
- headers:
- name: x-name
value: Tom
# catch all
- backendRefs:
- kind: Service
name: infra-backend-invalid
port: 8080
weight: 1
matches:
- path:
type: PathPrefix
value: /
29 changes: 29 additions & 0 deletions test/e2e/tests/jwt-backend-remote-jwks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright Envoy Gateway Authors
// SPDX-License-Identifier: Apache-2.0
// The full text of the Apache license is available in the LICENSE file at
// the root of the repo.

//go:build e2e

package tests

import (
"testing"

"sigs.k8s.io/gateway-api/conformance/utils/suite"
)

func init() {
ConformanceTests = append(ConformanceTests, JWTBackendRemoteJWKSTest)
}

var JWTBackendRemoteJWKSTest = suite.ConformanceTest{
ShortName: "JWTBackendRemoteJWKS",
Description: "JWT with Backend as remote JWKS",
Manifests: []string{"testdata/jwt-backend-remote-jwks.yaml"},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
t.Run("jwt claim base routing", func(t *testing.T) {
testClaimBasedRouting(t, suite)
})
},
}
128 changes: 66 additions & 62 deletions test/e2e/tests/jwt.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,75 +39,79 @@ var JWTTest = suite.ConformanceTest{
Manifests: []string{"testdata/jwt.yaml"},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
t.Run("jwt claim base routing", func(t *testing.T) {
ns := "gateway-conformance-infra"
routeNN := types.NamespacedName{Name: "jwt-claim-routing", Namespace: ns}
gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns}
gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
testClaimBasedRouting(t, suite)
})
},
}

testCases := []http.ExpectedResponse{
{
Request: http.Request{
Path: "/get",
Headers: map[string]string{
"Authorization": "Bearer " + v1Token,
},
},
Backend: "infra-backend-v1",
Response: http.Response{
StatusCode: 200,
},
Namespace: ns,
func testClaimBasedRouting(t *testing.T, suite *suite.ConformanceTestSuite) {
ns := "gateway-conformance-infra"
routeNN := types.NamespacedName{Name: "jwt-claim-routing", Namespace: ns}
gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns}
gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)

testCases := []http.ExpectedResponse{
{
Request: http.Request{
Path: "/get",
Headers: map[string]string{
"Authorization": "Bearer " + v1Token,
},
{
Request: http.Request{
Path: "/get",
Headers: map[string]string{
"Authorization": "Bearer " + v2Token,
},
},
Backend: "infra-backend-v2",
Response: http.Response{
StatusCode: 200,
},
Namespace: ns,
},
Backend: "infra-backend-v1",
Response: http.Response{
StatusCode: 200,
},
Namespace: ns,
},
{
Request: http.Request{
Path: "/get",
Headers: map[string]string{
"Authorization": "Bearer " + v2Token,
},
{
Request: http.Request{
Path: "/get",
Headers: map[string]string{
"Authorization": "Bearer " + anotherToken,
},
},
Backend: "infra-backend-v1",
Response: http.Response{
StatusCode: 500,
},
Namespace: ns,
},
Backend: "infra-backend-v2",
Response: http.Response{
StatusCode: 200,
},
Namespace: ns,
},
{
Request: http.Request{
Path: "/get",
Headers: map[string]string{
"Authorization": "Bearer " + anotherToken,
},
{
Request: http.Request{
Path: "/get",
Headers: map[string]string{
"x-name": "Tom",
},
},
Backend: "infra-backend-v2",
Response: http.Response{
StatusCode: 401,
},
Namespace: ns,
},
Backend: "infra-backend-v1",
Response: http.Response{
StatusCode: 500,
},
Namespace: ns,
},
{
Request: http.Request{
Path: "/get",
Headers: map[string]string{
"x-name": "Tom",
},
}
},
Backend: "infra-backend-v2",
Response: http.Response{
StatusCode: 401,
},
Namespace: ns,
},
}

for i := range testCases {
tc := testCases[i]
t.Run(tc.GetTestCaseName(i), func(t *testing.T) {
t.Parallel()
http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, tc)
})
}
for i := range testCases {
tc := testCases[i]
t.Run(tc.GetTestCaseName(i), func(t *testing.T) {
t.Parallel()
http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, tc)
})
},
}
}

var OptionalJWTTest = suite.ConformanceTest{
Expand Down

0 comments on commit 0f7096f

Please sign in to comment.