150 lines
8.0 KiB
Bash
Executable File
150 lines
8.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# Regenerate docs/02-architecture/DBIS_NODE_ROLE_MATRIX.md body tables from
|
||
# config/proxmox-operational-template.json (run from repo root).
|
||
set -euo pipefail
|
||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||
JSON="$ROOT/config/proxmox-operational-template.json"
|
||
OUT="$ROOT/docs/02-architecture/DBIS_NODE_ROLE_MATRIX.md"
|
||
|
||
if ! command -v jq &>/dev/null; then
|
||
echo "jq required" >&2
|
||
exit 1
|
||
fi
|
||
|
||
TMP="$(mktemp)"
|
||
trap 'rm -f "$TMP"' EXIT
|
||
|
||
jq -r '
|
||
def vstatus:
|
||
if .category == "besu_validator" then "QBFT signer"
|
||
elif .category == "besu_sentry" then "Sentry (no signer)"
|
||
elif (.category | test("^rpc")) then "RPC only"
|
||
else "N/A"
|
||
end;
|
||
def ntype:
|
||
if .category == "besu_validator" then "Besu validator"
|
||
elif .category == "besu_sentry" then "Besu sentry"
|
||
elif .category == "rpc_core" or .category == "rpc_public" or .category == "rpc_private" or .category == "rpc_named" or .category == "rpc_thirdweb" or .category == "rpc_alltra_hybx" then "Besu RPC (\(.category))"
|
||
elif .category == "dlt" and (.hostname | test("fabric")) then "Fabric"
|
||
elif .category == "dlt" and (.hostname | test("indy")) then "Indy"
|
||
elif .category == "firefly" then "FireFly"
|
||
elif .category == "explorer" then "Blockscout"
|
||
elif .category == "npmplus" then "NPMplus ingress"
|
||
elif .category == "infra" then "Infra LXC"
|
||
elif .category == "monitoring" and (.hostname | test("cacti")) then "Cacti"
|
||
elif .category == "monitoring" then "Monitoring"
|
||
elif .category == "oracle" then "Oracle publisher"
|
||
elif .category == "ccip" then "CCIP monitor"
|
||
elif .category == "tunnel" then "Cloudflare tunnel"
|
||
elif .category == "ml" then "ML node"
|
||
elif .category == "vault" then "HashiCorp Vault"
|
||
elif .category == "order" then "The Order service"
|
||
elif .category == "sankofa_phoenix" then "Sankofa / Phoenix"
|
||
elif .category == "mim4u" then "MIM4U"
|
||
elif .category == "dbis" then "DBIS stack"
|
||
elif .category == "mifos" then "Mifos"
|
||
elif .category == "dapp" then "DApp"
|
||
elif .category == "dev" then "Dev"
|
||
elif .category == "ai_infra" then "AI infra"
|
||
elif .category == "defi" then "DeFi"
|
||
elif .category == "general" then "General CT"
|
||
elif .category == "legacy_proxy" then "Legacy NPM"
|
||
else .category
|
||
end;
|
||
def stier:
|
||
if .category == "besu_validator" or .category == "besu_sentry" then "validator-tier"
|
||
elif (.category | test("^rpc")) then "DMZ / RPC exposure"
|
||
elif .category == "npmplus" or .category == "tunnel" then "edge ingress"
|
||
elif .category == "dlt" or .category == "firefly" then "identity / workflow DLT"
|
||
elif .category == "vault" or .category == "infra" then "management / secrets"
|
||
elif .category == "order" or .category == "sankofa_phoenix" or .category == "dbis" then "application"
|
||
else "standard internal"
|
||
end;
|
||
([.services[] | select(.ipv4 != null) | .ipv4] | group_by(.) | map(select(length > 1) | .[0])) as $dup_ips
|
||
| .services[]
|
||
| (.ipv4) as $ip
|
||
| [(.vmid // "—"), .hostname, ($ip // "—"), (if ($ip != null and ($dup_ips | index($ip))) then "shared / non-concurrent mapping — verify live owner" else "unique in template" end), ntype, (.runtime_state // "unspecified"), "TBD", "TBD", (.preferred_node // "—"), vstatus, stier]
|
||
| @tsv
|
||
' "$JSON" | sort -t$'\t' -k1,1n > "$TMP"
|
||
|
||
UPDATED="$(date -u +%Y-%m-%d)"
|
||
{
|
||
cat <<EOF
|
||
# DBIS Node Role Matrix
|
||
|
||
**Last updated:** ${UPDATED} (UTC) — regenerate machine-derived rows: \`bash scripts/docs/generate-dbis-node-role-matrix-md.sh\`
|
||
**Status:** Active — infrastructure constitution for DBIS Chain 138 and colocated workloads.
|
||
|
||
## Purpose
|
||
|
||
This matrix assigns **node type**, **preferred host placement**, **validator/signing role** (for Besu), and **security tier** per workload. It implements the entity-placement model in [dbis_chain_138_technical_master_plan.md](../../dbis_chain_138_technical_master_plan.md) (Sections 6–7) in a form operators can maintain.
|
||
|
||
**Canonical pairs (keep in sync):**
|
||
|
||
- Human detail and status: [ALL_VMIDS_ENDPOINTS.md](../04-configuration/ALL_VMIDS_ENDPOINTS.md)
|
||
- Machine-readable services: [config/proxmox-operational-template.json](../../config/proxmox-operational-template.json)
|
||
|
||
When you change VMID, IP, hostname, or placement, update **ALL_VMIDS** and **operational-template.json** first, then regenerate the table below with this script (or edit the static sections manually).
|
||
|
||
## Columns
|
||
|
||
| Column | Meaning |
|
||
|--------|---------|
|
||
| **Entity owner** | DBIS Core, Central Bank, IFI, Regional Operator, etc. — use **TBD** until governance assigns. |
|
||
| **Region** | Geographic or site label — **TBD** until multi-site is formalized. |
|
||
| **IP note** | Flags duplicate IPv4 entries in the planning template. A duplicate means **shared or historical mapping**, not concurrent ownership — verify live owner in ALL_VMIDS or on-cluster. |
|
||
| **Runtime state** | Current disposition from the planning template, e.g. active, placeholder CT only, or retired standby. |
|
||
| **Preferred host** | Preferred Proxmox node (\`r630-01\`, \`r630-02\`, \`ml110\`, \`any\`). This is a planning target, not an assertion of current placement. |
|
||
| **Validator / signing** | For Chain 138 Besu: QBFT signer, sentry (no signer), RPC-only, or N/A. |
|
||
| **Security tier** | High-level zone: validator-tier, DMZ/RPC, edge ingress, identity/DLT, application, etc. |
|
||
|
||
## Proxmox hypervisor nodes
|
||
|
||
| Hostname | MGMT IP | Cluster | Role (summary) |
|
||
|----------|---------|---------|------------------|
|
||
EOF
|
||
jq -r '.proxmox_nodes[] | "| \(.hostname) | \(.mgmt_ipv4) | \(.cluster_name // "h — verify") | \(.role) |"' "$JSON"
|
||
|
||
cat <<'MID'
|
||
|
||
## Workloads (from operational template)
|
||
|
||
Machine-derived rows below come from `services[]` in `config/proxmox-operational-template.json`. Duplicate IPv4 notes are warnings that the planning template still contains alternative or legacy ownership for the same address; they must not be read as concurrent live allocations.
|
||
|
||
| VMID | Hostname | IPv4 | IP note | Node type | Runtime state | Entity owner | Region | Preferred host | Validator / signing | Security tier |
|
||
|------|----------|------|---------|-----------|---------------|--------------|--------|----------------|---------------------|---------------|
|
||
MID
|
||
|
||
while IFS=$'\t' read -r vmid host ip ipnote ntype rstate ent reg hw vst stier; do
|
||
echo "| $vmid | $host | $ip | $ipnote | $ntype | $rstate | $ent | $reg | $hw | $vst | $stier |"
|
||
done < "$TMP"
|
||
|
||
cat <<'FOOT'
|
||
|
||
## Supplementary rows (not in template JSON)
|
||
|
||
These appear in [ALL_VMIDS_ENDPOINTS.md](../04-configuration/ALL_VMIDS_ENDPOINTS.md) but are not modeled as `services[]` entries in `proxmox-operational-template.json`. They are **manual supplements**, not generator-backed source of truth.
|
||
|
||
| VMID | Hostname | IPv4 | IP note | Node type | Runtime state | Entity owner | Region | Preferred host | Validator / signing | Security tier |
|
||
|------|----------|------|---------|-----------|---------------|--------------|--------|----------------|---------------------|---------------|
|
||
| 106 | redis-rpc-translator | 192.168.11.110 | manual supplement | RPC translator (Redis) | manual supplement | TBD | TBD | r630-01 (per ALL_VMIDS) | N/A | DMZ / RPC exposure |
|
||
| 107 | web3signer-rpc-translator | 192.168.11.111 | manual supplement | RPC translator (Web3Signer) | manual supplement | TBD | TBD | r630-01 | N/A | DMZ / RPC exposure |
|
||
| 108 | vault-rpc-translator | 192.168.11.112 | manual supplement | RPC translator (Vault) | manual supplement | TBD | TBD | r630-01 | N/A | management / secrets |
|
||
|
||
## Host-level services (no VMID)
|
||
|
||
| Name | Location | Node type | Notes |
|
||
|------|----------|-----------|-------|
|
||
| CCIP relay | r630-01 host `/opt/smom-dbis-138/services/relay` | Cross-chain relay | Uses RPC (e.g. VMID 2201); see [NETWORK_CONFIGURATION_MASTER.md](../11-references/NETWORK_CONFIGURATION_MASTER.md), [docs/07-ccip/](../07-ccip/). |
|
||
|
||
## Related
|
||
|
||
- [dbis_chain_138_technical_master_plan.md](../../dbis_chain_138_technical_master_plan.md)
|
||
- [CHAIN138_CANONICAL_NETWORK_ROLES_VALIDATORS_SENTRY_AND_RPC.md](CHAIN138_CANONICAL_NETWORK_ROLES_VALIDATORS_SENTRY_AND_RPC.md)
|
||
- [VMID_ALLOCATION_FINAL.md](VMID_ALLOCATION_FINAL.md)
|
||
|
||
FOOT
|
||
} > "$OUT"
|
||
|
||
echo "Wrote $OUT"
|