Skip to content

Commit 9439768

Browse files
committed
Test agentgateway egress behavior
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
1 parent aa37b5f commit 9439768

7 files changed

Lines changed: 263 additions & 132 deletions

File tree

.github/workflows/helm-e2e.yaml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,6 @@ jobs:
8181
--namespace ate-system \
8282
--reuse-values \
8383
--wait --timeout=10m
84-
- name: Deploy egress gateway fixture
85-
env:
86-
KO_DOCKER_REPO: localhost:5001
87-
KO_DEFAULTPLATFORMS: linux/amd64
88-
run: |
89-
./hack/run-tool.sh ko apply -f manifests/ate-install/atenet-egress.yaml -- --context=kind-kind
90-
kubectl --context kind-kind rollout status deployment/atenet-egress -n ate-system --timeout=120s
9184
- name: Deploy micro-VM counter demo
9285
run: hack/run-microvm-demo-kind.sh --skip-control-plane
9386
- name: Deploy gVisor counter demo

.github/workflows/pr-workflow.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,11 @@ jobs:
7878
- name: Create cluster
7979
run: hack/create-kind-cluster.sh
8080
- name: Install Agent Substrate
81-
run: hack/install-ate-kind.sh --deploy-ate-system
81+
run: hack/install-ate-kind.sh --deploy-ate-system --atenet-router=agentgateway
8282
- name: Deploy micro-VM counter demo
8383
# Stages the (cached) assets into the cluster's rustfs and applies the
8484
# counter-microvm demo onto the control plane installed above.
85-
run: hack/run-microvm-demo-kind.sh
85+
run: hack/run-microvm-demo-kind.sh --skip-control-plane
8686
- name: Deploy gVisor counter demo
8787
run: hack/install-ate-kind.sh --deploy-demo-counter
8888
- name: Deploy egress demos

charts/substrate/templates/ate-api-server.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ spec:
8888
- "--postgres-connection-string=@env"
8989
- "--actor-id-jwt-pool=/run/actor-id-jwt-pool/pool.json"
9090
- "--actor-id-ca-pool=/run/actor-id-ca-pool/pool.json"
91-
- "--egress-gateway-address=atenet-egress.{{ .Release.Namespace }}.svc:443"
91+
- "--egress-gateway-address={{ include "substrate.fullname" (list "atenet-egress" .) }}.{{ .Release.Namespace }}.svc:443"
9292
- "--atelet-client-cred-bundle=/run/podidentity.podcert.ate.dev/credential-bundle.pem"
9393
- "--pod-identity-ca-certs=/run/podidentity.podcert.ate.dev/trust-bundle.pem"
9494
- "--drain-delay=13s"
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
{{/*
2+
Copyright 2026 Google LLC
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/}}
16+
17+
apiVersion: v1
18+
kind: ServiceAccount
19+
metadata:
20+
name: {{ include "substrate.fullname" (list "atenet-egress" .) }}
21+
namespace: {{ .Release.Namespace }}
22+
---
23+
apiVersion: v1
24+
kind: ConfigMap
25+
metadata:
26+
name: {{ include "substrate.fullname" (list "atenet-egress-agentgateway-config" .) }}
27+
namespace: {{ .Release.Namespace }}
28+
data:
29+
config.yaml: |
30+
# yaml-language-server: $schema=https://agentgateway.dev/schema/config
31+
frontendPolicies:
32+
connect:
33+
mode: route
34+
35+
gateways:
36+
egress:
37+
port: 8443
38+
protocol: HTTPS
39+
tls:
40+
cert: /run/servicedns.podcert.ate.dev/credential-bundle.pem
41+
key: /run/servicedns.podcert.ate.dev/credential-bundle.pem
42+
root: /run/actor-id-ca-certs/ca.crt
43+
44+
routes:
45+
- name: substrate-egress
46+
gateways:
47+
- egress
48+
policies:
49+
extProc:
50+
host: 127.0.0.1:50051
51+
failureMode: failClosed
52+
requestAttributes:
53+
ate.extproc.direction: "'egress'"
54+
source.certificate: source.certificate
55+
processingOptions:
56+
requestHeaderMode: send
57+
responseHeaderMode: skip
58+
requestBodyMode: none
59+
responseBodyMode: none
60+
requestTrailerMode: skip
61+
responseTrailerMode: skip
62+
backends:
63+
- dynamic: {}
64+
---
65+
apiVersion: apps/v1
66+
kind: Deployment
67+
metadata:
68+
name: {{ include "substrate.fullname" (list "atenet-egress" .) }}
69+
namespace: {{ .Release.Namespace }}
70+
labels:
71+
app: atenet-egress
72+
spec:
73+
replicas: 1
74+
selector:
75+
matchLabels:
76+
app: atenet-egress
77+
template:
78+
metadata:
79+
labels:
80+
app: atenet-egress
81+
spec:
82+
serviceAccountName: {{ include "substrate.fullname" (list "atenet-egress" .) }}
83+
securityContext:
84+
sysctls:
85+
- name: net.ipv4.ip_unprivileged_port_start
86+
value: "0"
87+
terminationGracePeriodSeconds: 60
88+
containers:
89+
- name: agentgateway
90+
image: {{ .Values.images.agentgateway }}
91+
args:
92+
- -f
93+
- /etc/agentgateway/config.yaml
94+
ports:
95+
- name: https
96+
containerPort: 8443
97+
- name: readiness
98+
containerPort: 15021
99+
- name: stats
100+
containerPort: 15020
101+
readinessProbe:
102+
httpGet:
103+
path: /healthz/ready
104+
port: readiness
105+
periodSeconds: 10
106+
startupProbe:
107+
failureThreshold: 60
108+
httpGet:
109+
path: /healthz/ready
110+
port: readiness
111+
periodSeconds: 1
112+
volumeMounts:
113+
- name: config
114+
mountPath: /etc/agentgateway
115+
readOnly: true
116+
- name: servicedns
117+
mountPath: /run/servicedns.podcert.ate.dev
118+
readOnly: true
119+
- name: actor-id-ca-certs
120+
mountPath: /run/actor-id-ca-certs
121+
readOnly: true
122+
- name: ext-proc
123+
image: {{ include "substrate.componentImage" (list "atenet" .) }}
124+
args:
125+
- router
126+
- --mode=egress
127+
- --namespace={{ .Release.Namespace }}
128+
- --port-extproc=50051
129+
- --extproc-address=127.0.0.1
130+
- --ateapi-address={{ include "substrate.ateApi.endpoint" . }}
131+
- --ateapi-ca-file=/run/servicedns.podcert.ate.dev/trust-bundle.pem
132+
- --ateapi-client-cert=/run/podidentity.podcert.ate.dev/credential-bundle.pem
133+
- --actor-identity-ca-file=/run/actor-id-ca-certs/ca.crt
134+
- --otlp-collector-address=
135+
- --envoy-admin-address=127.0.0.1:15000
136+
- --atenet-router=agentgateway
137+
env:
138+
- name: POD_NAME
139+
valueFrom:
140+
fieldRef:
141+
fieldPath: metadata.name
142+
- name: POD_NAMESPACE
143+
valueFrom:
144+
fieldRef:
145+
fieldPath: metadata.namespace
146+
ports:
147+
- name: extproc
148+
containerPort: 50051
149+
readinessProbe:
150+
tcpSocket:
151+
port: extproc
152+
periodSeconds: 10
153+
volumeMounts:
154+
- name: servicedns
155+
mountPath: /run/servicedns.podcert.ate.dev
156+
readOnly: true
157+
- name: podidentity
158+
mountPath: /run/podidentity.podcert.ate.dev
159+
readOnly: true
160+
- name: actor-id-ca-certs
161+
mountPath: /run/actor-id-ca-certs
162+
readOnly: true
163+
- name: drain-signal
164+
mountPath: /var/run/atenet
165+
volumes:
166+
- name: config
167+
configMap:
168+
name: {{ include "substrate.fullname" (list "atenet-egress-agentgateway-config" .) }}
169+
- name: drain-signal
170+
emptyDir: {}
171+
- name: servicedns
172+
projected:
173+
sources:
174+
- podCertificate:
175+
signerName: servicedns.podcert.ate.dev/identity
176+
keyType: ECDSAP256
177+
credentialBundlePath: credential-bundle.pem
178+
- clusterTrustBundle:
179+
signerName: servicedns.podcert.ate.dev/identity
180+
labelSelector:
181+
matchLabels:
182+
podcert.ate.dev/canarying: live
183+
path: trust-bundle.pem
184+
- name: podidentity
185+
projected:
186+
sources:
187+
- podCertificate:
188+
signerName: podidentity.podcert.ate.dev/identity
189+
keyType: ECDSAP256
190+
credentialBundlePath: credential-bundle.pem
191+
- clusterTrustBundle:
192+
signerName: podidentity.podcert.ate.dev/identity
193+
labelSelector:
194+
matchLabels:
195+
podcert.ate.dev/canarying: live
196+
path: trust-bundle.pem
197+
- name: actor-id-ca-certs
198+
secret:
199+
secretName: actor-id-ca-certs
200+
---
201+
apiVersion: v1
202+
kind: Service
203+
metadata:
204+
name: {{ include "substrate.fullname" (list "atenet-egress" .) }}
205+
namespace: {{ .Release.Namespace }}
206+
spec:
207+
type: ClusterIP
208+
selector:
209+
app: atenet-egress
210+
ports:
211+
- name: https
212+
port: 443
213+
targetPort: https
214+
protocol: TCP

charts/substrate/templates/atenet-router.yaml

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,17 @@ data:
7171
randomSampling: 0.01
7272
{{- end }}
7373

74+
backends:
75+
- name: worker-connect-proxy
76+
dynamic:
77+
target: extproc["envoy.filters.listener.original_dst"]["connect_proxy"]
78+
policies:
79+
backendTLS:
80+
cert: /run/podidentity.podcert.ate.dev/credential-bundle.pem
81+
key: /run/podidentity.podcert.ate.dev/credential-bundle.pem
82+
root: /run/podidentity.podcert.ate.dev/trust-bundle.pem
83+
insecureHost: true
84+
7485
gateways:
7586
http:
7687
port: 8080
@@ -105,13 +116,12 @@ data:
105116
"filter_state['dev.ate.authority']": request.host
106117
backends:
107118
- dynamic:
108-
target: extproc["envoy.filters.listener.original_dst"]["local"]
119+
target: extproc["envoy.filters.listener.original_dst"]["connect_destination"]
109120
policies:
110-
backendTLS:
111-
cert: /run/podidentity.podcert.ate.dev/credential-bundle.pem
112-
key: /run/podidentity.podcert.ate.dev/credential-bundle.pem
113-
root: /run/podidentity.podcert.ate.dev/trust-bundle.pem
114-
insecureHost: true
121+
backendTunnel:
122+
proxy:
123+
backend: /worker-connect-proxy
124+
mode: connect
115125

116126
binds:
117127
- port: 8081
@@ -150,13 +160,12 @@ data:
150160
"filter_state['dev.ate.authority']": source.connectHeaders["host"]
151161
backends:
152162
- dynamic:
153-
target: extproc["envoy.filters.listener.original_dst"]["local"]
163+
target: extproc["envoy.filters.listener.original_dst"]["connect_destination"]
154164
policies:
155-
backendTLS:
156-
cert: /run/podidentity.podcert.ate.dev/credential-bundle.pem
157-
key: /run/podidentity.podcert.ate.dev/credential-bundle.pem
158-
root: /run/podidentity.podcert.ate.dev/trust-bundle.pem
159-
insecureHost: true
165+
backendTunnel:
166+
proxy:
167+
backend: /worker-connect-proxy
168+
mode: connect
160169
---
161170
apiVersion: apps/v1
162171
kind: Deployment

internal/e2e/suites/identity/identity_test.go

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -272,18 +272,30 @@ func createAndResumeActor(t *testing.T, ctx context.Context, clients *e2e.Client
272272

273273
func whoami(t *testing.T, ctx context.Context, rc *e2e.RouterClient, id string) whoamiResponse {
274274
t.Helper()
275-
resp, err := rc.Get(ctx, resources.ActorRef{Atespace: probeNamespace, Name: id}, "/whoami")
276-
if err != nil {
277-
t.Fatalf("GET /whoami for %q: %v", id, err)
278-
}
279-
defer resp.Body.Close()
280-
if resp.StatusCode != http.StatusOK {
281-
body, _ := io.ReadAll(resp.Body)
282-
t.Fatalf("GET /whoami for %q: status %d, body %q", id, resp.StatusCode, body)
283-
}
284-
var out whoamiResponse
285-
if err := json.NewDecoder(resp.Body).Decode(&out); err != nil {
286-
t.Fatalf("decoding /whoami for %q: %v", id, err)
275+
deadline := time.Now().Add(30 * time.Second)
276+
for {
277+
resp, err := rc.Get(ctx, resources.ActorRef{Atespace: probeNamespace, Name: id}, "/whoami")
278+
if err != nil {
279+
if time.Now().After(deadline) {
280+
t.Fatalf("GET /whoami for %q did not become ready: %v", id, err)
281+
}
282+
time.Sleep(time.Second)
283+
continue
284+
}
285+
if resp.StatusCode != http.StatusOK {
286+
body, _ := io.ReadAll(resp.Body)
287+
_ = resp.Body.Close()
288+
if time.Now().After(deadline) {
289+
t.Fatalf("GET /whoami for %q: status %d, body %q", id, resp.StatusCode, body)
290+
}
291+
time.Sleep(time.Second)
292+
continue
293+
}
294+
defer resp.Body.Close()
295+
var out whoamiResponse
296+
if err := json.NewDecoder(resp.Body).Decode(&out); err != nil {
297+
t.Fatalf("decoding /whoami for %q: %v", id, err)
298+
}
299+
return out
287300
}
288-
return out
289301
}

0 commit comments

Comments
 (0)