Compare commits
10 changed files with 29 additions and 40 deletions
|
|
@ -7,7 +7,7 @@ Humans / Zapier cloud
|
||||||
access-web :3021/portal access-zapier :3024 access-api :3022
|
access-web :3021/portal access-zapier :3024 access-api :3022
|
||||||
│ │
|
│ │
|
||||||
▼ ▼
|
▼ ▼
|
||||||
verae-edge-billing loopback :3000 (meter, admin, Stripe; not a public door)
|
zappier-edge loopback :3000 (meter, admin, Stripe; not a public door)
|
||||||
│ HTTPS internal
|
│ HTTPS internal
|
||||||
▼
|
▼
|
||||||
middleware-http :3100 (/zapier/v1)
|
middleware-http :3100 (/zapier/v1)
|
||||||
|
|
@ -29,7 +29,7 @@ Prefix `ssh://git@git.georgelambert.org:2223/marchon/<name>.git` (SSH **2223**).
|
||||||
|
|
||||||
| You need | Repo | Catalog README |
|
| You need | Repo | Catalog README |
|
||||||
|----------|------|----------------|
|
|----------|------|----------------|
|
||||||
| Billing HTTPS | `verae-edge-billing` | https://zapier.georgelambert.org/packages/zappier/README.pdf |
|
| Billing HTTPS | `zappier-edge` | https://zapier.georgelambert.org/packages/zappier/README.pdf |
|
||||||
| Zapier adapter | `verae-middleware` | https://zapier.georgelambert.org/packages/verae-zapier-middleware/README.pdf |
|
| Zapier adapter | `verae-middleware` | https://zapier.georgelambert.org/packages/verae-zapier-middleware/README.pdf |
|
||||||
| Zapier app (cloud) | `verae-zapier-app` | https://zapier.georgelambert.org/packages/verae-zapier/README.pdf |
|
| Zapier app (cloud) | `verae-zapier-app` | https://zapier.georgelambert.org/packages/verae-zapier/README.pdf |
|
||||||
| WORM nodes | `verae-archive-worm` | https://zapier.georgelambert.org/packages/verae-archive-worm/README.pdf |
|
| WORM nodes | `verae-archive-worm` | https://zapier.georgelambert.org/packages/verae-archive-worm/README.pdf |
|
||||||
|
|
@ -59,18 +59,18 @@ Manifest: `host-deps.tsv`. Narrative: [HOST-DEPS.md](https://git.georgelambert.o
|
||||||
|
|
||||||
| Service | Needs |
|
| Service | Needs |
|
||||||
|---------|--------|
|
|---------|--------|
|
||||||
| verae-edge-billing | Node 20+, **better-sqlite3** (python3/make/g++ on Linux), SQLite path, `PORT`, optional Stripe keys |
|
| zappier-edge | Node 20+, **better-sqlite3** (python3/make/g++ on Linux), SQLite path, `PORT`, optional Stripe keys |
|
||||||
| middleware | Node 22+, `NATS_URL` **or** `NATS_ENABLED=false`, chain URL or `MOCK_VERAE` |
|
| middleware | Node 22+, `NATS_URL` **or** `NATS_ENABLED=false`, chain URL or `MOCK_VERAE` |
|
||||||
| NATS | JetStream, **no public bind** (`host-deps.sh --nats` on archive / all-in-one) |
|
| NATS | JetStream, **no public bind** (`host-deps.sh --nats` on archive / all-in-one) |
|
||||||
| worm / tree-node | Node, `NATS_URL`, local state dir |
|
| worm / tree-node | Node, `NATS_URL`, local state dir |
|
||||||
| fleet | Node, `machines.json` (SSH **paths**), HTTP `:3850` on `0.0.0.0`, `openssh-client` |
|
| fleet | Node, `machines.json` (SSH **paths**), HTTP `:3850` on `0.0.0.0`, `openssh-client` |
|
||||||
| Zapier cloud app | `MIDDLEWARE_BASE_URL` = **public HTTPS of verae-edge-billing** (or middleware if you skip metering in lab) |
|
| Zapier cloud app | `MIDDLEWARE_BASE_URL` = **public HTTPS of zappier-edge** (or middleware if you skip metering in lab) |
|
||||||
|
|
||||||
## Ports (lab defaults)
|
## Ports (lab defaults)
|
||||||
|
|
||||||
| Port | Bind | Process |
|
| Port | Bind | Process |
|
||||||
|------|------|---------|
|
|------|------|---------|
|
||||||
| 3000 | **loopback** (lab) | verae-edge-billing (admin); public portal is `:3021` |
|
| 3000 | **loopback** (lab) | zappier-edge (admin); public portal is `:3021` |
|
||||||
| 3021 | public | access-web `/portal/` |
|
| 3021 | public | access-web `/portal/` |
|
||||||
| 3028 | private/LAN | staff IAM |
|
| 3028 | private/LAN | staff IAM |
|
||||||
| 3100 | public or docker publish | middleware |
|
| 3100 | public or docker publish | middleware |
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
`docker-compose.yml` in this repo starts:
|
`docker-compose.yml` in this repo starts:
|
||||||
|
|
||||||
- NATS JetStream **3-node cluster** (`nats1`–`nats3`) on an internal network
|
- NATS JetStream **3-node cluster** (`nats1`–`nats3`) on an internal network
|
||||||
- **verae-edge-billing** `:3000`
|
- **zappier-edge** `:3000`
|
||||||
- **middleware** `:3100` with `NATS_URL=nats://nats1:4222` and `MOCK_VERAE=true` by default
|
- **middleware** `:3100` with `NATS_URL=nats://nats1:4222` and `MOCK_VERAE=true` by default
|
||||||
- **archive-worm** ×3 and **tree-node** ×3 (fleet floors) as long-running Node workers
|
- **archive-worm** ×3 and **tree-node** ×3 (fleet floors) as long-running Node workers
|
||||||
- **aggregator** + **job-poller** stand-ins via middleware workers when `NATS_ENABLED=true`
|
- **aggregator** + **job-poller** stand-ins via middleware workers when `NATS_ENABLED=true`
|
||||||
|
|
@ -25,7 +25,7 @@ Without `MONOREPO`, Compose expects `../zappier`, `../verae-zapier-middleware`,
|
||||||
|
|
||||||
## Link Zapier (cloud) to the lab
|
## Link Zapier (cloud) to the lab
|
||||||
|
|
||||||
1. Publish verae-edge-billing on a TLS hostname (Caddy/nginx in front of `:3000`).
|
1. Publish zappier-edge on a TLS hostname (Caddy/nginx in front of `:3000`).
|
||||||
2. In the Zapier app env: `MIDDLEWARE_BASE_URL=https://<zappier-host>` (edge meters, then proxies).
|
2. In the Zapier app env: `MIDDLEWARE_BASE_URL=https://<zappier-host>` (edge meters, then proxies).
|
||||||
3. Sign up on `/portal`, copy `x-api-key`.
|
3. Sign up on `/portal`, copy `x-api-key`.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,6 @@ Loopback NATS on the host stays `127.0.0.1:4222` (current lab bus). `verae-nats-
|
||||||
|
|
||||||
## Edge / Caddy
|
## Edge / Caddy
|
||||||
|
|
||||||
Stay on the **host** (already live). Do not put verae-edge-billing in the worker CT.
|
Stay on the **host** (already live). Do not put zappier-edge in the worker CT.
|
||||||
|
|
||||||
Operator console: `https://fleet.zapier.georgelambert.org/` · overlay `packages/verae-fleet/overlays/ns1/`.
|
Operator console: `https://fleet.zapier.georgelambert.org/` · overlay `packages/verae-fleet/overlays/ns1/`.
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,9 @@ NS1-style: a box that already runs NATS on **127.0.0.1:4222** (never a public bi
|
||||||
|
|
||||||
1. Node 22+, git (SSH port **2223** to Forgejo).
|
1. Node 22+, git (SSH port **2223** to Forgejo).
|
||||||
2. `nats-server -js` listening **127.0.0.1:4222** only (cluster later on a private NIC).
|
2. `nats-server -js` listening **127.0.0.1:4222** only (cluster later on a private NIC).
|
||||||
3. Clone `verae-edge-billing`, `verae-middleware`, `verae-fleet`.
|
3. Clone `zappier-edge`, `verae-middleware`, `verae-fleet`.
|
||||||
4. systemd units (below) or `verae-fleet serve` which keepFloor-spawns workers.
|
4. systemd units (below) or `verae-fleet serve` which keepFloor-spawns workers.
|
||||||
5. Caddy file `caddy/zapier-services.georgelambert.org.caddy` on NS1: `portal`/`zap`/`api`/staff/fleet hostnames → local ports. verae-edge-billing stays loopback (`:3000`, or `:13000` on NS1 if `:3000` is already taken).
|
5. Caddy file `caddy/zapier-services.georgelambert.org.caddy` on NS1: `portal`/`zap`/`api`/staff/fleet hostnames → local ports. zappier-edge stays loopback (`:3000`, or `:13000` on NS1 if `:3000` is already taken).
|
||||||
6. Operator console: `0.0.0.0:3850`. `verae-keep` (`:3860`) + `watch` (`:3861`) + `guard.sh` keep workers up unless you paused/stopped them in the console.
|
6. Operator console: `0.0.0.0:3850`. `verae-keep` (`:3860`) + `watch` (`:3861`) + `guard.sh` keep workers up unless you paused/stopped them in the console.
|
||||||
7. Clone/install: [verae-bootstrap](https://git.georgelambert.org/marchon/verae-bootstrap) type `ns1-all-in-one`.
|
7. Clone/install: [verae-bootstrap](https://git.georgelambert.org/marchon/verae-bootstrap) type `ns1-all-in-one`.
|
||||||
|
|
||||||
|
|
@ -33,7 +33,7 @@ User=verae
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
```
|
```
|
||||||
|
|
||||||
verae-edge-billing similar with `PORT=3000` and `WorkingDirectory` of that clone.
|
zappier-edge similar with `PORT=3000` and `WorkingDirectory` of that clone.
|
||||||
|
|
||||||
## Extra machines
|
## Extra machines
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ Every process learns peers from **environment variables** and **fleet service JS
|
||||||
|
|
||||||
| Process | Variable | Points at |
|
| Process | Variable | Points at |
|
||||||
|---------|----------|-----------|
|
|---------|----------|-----------|
|
||||||
| Zapier cloud app | `MIDDLEWARE_BASE_URL` | Public **verae-edge-billing** HTTPS (prod) or middleware (lab) |
|
| Zapier cloud app | `MIDDLEWARE_BASE_URL` | Public **zappier-edge** HTTPS (prod) or middleware (lab) |
|
||||||
| verae-edge-billing | `ZAPPIER_UPSTREAM` or internal proxy target | middleware `:3100` |
|
| zappier-edge | `ZAPPIER_UPSTREAM` or internal proxy target | middleware `:3100` |
|
||||||
| middleware | `NATS_URL` | `nats://nats1:4222,nats://nats2:4222,nats://nats3:4222` |
|
| middleware | `NATS_URL` | `nats://nats1:4222,nats://nats2:4222,nats://nats3:4222` |
|
||||||
| middleware | `VERAE_API_BASE_URL` | `https://api.veraetime.net` |
|
| middleware | `VERAE_API_BASE_URL` | `https://api.veraetime.net` |
|
||||||
| middleware | `MOCK_VERAE` | `true` only in lab |
|
| middleware | `MOCK_VERAE` | `true` only in lab |
|
||||||
|
|
@ -23,7 +23,7 @@ curl -H "x-api-key: $KEY" https://zappier.example.com/v1/status
|
||||||
curl http://127.0.0.1:3100/health
|
curl http://127.0.0.1:3100/health
|
||||||
```
|
```
|
||||||
|
|
||||||
If Zapier gets 401/402, fix keys and the rate card on verae-edge-billing — not NATS.
|
If Zapier gets 401/402, fix keys and the rate card on zappier-edge — not NATS.
|
||||||
|
|
||||||
## NATS hops (must stay private)
|
## NATS hops (must stay private)
|
||||||
|
|
||||||
|
|
@ -47,7 +47,7 @@ https://zapier.georgelambert.org/docs/02-architecture/fleet.pdf
|
||||||
| archive-worm | 3 |
|
| archive-worm | 3 |
|
||||||
| tree-node | 3 |
|
| tree-node | 3 |
|
||||||
| middleware-http | 1 |
|
| middleware-http | 1 |
|
||||||
| verae-edge-billing | 1 |
|
| zappier-edge | 1 |
|
||||||
| aggregator / poller / webhook | 1 |
|
| aggregator / poller / webhook | 1 |
|
||||||
|
|
||||||
Link a new host: operator console → Add machine → `ssh-check` → reconcile.
|
Link a new host: operator console → Add machine → `ssh-check` → reconcile.
|
||||||
|
|
|
||||||
1
AUTHORS
1
AUTHORS
|
|
@ -1 +0,0 @@
|
||||||
Scott "R00tPiG Security" Lindsey <rootpig@georgelambert.org> (rootpig) — owner
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
This is the **top document** for install, first-up, and monitoring. Platform-specific detail lives in the numbered ops chapters; do not start there.
|
This is the **top document** for install, first-up, and monitoring. Platform-specific detail lives in the numbered ops chapters; do not start there.
|
||||||
|
|
||||||
**Catalog:** https://zapier.georgelambert.org/packages/verae-ops/GETTING-STARTED.pdf
|
**Catalog:** https://zapier.georgelambert.org/packages/verae-ops/GETTING-STARTED.pdf
|
||||||
**Billing / users (verae-edge-billing):** https://zapier.georgelambert.org/packages/zappier/docs/USER-MANUAL.pdf
|
**Billing / users (zappier-edge):** https://zapier.georgelambert.org/packages/zappier/docs/USER-MANUAL.pdf
|
||||||
**Operator console:** http://127.0.0.1:3850/ (loopback) · https://zapier.georgelambert.org/packages/verae-fleet/docs/CONSOLE.pdf
|
**Operator console:** http://127.0.0.1:3850/ (loopback) · https://zapier.georgelambert.org/packages/verae-fleet/docs/CONSOLE.pdf
|
||||||
|
|
||||||
## What you are turning on
|
## What you are turning on
|
||||||
|
|
@ -13,7 +13,7 @@ This is the **top document** for install, first-up, and monitoring. Platform-spe
|
||||||
| **access-authz** | NATS authorization step for every access plane | `:3020` |
|
| **access-authz** | NATS authorization step for every access plane | `:3020` |
|
||||||
| **access-web / api / leaf / zapier / staff** | Public HTTP doors | `:3021–:3025` |
|
| **access-web / api / leaf / zapier / staff** | Public HTTP doors | `:3021–:3025` |
|
||||||
| **identity** | `veraeUserId` bind/lookup | `:3026` |
|
| **identity** | `veraeUserId` bind/lookup | `:3026` |
|
||||||
| **verae-edge-billing** | Identity cache, Stripe, admin (loopback only) | `127.0.0.1:3000` (lab; NS1 all-in-one uses `:13000` if `:3000` is taken) |
|
| **zappier-edge** | Identity cache, Stripe, admin (loopback only) | `127.0.0.1:3000` (lab; NS1 all-in-one uses `:13000` if `:3000` is taken) |
|
||||||
| **staff-iam** | Named staff users, roles, sessions | `:3028` |
|
| **staff-iam** | Named staff users, roles, sessions | `:3028` |
|
||||||
| **staff-session** | Staff cookie (proxies IAM) | `:3027` |
|
| **staff-session** | Staff cookie (proxies IAM) | `:3027` |
|
||||||
| **verae-keep** | Restart crashed units unless admin paused/stopped | keep `:3860`, watch `:3861` |
|
| **verae-keep** | Restart crashed units unless admin paused/stopped | keep `:3860`, watch `:3861` |
|
||||||
|
|
@ -27,9 +27,9 @@ This is the **top document** for install, first-up, and monitoring. Platform-spe
|
||||||
| **worm ×3, tree-node ×3** | Off-chain files and Merkle leaves | fleet floor |
|
| **worm ×3, tree-node ×3** | Off-chain files and Merkle leaves | fleet floor |
|
||||||
| **fleet** | Replica floors, SSH hosts, Trace, Docs | `:3850` on `0.0.0.0` |
|
| **fleet** | Replica floors, SSH hosts, Trace, Docs | `:3850` on `0.0.0.0` |
|
||||||
|
|
||||||
Zapier cloud talks **only** to **access-zapier** (`:3024`) over HTTPS. Browsers use access-web. Customer API keys use access-api. Staff use access-staff. verae-edge-billing is loopback.
|
Zapier cloud talks **only** to **access-zapier** (`:3024`) over HTTPS. Browsers use access-web. Customer API keys use access-api. Staff use access-staff. zappier-edge is loopback.
|
||||||
|
|
||||||
The billing and user platform is the standalone **zappier** project (`/Users/marchon/zappier`, Forgejo [verae-edge-billing](https://git.georgelambert.org/marchon/verae-edge-billing)): portal signup, TOTP, API keys, rate card, Stripe meter, PO invoices, admin users. Verae middleware does **not** replace it.
|
The billing and user platform is the standalone **zappier** project (`/Users/marchon/zappier`, Forgejo [zappier-edge](https://git.georgelambert.org/marchon/zappier-edge)): portal signup, TOTP, API keys, rate card, Stripe meter, PO invoices, admin users. Verae middleware does **not** replace it.
|
||||||
|
|
||||||
## 15-minute lab (one machine)
|
## 15-minute lab (one machine)
|
||||||
|
|
||||||
|
|
@ -58,7 +58,7 @@ docker compose up --build
|
||||||
Check:
|
Check:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -fsS http://127.0.0.1:3000/health # verae-edge-billing (billing + users)
|
curl -fsS http://127.0.0.1:3000/health # zappier-edge (billing + users)
|
||||||
curl -fsS http://127.0.0.1:3010/health # account-balance (NATS SoT)
|
curl -fsS http://127.0.0.1:3010/health # account-balance (NATS SoT)
|
||||||
curl -fsS http://127.0.0.1:3011/health # customer-service
|
curl -fsS http://127.0.0.1:3011/health # customer-service
|
||||||
curl -fsS http://127.0.0.1:3012/health # sales-pricing
|
curl -fsS http://127.0.0.1:3012/health # sales-pricing
|
||||||
|
|
@ -127,5 +127,5 @@ node src/cli.js ssh-check ns1
|
||||||
## If something is red
|
## If something is red
|
||||||
|
|
||||||
1. Fleet row color: yellow = paused/degraded, red = below floor — `restart` that replica.
|
1. Fleet row color: yellow = paused/degraded, red = below floor — `restart` that replica.
|
||||||
2. 401/402 from Zapier → verae-edge-billing keys and rate card, not NATS.
|
2. 401/402 from Zapier → zappier-edge keys and rate card, not NATS.
|
||||||
3. Archive lookup empty → bloom miss is **silence**; check worm/tree floors, not “error replies”.
|
3. Archive lookup empty → bloom miss is **silence**; check worm/tree floors, not “error replies”.
|
||||||
|
|
|
||||||
10
OWNER.md
10
OWNER.md
|
|
@ -1,10 +0,0 @@
|
||||||
# Repository owner
|
|
||||||
|
|
||||||
**Owner / credited author:** Scott "R00tPiG Security" Lindsey (`rootpig`)
|
|
||||||
|
|
||||||
Forgejo: https://git.georgelambert.org/rootpig
|
|
||||||
|
|
||||||
This repository is owned by **rootpig** for Verae Inc. server maintenance,
|
|
||||||
deployment scripting, and related operations work.
|
|
||||||
|
|
||||||
Co-contributors may appear in git history; ownership and ops credit belong to rootpig.
|
|
||||||
|
|
@ -26,7 +26,7 @@ Public PDFs of the same files: `https://zapier.georgelambert.org/packages/verae-
|
||||||
|
|
||||||
| Rule | Why |
|
| Rule | Why |
|
||||||
|------|-----|
|
|------|-----|
|
||||||
| Zapier cloud → **HTTPS only** (verae-edge-billing) | Never NATS, never `api.veraetime.net` |
|
| Zapier cloud → **HTTPS only** (zappier-edge) | Never NATS, never `api.veraetime.net` |
|
||||||
| NATS binds **loopback or a private docker/VM net** | Not on the public NIC |
|
| NATS binds **loopback or a private docker/VM net** | Not on the public NIC |
|
||||||
| Tree-node **min 3**, pause does not count | Bulk Merkle lookups |
|
| Tree-node **min 3**, pause does not count | Bulk Merkle lookups |
|
||||||
| Private keys stay on disk; git stores **paths** | `machines.json` `identityFile` |
|
| Private keys stay on disk; git stores **paths** | `machines.json` `identityFile` |
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ services:
|
||||||
networks: [verae]
|
networks: [verae]
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
verae-edge-billing:
|
zappier-edge:
|
||||||
<<: *node
|
<<: *node
|
||||||
build:
|
build:
|
||||||
context: ${MONOREPO:-..}/packages/zappier
|
context: ${MONOREPO:-..}/packages/zappier
|
||||||
|
|
@ -158,13 +158,13 @@ services:
|
||||||
command: ["node", "src/server.js"]
|
command: ["node", "src/server.js"]
|
||||||
environment:
|
environment:
|
||||||
PORT: "3011"
|
PORT: "3011"
|
||||||
ZAPPIER_ADMIN_URL: http://verae-edge-billing:3000
|
ZAPPIER_ADMIN_URL: http://zappier-edge:3000
|
||||||
ACCOUNT_BALANCE_URL: http://account-balance:3010
|
ACCOUNT_BALANCE_URL: http://account-balance:3010
|
||||||
NATS_URL: nats://nats1:4222
|
NATS_URL: nats://nats1:4222
|
||||||
AUTHZ_URL: http://access-authz:3020
|
AUTHZ_URL: http://access-authz:3020
|
||||||
ports:
|
ports:
|
||||||
- "3011:3011"
|
- "3011:3011"
|
||||||
depends_on: [verae-edge-billing, account-balance, nats1]
|
depends_on: [zappier-edge, account-balance, nats1]
|
||||||
|
|
||||||
sales-pricing:
|
sales-pricing:
|
||||||
<<: *node
|
<<: *node
|
||||||
|
|
@ -175,12 +175,12 @@ services:
|
||||||
command: ["node", "src/server.js"]
|
command: ["node", "src/server.js"]
|
||||||
environment:
|
environment:
|
||||||
PORT: "3012"
|
PORT: "3012"
|
||||||
ZAPPIER_ADMIN_URL: http://verae-edge-billing:3000
|
ZAPPIER_ADMIN_URL: http://zappier-edge:3000
|
||||||
ACCOUNT_BALANCE_URL: http://account-balance:3010
|
ACCOUNT_BALANCE_URL: http://account-balance:3010
|
||||||
NATS_URL: nats://nats1:4222
|
NATS_URL: nats://nats1:4222
|
||||||
ports:
|
ports:
|
||||||
- "3012:3012"
|
- "3012:3012"
|
||||||
depends_on: [verae-edge-billing, account-balance, nats1]
|
depends_on: [zappier-edge, account-balance, nats1]
|
||||||
|
|
||||||
accounting-export:
|
accounting-export:
|
||||||
<<: *node
|
<<: *node
|
||||||
|
|
@ -191,12 +191,12 @@ services:
|
||||||
command: ["node", "src/server.js"]
|
command: ["node", "src/server.js"]
|
||||||
environment:
|
environment:
|
||||||
PORT: "3013"
|
PORT: "3013"
|
||||||
ZAPPIER_ADMIN_URL: http://verae-edge-billing:3000
|
ZAPPIER_ADMIN_URL: http://zappier-edge:3000
|
||||||
ACCOUNT_BALANCE_URL: http://account-balance:3010
|
ACCOUNT_BALANCE_URL: http://account-balance:3010
|
||||||
NATS_URL: nats://nats1:4222
|
NATS_URL: nats://nats1:4222
|
||||||
ports:
|
ports:
|
||||||
- "3013:3013"
|
- "3013:3013"
|
||||||
depends_on: [verae-edge-billing, account-balance, nats1]
|
depends_on: [zappier-edge, account-balance, nats1]
|
||||||
|
|
||||||
middleware:
|
middleware:
|
||||||
<<: *node
|
<<: *node
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue