Skip to content

Commit 492ce8d

Browse files
authored
Merge pull request #1190 from openziti/no-public-template
drop public token template; test metrics and dynamic name selection
2 parents 37ab176 + 2c5c33a commit 492ce8d

20 files changed

Lines changed: 1013 additions & 104 deletions

File tree

.github/workflows/integration-tests.yml

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,41 @@ jobs:
4545
python3 -m venv sdk/python/.venv
4646
sdk/python/.venv/bin/pip install -e 'sdk/python/src/[test]' flask waitress requests
4747
48+
- name: Resolve Ziti version for Docker images
49+
id: ziti-docker-version
50+
env:
51+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
52+
ZITI_TEST_VERSION: ${{ vars.ZITI_TEST_VERSION }}
53+
run: |
54+
if [[ -n "${ZITI_TEST_VERSION:-}" ]]; then
55+
V="${ZITI_TEST_VERSION}"
56+
echo "Using pinned version: ${V}"
57+
else
58+
V=$(
59+
gh api --method GET \
60+
'repos/openziti/ziti/releases?per_page=100' \
61+
--jq '
62+
[.[]
63+
| select(.prerelease == false
64+
and .draft == false)
65+
] | first | .tag_name | ltrimstr("v")'
66+
)
67+
echo "Resolved latest stable: ${V}"
68+
fi
69+
V="${V#v}"
70+
if [[ -z "${V}" ]]; then
71+
echo "ERROR: could not resolve Ziti version" >&2
72+
exit 1
73+
fi
74+
echo "ZITI_TEST_VERSION=${V}" | tee -a "$GITHUB_OUTPUT"
75+
4876
- name: Start zrok2 instance (built from source)
49-
run: bash docker/compose/zrok2-instance/dangerous.docker.test.bash --keep
77+
run: |
78+
ARGS=(--keep --ziti-tag "${{ steps.ziti-docker-version.outputs.ZITI_TEST_VERSION }}")
79+
if [[ -n "${{ vars.ZITI_TEST_REPO }}" ]]; then
80+
ARGS+=(--ziti-repo "${{ vars.ZITI_TEST_REPO }}")
81+
fi
82+
bash docker/compose/zrok2-instance/dangerous.docker.test.bash "${ARGS[@]}"
5083
timeout-minutes: 13
5184

5285
- name: Run Python SDK integration tests
@@ -102,10 +135,10 @@ jobs:
102135
id: ziti-version
103136
env:
104137
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
105-
ZITI_LINUX_VERSION: ${{ vars.ZITI_LINUX_VERSION }}
138+
ZITI_TEST_VERSION: ${{ vars.ZITI_TEST_VERSION }}
106139
run: |
107-
if [[ -n "${ZITI_LINUX_VERSION:-}" ]]; then
108-
V="${ZITI_LINUX_VERSION}"
140+
if [[ -n "${ZITI_TEST_VERSION:-}" ]]; then
141+
V="${ZITI_TEST_VERSION}"
109142
echo "Using pinned version: ${V}"
110143
else
111144
V=$(
@@ -124,7 +157,7 @@ jobs:
124157
echo "ERROR: could not resolve Ziti version" >&2
125158
exit 1
126159
fi
127-
echo "ZITI_VERSION=${V}" | tee -a "$GITHUB_OUTPUT"
160+
echo "ZITI_TEST_VERSION=${V}" | tee -a "$GITHUB_OUTPUT"
128161
129162
- name: Run Linux deployment test (keep instance)
130163
env:
@@ -133,7 +166,7 @@ jobs:
133166
run: |
134167
bash ./nfpm/dangerous.linux.test.bash \
135168
--keep \
136-
--ziti-version "${{ steps.ziti-version.outputs.ZITI_VERSION }}"
169+
--ziti-version "${{ steps.ziti-version.outputs.ZITI_TEST_VERSION }}"
137170
138171
- name: Run Go SDK integration tests
139172
run: |

canary/looper.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ type LooperOptions struct {
2323
TargetName string
2424
BindAddress string
2525
FrontendScheme string
26+
FrontendPort uint16
2627
SnapshotQueue chan *Snapshot
2728
}
2829

canary/publicHttpLooper.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,11 @@ func (l *PublicHttpLooper) startup() error {
104104
// can reach the frontend proxy.
105105
for i, ep := range l.shr.FrontendEndpoints {
106106
if !strings.Contains(ep, "://") {
107-
l.shr.FrontendEndpoints[i] = fmt.Sprintf("%s://%s", l.opt.FrontendScheme, ep)
107+
if l.opt.FrontendPort != 0 {
108+
l.shr.FrontendEndpoints[i] = fmt.Sprintf("%s://%s:%d", l.opt.FrontendScheme, ep, l.opt.FrontendPort)
109+
} else {
110+
l.shr.FrontendEndpoints[i] = fmt.Sprintf("%s://%s", l.opt.FrontendScheme, ep)
111+
}
108112
dl.Infof("#%d rewrote frontend endpoint: %v", l.id, l.shr.FrontendEndpoints[i])
109113
}
110114
}

cmd/zrok2/adminCreateFrontend.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ type adminCreateFrontendCommand struct {
2121

2222
func newAdminCreateFrontendCommand() *adminCreateFrontendCommand {
2323
cmd := &cobra.Command{
24-
Use: "frontend <zitiId> <publicName> <urlTemplate>",
24+
Use: "frontend <zitiId> <publicName> [urlTemplate]",
2525
Short: "Create a global public frontend",
26-
Args: cobra.ExactArgs(3),
26+
Args: cobra.RangeArgs(2, 3),
2727
}
2828
command := &adminCreateFrontendCommand{cmd: cmd}
2929
cmd.Flags().BoolVar(&command.closed, "closed", false, "Enabled closed permission mode")
@@ -35,7 +35,10 @@ func newAdminCreateFrontendCommand() *adminCreateFrontendCommand {
3535
func (cmd *adminCreateFrontendCommand) run(_ *cobra.Command, args []string) {
3636
zId := args[0]
3737
publicName := args[1]
38-
urlTemplate := args[2]
38+
urlTemplate := ""
39+
if len(args) > 2 {
40+
urlTemplate = args[2]
41+
}
3942

4043
root, err := environment.LoadRoot()
4144
if err != nil {

cmd/zrok2/testCanaryPublicProxy.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ type testCanaryPublicProxy struct {
4343
targetName string
4444
frontendSelection string
4545
http bool
46+
frontendPort uint16
4647
canaryConfig string
4748
}
4849

@@ -77,6 +78,7 @@ func newTestCanaryPublicProxy() *testCanaryPublicProxy {
7778
cmd.Flags().StringVar(&command.targetName, "target-name", "", "Metadata describing the virtual target")
7879
cmd.Flags().StringVar(&command.frontendSelection, "frontend-selection", "public", "Select frontend selection")
7980
cmd.Flags().BoolVar(&command.http, "http", false, "Use http:// scheme for frontend endpoints (default: https://)")
81+
cmd.Flags().Uint16Var(&command.frontendPort, "frontend-port", 0, "Port to append to frontend endpoints (0 = omit port)")
8082
cmd.Flags().StringVar(&command.canaryConfig, "canary-config", "", "Path to canary configuration file")
8183
return command
8284
}
@@ -144,6 +146,7 @@ func (cmd *testCanaryPublicProxy) run(_ *cobra.Command, _ []string) {
144146
MaxBatchPacing: cmd.maxBatchPacing,
145147
TargetName: cmd.targetName,
146148
FrontendScheme: frontendScheme,
149+
FrontendPort: cmd.frontendPort,
147150
}
148151
if cmd.payload > 0 {
149152
looperOpts.MinPayload = cmd.payload

docker/compose/zrok2-instance/Dockerfile.build

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ RUN --mount=type=cache,target=/go/pkg/mod \
5353

5454
# ── Stage 3: Final image (matches published openziti/zrok2 layout) ───────────
5555

56-
FROM docker.io/openziti/ziti-cli:1.6.13
56+
FROM docker.io/openziti/ziti-cli:1.6.14
5757

5858
LABEL name="openziti/zrok2" \
5959
maintainer="support@zrok.io" \
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# Docker Compose overlay for the canary integration test.
2+
# Merged by dangerous.docker.test.bash — not part of the user-facing stack.
3+
#
4+
# The canary service uses host networking so *.localhost resolves to 127.0.0.1
5+
# and reaches published frontend and controller ports directly.
6+
7+
services:
8+
canary:
9+
image: ${ZROK2_IMAGE:-docker.io/openziti/zrok2}:${ZROK2_TAG:-latest}
10+
network_mode: host
11+
environment:
12+
ZROK2_API_ENDPOINT: http://127.0.0.1:${ZROK2_CTRL_PORT:-18080}
13+
ZROK2_ADMIN_TOKEN: ${ZROK2_ADMIN_TOKEN}
14+
ZROK2_DANGEROUS_CANARY: "1"
15+
ZROK2_FRONTEND_PORT: ${ZROK2_FRONTEND_PORT:-8080}
16+
ZROK2_DNS_ZONE: ${ZROK2_DNS_ZONE:-localhost}
17+
HOME: /tmp/canary
18+
entrypoint: ["/bin/bash", "-c"]
19+
command:
20+
- |
21+
set -o errexit -o nounset -o pipefail
22+
23+
FRONTEND_PORT="$${ZROK2_FRONTEND_PORT}"
24+
DNS_ZONE="$${ZROK2_DNS_ZONE}"
25+
26+
# Create a throwaway canary account and enable an environment.
27+
# ZROK2_API_ENDPOINT is already set — zrok2 enable bootstraps
28+
# the environment in one shot.
29+
TOKEN=$$(zrok2 admin create account \
30+
"canary-$$(date +%s)@zrok.internal" "canarypass")
31+
echo "canary account token: $${TOKEN}"
32+
zrok2 enable "$${TOKEN}" --description canary-test
33+
34+
# ── Test 1: Canary looper (random share token) ──────────────────
35+
# Exercises the public frontend with random share tokens. The
36+
# host-networked container reaches the frontend at
37+
# localhost:ZROK2_FRONTEND_PORT, and *.localhost resolves to
38+
# 127.0.0.1 (RFC 6761).
39+
echo "=== Test 1: canary public-proxy looper ==="
40+
zrok2 test canary public-proxy \
41+
--iterations 3 --loopers 1 \
42+
--min-payload 256 --max-payload 256 \
43+
--min-pacing 1s --max-pacing 1s \
44+
--http --frontend-port "$${FRONTEND_PORT}"
45+
46+
# ── Test 2: Named share via --name-selection ────────────────────
47+
# Creates a share with an explicit name in the public namespace,
48+
# then verifies the AMQP-backed dynamic frontend routes it.
49+
echo "=== Test 2: named share ==="
50+
SHARE_NAME="citest-$$(date +%s)"
51+
52+
BACKEND_PORT=19999
53+
zrok2 test endpoint --port "$${BACKEND_PORT}" &
54+
HTTP_PID=$$!
55+
56+
# Pre-create the name (v2 equivalent of "zrok reserve").
57+
zrok2 create name "$${SHARE_NAME}"
58+
59+
# Create the named share in the background (long-running).
60+
zrok2 share public "http://127.0.0.1:$${BACKEND_PORT}" \
61+
--name-selection "public:$${SHARE_NAME}" \
62+
--backend-mode proxy --headless &
63+
SHARE_PID=$$!
64+
65+
# Wait for the share to propagate to the dynamic frontend.
66+
echo "waiting for named share '$${SHARE_NAME}' ..."
67+
sleep 5
68+
ATTEMPTS=30
69+
while (( ATTEMPTS-- > 0 )); do
70+
if curl -sf -H "Host: $${SHARE_NAME}.$${DNS_ZONE}" \
71+
"http://127.0.0.1:$${FRONTEND_PORT}/" 2>/dev/null \
72+
| grep -q "zrok"; then
73+
echo "PASS: named share '$${SHARE_NAME}' content verified"
74+
break
75+
fi
76+
sleep 2
77+
done
78+
if (( ATTEMPTS < 0 )); then
79+
echo "FAIL: named share '$${SHARE_NAME}' not reachable after 60s"
80+
kill $${SHARE_PID} $${HTTP_PID} 2>/dev/null || true
81+
exit 1
82+
fi
83+
84+
# Clean up share and backend.
85+
kill $${SHARE_PID} $${HTTP_PID} 2>/dev/null || true
86+
wait $${SHARE_PID} 2>/dev/null || true
87+
wait $${HTTP_PID} 2>/dev/null || true
88+
89+
zrok2 disable || true
90+
echo "=== All canary tests passed ==="
91+
profiles: ["canary"]

docker/compose/zrok2-instance/compose.yml

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ services:
2929
ZITI_CLUSTER_NODE_NAME: ziti-ctrl
3030
PFXLOG_NO_JSON: "true"
3131
volumes:
32-
- ziti-ctrl-data:/home/ziggy
32+
- ziti-ctrl-data:/ziti-controller
3333
ports:
3434
- "${ZROK2_INSECURE_INTERFACE:-127.0.0.1}:${ZITI_CTRL_PORT:-1280}:${ZITI_CTRL_PORT:-1280}"
3535
networks:
@@ -190,12 +190,16 @@ services:
190190
ZROK2_FRONTEND_PORT: ${ZROK2_FRONTEND_PORT:-8080}
191191
ZROK2_STORE_TYPE: ${ZROK2_STORE_TYPE:-postgres}
192192
ZROK2_DB_PASSWORD: ${ZROK2_DB_PASSWORD:-zrok2defaultpw}
193+
ZROK2_METRICS_ENABLED: ${ZROK2_METRICS_ENABLED:-false}
194+
ZROK2_INFLUX_TOKEN: ${ZROK2_INFLUX_TOKEN:-}
193195
HOME: /var/lib/zrok2
194196
depends_on:
195197
ziti-controller:
196198
condition: service_healthy
197199
postgresql:
198200
condition: service_healthy
201+
rabbitmq:
202+
condition: service_healthy
199203
volumes:
200204
- zrok2-config:/var/lib/zrok2
201205
- ./entrypoint-init.bash:/bootstrap/entrypoint-init.bash:ro
@@ -235,7 +239,7 @@ services:
235239

236240
zrok2-frontend:
237241
<<: *zrok2-image
238-
command: ["access", "public", "/var/lib/zrok2/config/frontend.yaml"]
242+
command: ["access", "dynamicProxy", "/var/lib/zrok2/config/frontend.yaml"]
239243
environment:
240244
ZROK2_API_ENDPOINT: http://zrok2-controller:${ZROK2_CTRL_PORT:-18080}
241245
HOME: /var/lib/zrok2
@@ -251,11 +255,34 @@ services:
251255
restart: unless-stopped
252256

253257
# ── Metrics Pipeline (optional) ──────────────────────────────────────────
254-
# To enable: set ZROK2_METRICS_ENABLED=true in .env
258+
# To enable: set ZROK2_METRICS_ENABLED=true in .env and run with
259+
# docker compose --profile metrics up -d
260+
261+
# Metrics bridge: reads fabric-usage.json from the Ziti controller data
262+
# volume and publishes events to RabbitMQ for the zrok2 controller to
263+
# consume and write to InfluxDB.
264+
zrok2-metrics-bridge:
265+
<<: *zrok2-image
266+
command: ["controller", "metrics", "bridge", "/var/lib/zrok2/config/ctrl.yaml"]
267+
profiles: ["metrics"]
268+
environment:
269+
HOME: /var/lib/zrok2
270+
depends_on:
271+
zrok2-controller:
272+
condition: service_healthy
273+
rabbitmq:
274+
condition: service_healthy
275+
volumes:
276+
- zrok2-config:/var/lib/zrok2:ro
277+
- ziti-ctrl-data:/ziti-data
278+
networks:
279+
- zrok2
280+
restart: unless-stopped
255281

282+
# RabbitMQ is required by the dynamic frontend for real-time mapping updates
283+
# (AMQP-backed share name resolution). It is NOT optional.
256284
rabbitmq:
257285
image: rabbitmq:3-management-alpine
258-
profiles: ["metrics"]
259286
volumes:
260287
- rabbitmq-data:/var/lib/rabbitmq
261288
networks:

0 commit comments

Comments
 (0)