diff --git a/portal/src/app/atlas/page.tsx b/portal/src/app/atlas/page.tsx index 18baac2..28905f2 100644 --- a/portal/src/app/atlas/page.tsx +++ b/portal/src/app/atlas/page.tsx @@ -9,7 +9,7 @@ export const revalidate = 0; export const metadata: Metadata = { title: 'Ecosystem Atlas', description: - 'Live Sankofa route matrix, hidden inventory, and revision notes with server-side IT inventory awareness.', + 'Project Atlas-backed Sankofa route matrix, hidden inventory, and revision notes with server-side IT inventory awareness.', alternates: { canonical: 'https://sankofa.nexus/atlas', }, diff --git a/portal/src/components/atlas/AtlasDashboard.tsx b/portal/src/components/atlas/AtlasDashboard.tsx index fac51d8..64ccd6d 100644 --- a/portal/src/components/atlas/AtlasDashboard.tsx +++ b/portal/src/components/atlas/AtlasDashboard.tsx @@ -113,7 +113,8 @@ export default function AtlasDashboard({

Public Sankofa routing, live inventory, hidden operator surfaces, and revision notes in one place. The live counters come from the portal server's IT read API, while the route matrix - is normalized from the repo's canonical hostname and tunnel docs. + is sourced from the vendored Project Atlas manifests so the page mirrors the canonical + ecosystem map.

edge -> origin -> app", + "type": "web", + "url": "https://admin.sankofa.nexus" + }, + { + "checks": { + "app": "curl -skI https://besu-sentry-ali.sankofa.nexus", + "dns": "dig +short besu-sentry-ali.sankofa.nexus", + "edge": "curl -skI https://besu-sentry-ali.sankofa.nexus", + "origin": "nc -vz 192.168.11.154 9545" + }, + "domain": "besu-sentry-ali.sankofa.nexus", + "ecosystem": "sankofa", + "reverseNote": "Ali sentry metrics", + "reverseTarget": "192.168.11.154:9545", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://besu-sentry-ali.sankofa.nexus" + }, + { + "checks": { + "app": "curl -skI https://blockscout.defi-oracle.io", + "dns": "dig +short blockscout.defi-oracle.io", + "edge": "curl -skI https://blockscout.defi-oracle.io", + "origin": "nc -vz 192.168.11.142 80" + }, + "domain": "blockscout.defi-oracle.io", + "ecosystem": "proxmox", + "reverseNote": "Standard Blockscout / VMID 5011", + "reverseTarget": "192.168.11.142:80", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://blockscout.defi-oracle.io" + }, + { + "checks": { + "app": "curl -skI https://cacti-alltra.d-bis.org", + "dns": "dig +short cacti-alltra.d-bis.org", + "edge": "curl -skI https://cacti-alltra.d-bis.org", + "origin": "nc -vz 192.168.11.80 80" + }, + "domain": "cacti-alltra.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "Cacti monitoring", + "reverseTarget": "192.168.11.80:80", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://cacti-alltra.d-bis.org" + }, + { + "checks": { + "app": "curl -skI https://cacti-hybx.d-bis.org", + "dns": "dig +short cacti-hybx.d-bis.org", + "edge": "curl -skI https://cacti-hybx.d-bis.org", + "origin": "nc -vz 192.168.11.80 80" + }, + "domain": "cacti-hybx.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "Cacti monitoring", + "reverseTarget": "192.168.11.80:80", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://cacti-hybx.d-bis.org" + }, + { + "checks": { + "app": "curl -skI https://codespaces.d-bis.org", + "dns": "dig +short codespaces.d-bis.org", + "edge": "curl -skI https://codespaces.d-bis.org", + "origin": "nc -vz 192.168.11.170 443" + }, + "domain": "codespaces.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "Fourth NPMplus / dev or Codespaces ingress", + "reverseTarget": "192.168.11.170:443", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://codespaces.d-bis.org" + }, + { + "checks": { + "app": "curl -skI https://dapp.d-bis.org", + "dns": "dig +short dapp.d-bis.org", + "edge": "curl -skI https://dapp.d-bis.org", + "origin": "nc -vz 192.168.11.58 80" + }, + "domain": "dapp.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "DApp frontend / VMID 5801", + "reverseTarget": "192.168.11.58:80", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://dapp.d-bis.org" + }, + { + "checks": { + "app": "curl -skI https://dash.sankofa.nexus", + "dns": "dig +short dash.sankofa.nexus", + "edge": "curl -skI https://dash.sankofa.nexus", + "origin": "nc -vz 192.168.11.50 8080" + }, + "domain": "dash.sankofa.nexus", + "ecosystem": "sankofa", + "reverseNote": "Sankofa operator dashboard", + "reverseTarget": "192.168.11.50:8080", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://dash.sankofa.nexus" + }, + { + "checks": { + "app": "curl -skI https://dbis-admin.d-bis.org", + "dns": "dig +short dbis-admin.d-bis.org", + "edge": "curl -skI https://dbis-admin.d-bis.org", + "origin": "nc -vz 192.168.11.130 80" + }, + "domain": "dbis-admin.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "DBIS admin console / VMID 10130", + "reverseTarget": "192.168.11.130:80", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://dbis-admin.d-bis.org" + }, + { + "checks": { + "app": "curl -sk https://dbis-api-2.d-bis.org", + "dns": "dig +short dbis-api-2.d-bis.org", + "edge": "curl -skI https://dbis-api-2.d-bis.org", + "origin": "nc -vz 192.168.11.156 3000" + }, + "domain": "dbis-api-2.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "DBIS API secondary / VMID 10151", + "reverseTarget": "192.168.11.156:3000", + "triagePath": "DNS -> edge -> origin -> app", + "type": "api", + "url": "https://dbis-api-2.d-bis.org" + }, + { + "checks": { + "app": "curl -sk https://dbis-api.d-bis.org", + "dns": "dig +short dbis-api.d-bis.org", + "edge": "curl -skI https://dbis-api.d-bis.org", + "origin": "nc -vz 192.168.11.155 3000" + }, + "domain": "dbis-api.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "DBIS API primary / VMID 10150", + "reverseTarget": "192.168.11.155:3000", + "triagePath": "DNS -> edge -> origin -> app", + "type": "api", + "url": "https://dbis-api.d-bis.org" + }, + { + "checks": { + "app": "curl -skI https://dealflow.d-bis.org", + "dns": "dig +short dealflow.d-bis.org", + "edge": "curl -skI https://dealflow.d-bis.org", + "origin": "nc -vz 192.168.11.94 443" + }, + "domain": "dealflow.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "DealFlow Command Center / VMID 10381", + "reverseTarget": "192.168.11.94:443", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://dealflow.d-bis.org" + }, + { + "checks": { + "app": "curl -skI https://dev.d-bis.org", + "dns": "dig +short dev.d-bis.org", + "edge": "curl -skI https://dev.d-bis.org", + "origin": "nc -vz 192.168.11.170 443" + }, + "domain": "dev.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "Fourth NPMplus / dev ingress", + "reverseTarget": "192.168.11.170:443", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://dev.d-bis.org" + }, + { + "checks": { + "app": "curl -skI https://docs.d-bis.org", + "dns": "dig +short docs.d-bis.org", + "edge": "curl -skI https://docs.d-bis.org", + "origin": "nc -vz 192.168.11.140 4000" + }, + "domain": "docs.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "Explorer nginx / docs host (same edge as explorer)", + "reverseTarget": "192.168.11.140:4000", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://docs.d-bis.org" + }, + { + "checks": { + "app": "curl -skI https://explorer.d-bis.org", + "dns": "dig +short explorer.d-bis.org", + "edge": "curl -skI https://explorer.d-bis.org", + "origin": "nc -vz 192.168.11.140 4000" + }, + "domain": "explorer.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "Direct Blockscout route on port 4000", + "reverseTarget": "192.168.11.140:4000", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://explorer.d-bis.org" + }, + { + "checks": { + "app": "curl -sk https://firefly-ali.sankofa.nexus", + "dns": "dig +short firefly-ali.sankofa.nexus", + "edge": "curl -skI https://firefly-ali.sankofa.nexus", + "origin": "nc -vz 192.168.11.57 5000" + }, + "domain": "firefly-ali.sankofa.nexus", + "ecosystem": "sankofa", + "reverseNote": "Firefly Ali instance / VMID 6201", + "reverseTarget": "192.168.11.57:5000", + "triagePath": "DNS -> edge -> origin -> app", + "type": "api", + "url": "https://firefly-ali.sankofa.nexus" + }, + { + "checks": { + "app": "curl -skI https://gitea.d-bis.org", + "dns": "dig +short gitea.d-bis.org", + "edge": "curl -skI https://gitea.d-bis.org", + "origin": "nc -vz 192.168.11.59 3000" + }, + "domain": "gitea.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "Dev VM Gitea endpoint", + "reverseTarget": "192.168.11.59:3000", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://gitea.d-bis.org" + }, + { + "checks": { + "app": "curl -skI https://hermes.sankofa.nexus", + "dns": "dig +short hermes.sankofa.nexus", + "edge": "curl -skI https://hermes.sankofa.nexus", + "origin": "nc -vz 192.168.11.77 3020" + }, + "domain": "hermes.sankofa.nexus", + "ecosystem": "sankofa", + "reverseNote": "Hermes underwiting intelligence / VMID 7817", + "reverseTarget": "192.168.11.77:3020", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://hermes.sankofa.nexus" + }, + { + "checks": { + "app": "curl -skI https://howtothinkwithai.sankofa.nexus", + "dns": "dig +short howtothinkwithai.sankofa.nexus", + "edge": "curl -skI https://howtothinkwithai.sankofa.nexus", + "origin": "nc -vz 192.168.11.79 3021" + }, + "domain": "howtothinkwithai.sankofa.nexus", + "ecosystem": "sankofa", + "reverseNote": "HowToThinkWithAI / VMID 7819", + "reverseTarget": "192.168.11.79:3021", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://howtothinkwithai.sankofa.nexus" + }, + { + "checks": { + "app": "curl -skI https://keycloak.sankofa.nexus", + "dns": "dig +short keycloak.sankofa.nexus", + "edge": "curl -skI https://keycloak.sankofa.nexus", + "origin": "nc -vz 192.168.11.52 8080" + }, + "domain": "keycloak.sankofa.nexus", + "ecosystem": "sankofa", + "reverseNote": "Sankofa Keycloak / VMID 7802", + "reverseTarget": "192.168.11.52:8080", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://keycloak.sankofa.nexus" + }, + { + "checks": { + "app": "curl -skI https://mail.d-bis.org", + "dns": "dig +short mail.d-bis.org", + "edge": "curl -skI https://mail.d-bis.org", + "origin": "nc -vz 192.168.11.32 25 && nc -vz 192.168.11.32 587 && nc -vz 192.168.11.32 465" + }, + "domain": "mail.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "Mail gateway / PMG", + "reverseTarget": "192.168.11.32:25/587/465", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://mail.d-bis.org" + }, + { + "checks": { + "app": "curl -skI https://mifos.d-bis.org", + "dns": "dig +short mifos.d-bis.org", + "edge": "curl -skI https://mifos.d-bis.org", + "origin": "nc -vz 192.168.11.85 80" + }, + "domain": "mifos.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "Mifos/Fineract / VMID 5800", + "reverseTarget": "192.168.11.85:80", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://mifos.d-bis.org" + }, + { + "checks": { + "app": "curl -skI https://mim4u.org", + "dns": "dig +short mim4u.org", + "edge": "curl -skI https://mim4u.org", + "origin": "nc -vz 192.168.11.37 80" + }, + "domain": "mim4u.org", + "ecosystem": "other", + "reverseNote": "MIM4U web / VMID 7810", + "reverseTarget": "192.168.11.37:80", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://mim4u.org" + }, + { + "checks": { + "app": "curl -skI https://phoenix.sankofa.nexus", + "dns": "dig +short phoenix.sankofa.nexus", + "edge": "curl -skI https://phoenix.sankofa.nexus", + "origin": "nc -vz 192.168.11.50 8080" + }, + "domain": "phoenix.sankofa.nexus", + "ecosystem": "sankofa", + "reverseNote": "Phoenix API hub / VMID 7800", + "reverseTarget": "192.168.11.50:8080", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://phoenix.sankofa.nexus" + }, + { + "checks": { + "app": "curl -skI https://portal.sankofa.nexus", + "dns": "dig +short portal.sankofa.nexus", + "edge": "curl -skI https://portal.sankofa.nexus", + "origin": "nc -vz 192.168.11.51 3000" + }, + "domain": "portal.sankofa.nexus", + "ecosystem": "sankofa", + "reverseNote": "Sankofa portal / VMID 7801", + "reverseTarget": "192.168.11.51:3000", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://portal.sankofa.nexus" + }, + { + "checks": { + "app": "curl -skI https://reserve.d-bis.org", + "dns": "dig +short reserve.d-bis.org", + "edge": "curl -skI https://reserve.d-bis.org", + "origin": "nc -vz 192.168.11.140 4000" + }, + "domain": "reserve.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "Explorer / reserve shared backend", + "reverseTarget": "192.168.11.140:4000", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://reserve.d-bis.org" + }, + { + "checks": { + "app": "curl -sk https://rpc-ali-0x1.sankofa.nexus -H 'content-type: application/json' --data '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"web3_clientVersion\",\"params\":[]}'", + "dns": "dig +short rpc-ali-0x1.sankofa.nexus", + "edge": "curl -skI https://rpc-ali-0x1.sankofa.nexus", + "origin": "nc -vz 192.168.11.234 8545 && nc -vz 192.168.11.234 8546" + }, + "domain": "rpc-ali-0x1.sankofa.nexus", + "ecosystem": "sankofa", + "reverseNote": "Ali Besu RPC 0x1 / VMID 2304", + "reverseTarget": "192.168.11.234:8545/8546", + "triagePath": "DNS -> edge -> origin -> app", + "type": "rpc-http", + "url": "https://rpc-ali-0x1.sankofa.nexus" + }, + { + "checks": { + "app": "curl -sk https://rpc-ali-0x8a.sankofa.nexus -H 'content-type: application/json' --data '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"web3_clientVersion\",\"params\":[]}'", + "dns": "dig +short rpc-ali-0x8a.sankofa.nexus", + "edge": "curl -skI https://rpc-ali-0x8a.sankofa.nexus", + "origin": "nc -vz 192.168.11.233 8545 && nc -vz 192.168.11.233 8546" + }, + "domain": "rpc-ali-0x8a.sankofa.nexus", + "ecosystem": "sankofa", + "reverseNote": "Ali Besu RPC 0x8a / VMID 2303", + "reverseTarget": "192.168.11.233:8545/8546", + "triagePath": "DNS -> edge -> origin -> app", + "type": "rpc-http", + "url": "https://rpc-ali-0x8a.sankofa.nexus" + }, + { + "checks": { + "app": "curl -sk https://rpc-alltra-2.d-bis.org -H 'content-type: application/json' --data '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"web3_clientVersion\",\"params\":[]}'", + "dns": "dig +short rpc-alltra-2.d-bis.org", + "edge": "curl -skI https://rpc-alltra-2.d-bis.org", + "origin": "nc -vz 192.168.11.173 8545 && nc -vz 192.168.11.173 8546" + }, + "domain": "rpc-alltra-2.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "ALLTRA internal RPC 2 / VMID 2501", + "reverseTarget": "192.168.11.173:8545/8546", + "triagePath": "DNS -> edge -> origin -> app", + "type": "rpc-http", + "url": "https://rpc-alltra-2.d-bis.org" + }, + { + "checks": { + "app": "curl -sk https://rpc-alltra-3.d-bis.org -H 'content-type: application/json' --data '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"web3_clientVersion\",\"params\":[]}'", + "dns": "dig +short rpc-alltra-3.d-bis.org", + "edge": "curl -skI https://rpc-alltra-3.d-bis.org", + "origin": "nc -vz 192.168.11.174 8545 && nc -vz 192.168.11.174 8546" + }, + "domain": "rpc-alltra-3.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "ALLTRA internal RPC 3 / VMID 2502", + "reverseTarget": "192.168.11.174:8545/8546", + "triagePath": "DNS -> edge -> origin -> app", + "type": "rpc-http", + "url": "https://rpc-alltra-3.d-bis.org" + }, + { + "checks": { + "app": "curl -sk https://rpc-alltra.d-bis.org -H 'content-type: application/json' --data '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"web3_clientVersion\",\"params\":[]}'", + "dns": "dig +short rpc-alltra.d-bis.org", + "edge": "curl -skI https://rpc-alltra.d-bis.org", + "origin": "nc -vz 192.168.11.172 8545 && nc -vz 192.168.11.172 8546" + }, + "domain": "rpc-alltra.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "ALLTRA internal RPC 1 / VMID 2500", + "reverseTarget": "192.168.11.172:8545/8546", + "triagePath": "DNS -> edge -> origin -> app", + "type": "rpc-http", + "url": "https://rpc-alltra.d-bis.org" + }, + { + "checks": { + "app": "curl -sk https://rpc-fireblocks.d-bis.org -H 'content-type: application/json' --data '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"web3_clientVersion\",\"params\":[]}'", + "dns": "dig +short rpc-fireblocks.d-bis.org", + "edge": "curl -skI https://rpc-fireblocks.d-bis.org", + "origin": "nc -vz 192.168.11.211 8545 && nc -vz 192.168.11.211 8546" + }, + "domain": "rpc-fireblocks.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "Fireblocks dedicated RPC / VMID 2101", + "reverseTarget": "192.168.11.211:8545/8546", + "triagePath": "DNS -> edge -> origin -> app", + "type": "rpc-http", + "url": "https://rpc-fireblocks.d-bis.org" + }, + { + "checks": { + "app": "curl -sk https://rpc-http-prv.d-bis.org -H 'content-type: application/json' --data '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"web3_clientVersion\",\"params\":[]}'", + "dns": "dig +short rpc-http-prv.d-bis.org", + "edge": "curl -skI https://rpc-http-prv.d-bis.org", + "origin": "nc -vz 192.168.11.211 8545 && nc -vz 192.168.11.211 8546" + }, + "domain": "rpc-http-prv.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "Private RPC / VMID 2101", + "reverseTarget": "192.168.11.211:8545/8546", + "triagePath": "DNS -> edge -> origin -> app", + "type": "rpc-http", + "url": "https://rpc-http-prv.d-bis.org" + }, + { + "checks": { + "app": "curl -sk https://rpc-http-pub.d-bis.org -H 'content-type: application/json' --data '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"web3_clientVersion\",\"params\":[]}'", + "dns": "dig +short rpc-http-pub.d-bis.org", + "edge": "curl -skI https://rpc-http-pub.d-bis.org", + "origin": "nc -vz 192.168.11.221 8545 && nc -vz 192.168.11.221 8546" + }, + "domain": "rpc-http-pub.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "Public RPC / VMID 2201", + "reverseTarget": "192.168.11.221:8545/8546", + "triagePath": "DNS -> edge -> origin -> app", + "type": "rpc-http", + "url": "https://rpc-http-pub.d-bis.org" + }, + { + "checks": { + "app": "curl -sk https://rpc-hybx-2.d-bis.org -H 'content-type: application/json' --data '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"web3_clientVersion\",\"params\":[]}'", + "dns": "dig +short rpc-hybx-2.d-bis.org", + "edge": "curl -skI https://rpc-hybx-2.d-bis.org", + "origin": "nc -vz 192.168.11.247 8545 && nc -vz 192.168.11.247 8546" + }, + "domain": "rpc-hybx-2.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "HYBX internal RPC 2 / VMID 2504", + "reverseTarget": "192.168.11.247:8545/8546", + "triagePath": "DNS -> edge -> origin -> app", + "type": "rpc-http", + "url": "https://rpc-hybx-2.d-bis.org" + }, + { + "checks": { + "app": "curl -sk https://rpc-hybx-3.d-bis.org -H 'content-type: application/json' --data '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"web3_clientVersion\",\"params\":[]}'", + "dns": "dig +short rpc-hybx-3.d-bis.org", + "edge": "curl -skI https://rpc-hybx-3.d-bis.org", + "origin": "nc -vz 192.168.11.248 8545 && nc -vz 192.168.11.248 8546" + }, + "domain": "rpc-hybx-3.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "HYBX internal RPC 3 / VMID 2505", + "reverseTarget": "192.168.11.248:8545/8546", + "triagePath": "DNS -> edge -> origin -> app", + "type": "rpc-http", + "url": "https://rpc-hybx-3.d-bis.org" + }, + { + "checks": { + "app": "curl -sk https://rpc-hybx.d-bis.org -H 'content-type: application/json' --data '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"web3_clientVersion\",\"params\":[]}'", + "dns": "dig +short rpc-hybx.d-bis.org", + "edge": "curl -skI https://rpc-hybx.d-bis.org", + "origin": "nc -vz 192.168.11.246 8545 && nc -vz 192.168.11.246 8546" + }, + "domain": "rpc-hybx.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "HYBX internal RPC 1 / VMID 2503", + "reverseTarget": "192.168.11.246:8545/8546", + "triagePath": "DNS -> edge -> origin -> app", + "type": "rpc-http", + "url": "https://rpc-hybx.d-bis.org" + }, + { + "checks": { + "app": "npx wscat -c wss://rpc-ws-prv.d-bis.org -x '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"web3_clientVersion\",\"params\":[]}'", + "dns": "dig +short rpc-ws-prv.d-bis.org", + "edge": "npx wscat -c wss://rpc-ws-prv.d-bis.org", + "origin": "nc -vz 192.168.11.211 8546" + }, + "domain": "rpc-ws-prv.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "Private WebSocket RPC / VMID 2101", + "reverseTarget": "192.168.11.211:8546", + "triagePath": "DNS -> edge -> origin -> app", + "type": "rpc-ws", + "url": "https://rpc-ws-prv.d-bis.org" + }, + { + "checks": { + "app": "npx wscat -c wss://rpc-ws-pub.d-bis.org -x '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"web3_clientVersion\",\"params\":[]}'", + "dns": "dig +short rpc-ws-pub.d-bis.org", + "edge": "npx wscat -c wss://rpc-ws-pub.d-bis.org", + "origin": "nc -vz 192.168.11.221 8546" + }, + "domain": "rpc-ws-pub.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "Public WebSocket RPC / VMID 2201", + "reverseTarget": "192.168.11.221:8546", + "triagePath": "DNS -> edge -> origin -> app", + "type": "rpc-ws", + "url": "https://rpc-ws-pub.d-bis.org" + }, + { + "checks": { + "app": "curl -sk https://rpc.d-bis.org -H 'content-type: application/json' --data '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"web3_clientVersion\",\"params\":[]}'", + "dns": "dig +short rpc.d-bis.org", + "edge": "curl -skI https://rpc.d-bis.org", + "origin": "nc -vz 192.168.11.221 8545 && nc -vz 192.168.11.221 8546" + }, + "domain": "rpc.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "Canonical public RPC / VMID 2201", + "reverseTarget": "192.168.11.221:8545/8546", + "triagePath": "DNS -> edge -> origin -> app", + "type": "rpc-http", + "url": "https://rpc.d-bis.org" + }, + { + "checks": { + "app": "curl -sk https://rpc.defi-oracle.io -H 'content-type: application/json' --data '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"web3_clientVersion\",\"params\":[]}'", + "dns": "dig +short rpc.defi-oracle.io", + "edge": "curl -skI https://rpc.defi-oracle.io", + "origin": "nc -vz 192.168.11.221 8545 && nc -vz 192.168.11.221 8546" + }, + "domain": "rpc.defi-oracle.io", + "ecosystem": "proxmox", + "reverseNote": "Defi Oracle RPC alias", + "reverseTarget": "192.168.11.221:8545/8546", + "triagePath": "DNS -> edge -> origin -> app", + "type": "rpc-http", + "url": "https://rpc.defi-oracle.io" + }, + { + "checks": { + "app": "curl -sk https://rpc.public-0138.defi-oracle.io -H 'content-type: application/json' --data '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"web3_clientVersion\",\"params\":[]}'", + "dns": "dig +short rpc.public-0138.defi-oracle.io", + "edge": "curl -skI https://rpc.public-0138.defi-oracle.io", + "origin": "nc -vz 192.168.11.221 8545 && nc -vz 192.168.11.221 8546" + }, + "domain": "rpc.public-0138.defi-oracle.io", + "ecosystem": "proxmox", + "reverseNote": "Defi Oracle public RPC", + "reverseTarget": "192.168.11.221:8545/8546", + "triagePath": "DNS -> edge -> origin -> app", + "type": "rpc-http", + "url": "https://rpc.public-0138.defi-oracle.io" + }, + { + "checks": { + "app": "curl -sk https://rpc2.d-bis.org -H 'content-type: application/json' --data '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"web3_clientVersion\",\"params\":[]}'", + "dns": "dig +short rpc2.d-bis.org", + "edge": "curl -skI https://rpc2.d-bis.org", + "origin": "nc -vz 192.168.11.221 8545 && nc -vz 192.168.11.221 8546" + }, + "domain": "rpc2.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "Canonical public RPC alias / VMID 2201", + "reverseTarget": "192.168.11.221:8545/8546", + "triagePath": "DNS -> edge -> origin -> app", + "type": "rpc-http", + "url": "https://rpc2.d-bis.org" + }, + { + "checks": { + "app": "curl -skI https://sankofa.nexus", + "dns": "dig +short sankofa.nexus", + "edge": "curl -skI https://sankofa.nexus", + "origin": "nc -vz 192.168.11.51 3000" + }, + "domain": "sankofa.nexus", + "ecosystem": "other", + "reverseNote": "Sankofa portal / VMID 7801", + "reverseTarget": "192.168.11.51:3000", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://sankofa.nexus" + }, + { + "checks": { + "app": "curl -skI https://secure.d-bis.org", + "dns": "dig +short secure.d-bis.org", + "edge": "curl -skI https://secure.d-bis.org", + "origin": "nc -vz 192.168.11.130 80 && nc -vz 192.168.11.130 443" + }, + "domain": "secure.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "DBIS admin / secure portal", + "reverseTarget": "192.168.11.130:80/443", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://secure.d-bis.org" + }, + { + "checks": { + "app": "curl -skI https://secure.mim4u.org", + "dns": "dig +short secure.mim4u.org", + "edge": "curl -skI https://secure.mim4u.org", + "origin": "nc -vz 192.168.11.37 80" + }, + "domain": "secure.mim4u.org", + "ecosystem": "proxmox", + "reverseNote": "MIM4U secure", + "reverseTarget": "192.168.11.37:80", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://secure.mim4u.org" + }, + { + "checks": { + "app": "curl -skI https://solace-treasury-mgmt.defi-oracle.io", + "dns": "dig +short solace-treasury-mgmt.defi-oracle.io", + "edge": "curl -skI https://solace-treasury-mgmt.defi-oracle.io", + "origin": "nc -vz 192.168.11.60 443" + }, + "domain": "solace-treasury-mgmt.defi-oracle.io", + "ecosystem": "proxmox", + "reverseNote": "Solace treasury frontend / VMID 3000", + "reverseTarget": "192.168.11.60:443", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://solace-treasury-mgmt.defi-oracle.io" + }, + { + "checks": { + "app": "curl -skI https://studio.sankofa.nexus", + "dns": "dig +short studio.sankofa.nexus", + "edge": "curl -skI https://studio.sankofa.nexus", + "origin": "nc -vz 192.168.11.72 8000" + }, + "domain": "studio.sankofa.nexus", + "ecosystem": "sankofa", + "reverseNote": "Sankofa Studio / VMID 7805", + "reverseTarget": "192.168.11.72:8000", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://studio.sankofa.nexus" + }, + { + "checks": { + "app": "curl -skI https://the-order.sankofa.nexus", + "dns": "dig +short the-order.sankofa.nexus", + "edge": "curl -skI https://the-order.sankofa.nexus", + "origin": "nc -vz 192.168.11.39 80" + }, + "domain": "the-order.sankofa.nexus", + "ecosystem": "sankofa", + "reverseNote": "Order HAProxy / VMID 10210", + "reverseTarget": "192.168.11.39:80", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://the-order.sankofa.nexus" + }, + { + "checks": { + "app": "curl -skI https://training.mim4u.org", + "dns": "dig +short training.mim4u.org", + "edge": "curl -skI https://training.mim4u.org", + "origin": "nc -vz 192.168.11.37 80" + }, + "domain": "training.mim4u.org", + "ecosystem": "proxmox", + "reverseNote": "MIM4U training", + "reverseTarget": "192.168.11.37:80", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://training.mim4u.org" + }, + { + "checks": { + "app": "curl -skI https://webmail.d-bis.org", + "dns": "dig +short webmail.d-bis.org", + "edge": "curl -skI https://webmail.d-bis.org", + "origin": "nc -vz 192.168.11.35 443" + }, + "domain": "webmail.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "Mailcow webmail", + "reverseTarget": "192.168.11.35:443", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://webmail.d-bis.org" + }, + { + "checks": { + "app": "npx wscat -c wss://ws-rpc-ali-0x1.sankofa.nexus -x '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"web3_clientVersion\",\"params\":[]}'", + "dns": "dig +short ws-rpc-ali-0x1.sankofa.nexus", + "edge": "npx wscat -c wss://ws-rpc-ali-0x1.sankofa.nexus", + "origin": "nc -vz 192.168.11.234 8546" + }, + "domain": "ws-rpc-ali-0x1.sankofa.nexus", + "ecosystem": "sankofa", + "reverseNote": "Ali Besu WS RPC 0x1 / VMID 2304", + "reverseTarget": "192.168.11.234:8546", + "triagePath": "DNS -> edge -> origin -> app", + "type": "rpc-ws", + "url": "https://ws-rpc-ali-0x1.sankofa.nexus" + }, + { + "checks": { + "app": "npx wscat -c wss://ws-rpc-ali-0x8a.sankofa.nexus -x '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"web3_clientVersion\",\"params\":[]}'", + "dns": "dig +short ws-rpc-ali-0x8a.sankofa.nexus", + "edge": "npx wscat -c wss://ws-rpc-ali-0x8a.sankofa.nexus", + "origin": "nc -vz 192.168.11.233 8546" + }, + "domain": "ws-rpc-ali-0x8a.sankofa.nexus", + "ecosystem": "sankofa", + "reverseNote": "Ali Besu WS RPC 0x8a / VMID 2303", + "reverseTarget": "192.168.11.233:8546", + "triagePath": "DNS -> edge -> origin -> app", + "type": "rpc-ws", + "url": "https://ws-rpc-ali-0x8a.sankofa.nexus" + }, + { + "checks": { + "app": "npx wscat -c wss://ws.rpc-fireblocks.d-bis.org -x '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"web3_clientVersion\",\"params\":[]}'", + "dns": "dig +short ws.rpc-fireblocks.d-bis.org", + "edge": "npx wscat -c wss://ws.rpc-fireblocks.d-bis.org", + "origin": "nc -vz 192.168.11.211 8546" + }, + "domain": "ws.rpc-fireblocks.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "Fireblocks WS RPC / VMID 2101", + "reverseTarget": "192.168.11.211:8546", + "triagePath": "DNS -> edge -> origin -> app", + "type": "rpc-ws", + "url": "https://ws.rpc-fireblocks.d-bis.org" + }, + { + "checks": { + "app": "npx wscat -c wss://ws.rpc.d-bis.org -x '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"web3_clientVersion\",\"params\":[]}'", + "dns": "dig +short ws.rpc.d-bis.org", + "edge": "npx wscat -c wss://ws.rpc.d-bis.org", + "origin": "nc -vz 192.168.11.221 8546" + }, + "domain": "ws.rpc.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "Public WS RPC / VMID 2201", + "reverseTarget": "192.168.11.221:8546", + "triagePath": "DNS -> edge -> origin -> app", + "type": "rpc-ws", + "url": "https://ws.rpc.d-bis.org" + }, + { + "checks": { + "app": "npx wscat -c wss://ws.rpc2.d-bis.org -x '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"web3_clientVersion\",\"params\":[]}'", + "dns": "dig +short ws.rpc2.d-bis.org", + "edge": "npx wscat -c wss://ws.rpc2.d-bis.org", + "origin": "nc -vz 192.168.11.221 8546" + }, + "domain": "ws.rpc2.d-bis.org", + "ecosystem": "proxmox", + "reverseNote": "Public WS RPC alias / VMID 2201", + "reverseTarget": "192.168.11.221:8546", + "triagePath": "DNS -> edge -> origin -> app", + "type": "rpc-ws", + "url": "https://ws.rpc2.d-bis.org" + }, + { + "checks": { + "app": "npx wscat -c wss://wss.defi-oracle.io -x '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"web3_clientVersion\",\"params\":[]}'", + "dns": "dig +short wss.defi-oracle.io", + "edge": "npx wscat -c wss://wss.defi-oracle.io", + "origin": "nc -vz 192.168.11.221 8546" + }, + "domain": "wss.defi-oracle.io", + "ecosystem": "proxmox", + "reverseNote": "Defi Oracle WS RPC", + "reverseTarget": "192.168.11.221:8546", + "triagePath": "DNS -> edge -> origin -> app", + "type": "rpc-ws", + "url": "https://wss.defi-oracle.io" + }, + { + "checks": { + "app": "curl -skI https://www.mim4u.org", + "dns": "dig +short www.mim4u.org", + "edge": "curl -skI https://www.mim4u.org", + "origin": "nc -vz 192.168.11.37 80" + }, + "domain": "www.mim4u.org", + "ecosystem": "proxmox", + "reverseNote": "MIM4U www redirect", + "reverseTarget": "192.168.11.37:80", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://www.mim4u.org" + }, + { + "checks": { + "app": "curl -skI https://www.phoenix.sankofa.nexus", + "dns": "dig +short www.phoenix.sankofa.nexus", + "edge": "curl -skI https://www.phoenix.sankofa.nexus", + "origin": "nc -vz 192.168.11.50 8080" + }, + "domain": "www.phoenix.sankofa.nexus", + "ecosystem": "sankofa", + "reverseNote": "Phoenix www redirect", + "reverseTarget": "192.168.11.50:8080", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://www.phoenix.sankofa.nexus" + }, + { + "checks": { + "app": "curl -skI https://www.sankofa.nexus", + "dns": "dig +short www.sankofa.nexus", + "edge": "curl -skI https://www.sankofa.nexus", + "origin": "nc -vz 192.168.11.51 3000" + }, + "domain": "www.sankofa.nexus", + "ecosystem": "sankofa", + "reverseNote": "Sankofa www redirect", + "reverseTarget": "192.168.11.51:3000", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://www.sankofa.nexus" + }, + { + "checks": { + "app": "curl -skI https://www.the-order.sankofa.nexus", + "dns": "dig +short www.the-order.sankofa.nexus", + "edge": "curl -skI https://www.the-order.sankofa.nexus", + "origin": "nc -vz 192.168.11.39 80" + }, + "domain": "www.the-order.sankofa.nexus", + "ecosystem": "sankofa", + "reverseNote": "Order www redirect", + "reverseTarget": "192.168.11.39:80", + "triagePath": "DNS -> edge -> origin -> app", + "type": "web", + "url": "https://www.the-order.sankofa.nexus" + } + ], + "name": "Project Atlas DNS Reverse E2E Map", + "version": "v1" +} diff --git a/portal/src/data/project-atlas/network-architecture.v1.json b/portal/src/data/project-atlas/network-architecture.v1.json new file mode 100644 index 0000000..0f3b81b --- /dev/null +++ b/portal/src/data/project-atlas/network-architecture.v1.json @@ -0,0 +1,316 @@ +{ + "name": "Project Atlas Network Architecture", + "version": "v1", + "traceOrder": [ + "dns", + "edge-routing", + "host-port", + "namespace-origin", + "application-route", + "content-marker" + ], + "e2eReverseCoverage": { + "command": "bash /home/intlc/projects/proxmox/scripts/verify/verify-end-to-end-routing.sh --list-endpoints --profile=all", + "endpointCount": 61, + "artifact": "manifest/dns-e2e-reverse-map.v1.json" + }, + "cloudflaredLayers": [ + { + "layer": "public", + "description": "Cloudflared Tunnel mapped to managed public DNS" + }, + { + "layer": "sd-wan", + "description": "Cloudflared Tunnels for ecosystem-to-ecosystem routing" + }, + { + "layer": "admin", + "description": "Cloudflared Tunnel access for admin tasks and redeployments" + } + ], + "ecosystems": [ + { + "name": "Nathan / AnakaTech", + "surfaces": [ + { + "label": "CT59 SSH", + "hostname": "192.168.1.59", + "alias": "ssh ct59", + "port": 22, + "state": "verified" + }, + { + "label": "PVE SSH", + "hostname": "192.168.1.50", + "alias": "ssh pve", + "port": 22, + "state": "verified" + }, + { + "label": "Astra", + "hostname": "192.168.1.100", + "alias": "not granted", + "port": 8006, + "state": "blocked" + } + ], + "tunnelName": "wg0-p", + "auth": [ + "WireGuard VPN", + "SSH key", + "ssh_config alias" + ], + "failureModes": [ + "network unreachable", + "wrong SSH target" + ] + }, + { + "name": "Sankofa / local Proxmox infrastructure", + "surfaces": [ + { + "label": "Local Proxmox workspace", + "hostname": "this checkout", + "alias": "projectAtlas", + "port": null, + "state": "live" + }, + { + "label": "Live canary", + "hostname": "scripts/maintenance/verify-pve-cluster-health.sh", + "alias": "cluster health", + "port": null, + "state": "available" + }, + { + "label": "Public E2E verifier", + "hostname": "scripts/verify/verify-end-to-end-routing.sh", + "alias": "dns / routing sweep", + "port": null, + "state": "available" + } + ], + "auth": [ + "local shell", + "live validation scripts" + ], + "failureModes": [ + "stale docs", + "repo-only readiness claims", + "uncorroborated localhost" + ] + }, + { + "name": "Nova App / Zardasht dual production", + "surfaces": [ + { + "label": "Nova Plus local machine", + "hostname": "localhost", + "alias": "nova-plus-server", + "port": 3099, + "state": "local-production" + }, + { + "label": "Nova Bank local machine", + "hostname": "localhost", + "alias": "nova-api-1", + "port": 3000, + "state": "local-production" + }, + { + "label": "Local edge shim", + "hostname": "localhost", + "alias": "novabank-uk-edge", + "port": 9080, + "state": "local-production" + }, + { + "label": "Cloudflare tunnel ingress", + "hostname": "novabank.uk / novablockchainsystem.com", + "alias": "public ingress", + "port": 80, + "state": "mixed" + }, + { + "label": "Legacy VPS origin", + "hostname": "51.75.64.28", + "alias": "public origin", + "port": 80, + "state": "blocked" + } + ], + "auth": [ + "local shell", + "Docker Desktop", + "compose", + "remote VPS access" + ], + "cloudflareDomains": [ + { + "domain": "novablockchainsystem.com", + "zoneId": "0711dce56ea228b3fc8625b96c486eb2", + "accountId": "197663c4dea180dc3310fea5702905ac", + "accountName": "Dsbullock" + }, + { + "domain": "d-bis.org", + "zoneId": "43599eed5d83f1fa641f2aaa276d3c4d", + "accountId": "52ad57a71671c5fc009edf0744658196", + "accountName": "SGI PARTNERS, LLC" + }, + { + "domain": "novabank.uk", + "zoneId": "1f7e82b672f78a862abcbe384509841c", + "accountId": "52ad57a71671c5fc009edf0744658196", + "accountName": "SGI PARTNERS, LLC" + }, + { + "domain": "omdnl.org", + "zoneId": "b9f8979a4088c2d6cfdfe0f952a46d89", + "accountId": "52ad57a71671c5fc009edf0744658196", + "accountName": "SGI PARTNERS, LLC" + }, + { + "domain": "z-bank.uk", + "zoneId": "1790b5b392c07b181e6ba1fc421cd347", + "accountId": "52ad57a71671c5fc009edf0744658196", + "accountName": "SGI PARTNERS, LLC" + } + ], + "publicTunnelHostnames": [ + { + "hostname": "novablockchainsystem.com", + "type": "CNAME", + "target": "Railway apex", + "status": "live", + "accountName": "Dsbullock" + }, + { + "hostname": "www.novablockchainsystem.com", + "type": "CNAME", + "target": "novablockchainsystem.com", + "status": "redirect-live", + "accountName": "Dsbullock" + }, + { + "hostname": "novabank.uk", + "type": "CNAME", + "target": "aa9d668a-43bb-487d-9189-edf7300e35e8.cfargotunnel.com", + "status": "configured-pending-connector", + "accountName": "SGI PARTNERS, LLC" + }, + { + "hostname": "www.novabank.uk", + "type": "CNAME", + "target": "novabank.uk", + "status": "configured-pending-connector", + "accountName": "SGI PARTNERS, LLC" + }, + { + "hostname": "devops.novabank.uk", + "type": "CNAME", + "target": "e979ef06-cb71-4550-a1ba-326ee4d1753d.cfargotunnel.com", + "status": "operator-tunnel", + "accountName": "SGI PARTNERS, LLC" + } + ], + "publicStaticIpPlan": [ + { + "ip": "76.53.10.43", + "plannedUse": "spare / unassigned", + "status": "unused" + }, + { + "ip": "76.53.10.44", + "plannedUse": "Zardasht public service IP", + "status": "planned" + }, + { + "ip": "76.53.10.45", + "plannedUse": "Zardasht public service IP", + "status": "planned" + }, + { + "ip": "76.53.10.46", + "plannedUse": "Zardasht devops host / tunnel ingress", + "status": "planned" + } + ], + "devopsTunnel": { + "hostname": "devops.novabank.uk", + "publicIp": "76.53.10.46", + "purpose": "operator-only tunnel for pushes, admin SSH, and deploy tooling", + "ports": [ + 22, + 3000, + 3099, + 9080 + ], + "access": "Cloudflare Access app/policy + SSH + TCP", + "verifiedWith": "ssh -l novac -o ProxyCommand=cloudflared access ssh --hostname %h devops.novabank.uk" + }, + "targetTopology": [ + { + "role": "edge / ingress", + "hostname": "zardasht-edge", + "exposure": "public + SD-WAN", + "services": [ + "Cloudflared ingress", + "reverse proxy", + "route fanout" + ] + }, + { + "role": "Nova Plus app", + "hostname": "zardasht-plus", + "exposure": "internal only", + "services": [ + "nova-plus-server", + "portal runtime" + ] + }, + { + "role": "Nova Bank API", + "hostname": "zardasht-bank", + "exposure": "internal only", + "services": [ + "nova-api-1", + "bank API" + ] + }, + { + "role": "data / state", + "hostname": "zardasht-data", + "exposure": "internal only", + "services": [ + "Postgres", + "Redis", + "uploads", + "persistent volumes" + ] + }, + { + "role": "admin / ops", + "hostname": "zardasht-ops", + "exposure": "admin-only", + "services": [ + "deploy scripts", + "health checks", + "SSH/SCP", + "logs" + ] + } + ], + "failureModes": [ + "localhost used as public target", + "container unhealthy", + "wrong port mapping", + "compose not up", + "tunnel connector unhealthy", + "VPS origin unreachable", + "DNS points at the wrong origin", + "missing Proxmox LXC target definitions" + ] + } + ] +} diff --git a/portal/src/data/project-atlas/project-atlas.v1.json b/portal/src/data/project-atlas/project-atlas.v1.json new file mode 100644 index 0000000..766bdd6 --- /dev/null +++ b/portal/src/data/project-atlas/project-atlas.v1.json @@ -0,0 +1,84 @@ +{ + "name": "Project Atlas", + "version": "v1", + "statusLegend": { + "blocked": "The ecosystem endpoint or access path is known but not reachable or not yet provisioned.", + "partial": "Some access exists, but the ecosystem is not fully usable or not fully public.", + "live": "The endpoint is reachable and the service is available now.", + "verified": "A live check has been run and matched the expected output." + }, + "statusEnum": [ + "blocked", + "partial", + "live", + "verified" + ], + "ecosystems": [ + { + "name": "Nathan / AnakaTech", + "status": "verified-wireguard-ct59-pve-astra-denied", + "access": { + "type": "wireguard-and-ssh", + "state": "verified", + "tunnelName": "wg0-p", + "scopeBoundary": "Astra denied, not granted" + }, + "sourceDocs": [ + "/home/intlc/Downloads/from_Nathan/P-ANAKATECH-ACCESS.md" + ], + "verificationCommands": [ + "wg-quick up wg0-p", + "ssh ct59", + "ssh pve", + "ssh -i /home/intlc/Downloads/from_Nathan/p_anakatech_key -o BatchMode=yes -o ConnectTimeout=5 root@192.168.1.100 'hostname && id'" + ], + "nextDependency": "Astra remains denied" + }, + { + "name": "Sankofa / local Proxmox infrastructure", + "status": "available", + "access": { + "type": "workspace-and-live-ops", + "state": "available" + }, + "sourceDocs": [ + "/home/intlc/projects/proxmox/docs/02-architecture/OMNL_BANKING_PORTAL_SMOM_AND_NOVA_TRUST_ARCHITECTURE.md", + "/home/intlc/projects/proxmox/docs/MASTER_INDEX.md", + "/home/intlc/projects/projectAtlas/docs/network-architecture.md" + ], + "verificationCommands": [ + "bash /home/intlc/projects/proxmox/scripts/maintenance/verify-pve-cluster-health.sh" + ], + "nextDependency": "ongoing-live-validation" + }, + { + "name": "Nova App / Zardasht dual production", + "status": "partial-dual-production-local-live-devops-live-public-tunnel-configured-pending-health", + "access": { + "type": "dual-production", + "state": "partial", + "tunnelName": "local-machine-and-vps", + "scopeBoundary": "Local machine and devops tunnel are live; the Dsbullock apex is live on Railway with www redirecting to apex, while novabank.uk is published but still connector-pending" + }, + "sourceDocs": [ + "/home/intlc/projects/projectAtlas/atlas.md", + "/home/intlc/projects/projectAtlas/docs/network-architecture.md", + "/home/intlc/projects/projectAtlas/ecosystems/zardasht-dual-production.md", + "/home/intlc/projects/projectAtlas/ecosystems/zardasht-migration-runbook.md", + "/home/intlc/projects/nova-trust/docs/architecture/system-atlas.md" + ], + "verificationCommands": [ + "docker ps --format '{{.Names}}\\t{{.Status}}\\t{{.Ports}}'", + "ipconfig", + "curl -I http://localhost:3099", + "curl -I http://localhost:3000", + "curl -I http://localhost:9080", + "curl -I http://51.75.64.28/", + "curl -I https://novablockchainsystem.com", + "curl -I https://novabank.uk", + "ssh -l novac -o ProxyCommand=\"cloudflared access ssh --hostname %h\" devops.novabank.uk 'hostname && id'" + ], + "nextDependency": "define-proxmox-lxc-targets-and-public-cutover" + } + ] +} diff --git a/portal/src/lib/atlas.ts b/portal/src/lib/atlas.ts index 5c1836c..e500f95 100644 --- a/portal/src/lib/atlas.ts +++ b/portal/src/lib/atlas.ts @@ -1,4 +1,7 @@ import { itReadApiBaseUrl, itReadApiKey } from '@/app/api/it/_auth'; +import projectAtlasReverseMapJson from '@/data/project-atlas/dns-e2e-reverse-map.v1.json'; +import projectAtlasNetworkJson from '@/data/project-atlas/network-architecture.v1.json'; +import projectAtlasRegistryJson from '@/data/project-atlas/project-atlas.v1.json'; export type AtlasRouteRow = { hostnames: string[]; @@ -60,6 +63,81 @@ export type AtlasSnapshot = { type RecordLike = Record; +type ProjectAtlasRegistry = { + ecosystems: Array<{ + name: string; + status: string; + access?: { + type?: string; + state?: string; + tunnelName?: string; + scopeBoundary?: string; + }; + sourceDocs?: string[]; + verificationCommands?: string[]; + nextDependency?: string; + }>; +}; + +type ProjectAtlasNetwork = { + e2eReverseCoverage?: { + command?: string; + endpointCount?: number; + artifact?: string; + }; + cloudflaredLayers?: Array<{ + layer: string; + description: string; + }>; + ecosystems?: Array<{ + name: string; + publicTunnelHostnames?: Array<{ + hostname: string; + type: string; + target: string; + status: string; + accountName?: string; + }>; + cloudflareDomains?: Array<{ + domain: string; + zoneId: string; + accountId: string; + accountName: string; + }>; + publicStaticIpPlan?: Array<{ + ip: string; + plannedUse: string; + status: string; + }>; + }>; +}; + +type ProjectAtlasReverseMap = { + endpointCount: number; + endpoints: Array<{ + domain: string; + type: string; + url: string; + ecosystem: string; + triagePath: string; + reverseTarget: string; + reverseNote?: string; + checks?: Record; + }>; +}; + +const projectAtlasRegistry = projectAtlasRegistryJson as ProjectAtlasRegistry; +const projectAtlasNetwork = projectAtlasNetworkJson as ProjectAtlasNetwork; +const projectAtlasReverseMap = projectAtlasReverseMapJson as ProjectAtlasReverseMap; + +function fetchProjectAtlasEcosystem(name: string) { + return projectAtlasRegistry.ecosystems.find((ecosystem) => ecosystem.name === name); +} + +function fetchProjectAtlasNetworkEcosystem(name: string) { + return projectAtlasNetwork.ecosystems?.find((ecosystem) => ecosystem.name === name); +} + async function fetchJson(url: string, apiKey?: string): Promise { try { const res = await fetch(url, { @@ -105,6 +183,48 @@ function toText(value: unknown, fallback = '—'): string { return fallback; } +function isInternalRoute(domain: string, type: string): boolean { + if (type === 'ssh') return true; + const normalized = domain.toLowerCase(); + return [ + 'portal.', + 'keycloak.', + 'admin.', + 'dash.', + 'rancher.', + 'argocd.', + 'grafana.', + 'vault.', + 'k8s-api.', + 'devops.', + 'mail.', + 'webmail.', + 'pve.', + 'cc.', + 'auth.cc.', + 'entity.cc.', + ].some((needle) => normalized.includes(needle)); +} + +function isPendingRoute(domain: string, status: string): boolean { + const normalized = domain.toLowerCase(); + return ( + status.includes('pending') || + status.includes('blocked') || + normalized === 'novabank.uk' || + normalized === 'www.novabank.uk' + ); +} + +function dedupeRoutes(rows: AtlasRouteRow[]): AtlasRouteRow[] { + const seen = new Map(); + for (const row of rows) { + const key = row.hostnames.join('|'); + if (!seen.has(key)) seen.set(key, row); + } + return [...seen.values()]; +} + function buildGuestRows(liveInventory: unknown): AtlasGuestRow[] { const rows = firstRecordArray(liveInventory); const vmRows = rows.filter((row) => @@ -123,141 +243,83 @@ function buildGuestRows(liveInventory: unknown): AtlasGuestRow[] { })); } -function buildRoutes(): AtlasRouteRow[] { - return [ - { - hostnames: ['sankofa.nexus', 'www.sankofa.nexus'], - edge: 'Cloudflare DNS -> 76.53.10.36 -> NPMplus', - backend: '192.168.11.51:3000 Sankofa public site', - visibility: 'public', - status: 'live', - source: 'docs/INSTITUTIONAL_REGISTRY.md', - notes: 'Public corporate apex. www canonicalizes to apex.', - }, - { - hostnames: ['phoenix.sankofa.nexus', 'www.phoenix.sankofa.nexus'], - edge: 'Cloudflare DNS -> 76.53.10.36 -> NPMplus', - backend: '192.168.11.50:4000 Phoenix surface', - visibility: 'public', - status: 'live', - source: 'docs/INSTITUTIONAL_REGISTRY.md', - }, - { - hostnames: ['the-order.sankofa.nexus', 'www.the-order.sankofa.nexus'], - edge: 'Cloudflare DNS -> 76.53.10.36 -> 192.168.11.39:80 HAProxy -> portal', - backend: '192.168.11.51:3000 Sankofa portal stack', - visibility: 'public', - status: 'live', - source: 'docs/04-configuration/ALL_VMIDS_ENDPOINTS.md', - notes: 'www redirects to apex.', - }, - { - hostnames: ['studio.sankofa.nexus'], - edge: 'Cloudflare DNS -> 76.53.10.36 -> NPMplus', - backend: '192.168.11.72:8000 Sankofa Studio', - visibility: 'public', - status: 'live', - source: 'docs/04-configuration/ALL_VMIDS_ENDPOINTS.md', - notes: 'Public tooling surface under /studio.', - }, - { - hostnames: ['portal.sankofa.nexus'], - edge: 'Cloudflare Tunnel -> control-plane ingress', - backend: 'portal.portal.svc.cluster.local:80', - visibility: 'internal', - status: 'live', - source: 'cloudflare/tunnel-configs/control-plane.yaml', - notes: 'Client workspace and SSO shell.', - }, - { - hostnames: ['keycloak.sankofa.nexus'], - edge: 'Cloudflare Tunnel -> control-plane ingress', - backend: 'keycloak.keycloak.svc.cluster.local:8080', - visibility: 'internal', - status: 'live', - source: 'cloudflare/tunnel-configs/control-plane.yaml', - notes: 'Shared identity provider.', - }, - { - hostnames: ['admin.sankofa.nexus'], - edge: 'Cloudflare DNS -> NPMplus / protected app', - backend: 'SSO administration boundary', - visibility: 'internal', - status: 'documented', - source: 'docs/02-architecture/EXPECTED_WEB_CONTENT.md', - }, - { - hostnames: ['dash.sankofa.nexus'], - edge: 'Cloudflare DNS -> NPMplus / operator access', - backend: 'IP allowlist + MFA operator dashboard', - visibility: 'hidden', - status: 'documented', - source: 'docs/02-architecture/EXPECTED_WEB_CONTENT.md', - }, - { - hostnames: ['pve.sankofa.nexus', 'pve1.sankofa.nexus'], - edge: 'Cloudflare DNS -> NPMplus / tunnel', - backend: 'Proxmox management surfaces', - visibility: 'hidden', - status: 'documented', - source: 'docs/INSTITUTIONAL_REGISTRY.md', - }, - { - hostnames: ['cc.sankofa.nexus', 'auth.cc.sankofa.nexus', 'admin.cc.sankofa.nexus', 'entity.cc.sankofa.nexus'], - edge: 'Cloudflare DNS -> Complete Credential stack', - backend: 'Credential issuance and admin portals', - visibility: 'hidden', - status: 'documented', - source: 'docs/INSTITUTIONAL_REGISTRY.md', - }, - { - hostnames: ['ml110-01.sankofa.nexus', 'ml110-01-api.sankofa.nexus', 'ml110-01-metrics.sankofa.nexus'], - edge: 'Cloudflare DNS -> internal instance routing', - backend: '192.168.11.10 / instance services', - visibility: 'hidden', - status: 'documented', - source: 'docs/proxmox/DNS_CONFIGURATION.md', - }, - { - hostnames: ['r630-01.sankofa.nexus', 'r630-01-api.sankofa.nexus', 'r630-01-metrics.sankofa.nexus'], - edge: 'Cloudflare DNS -> internal instance routing', - backend: '192.168.11.11 / instance services', - visibility: 'hidden', - status: 'documented', - source: 'docs/proxmox/DNS_CONFIGURATION.md', - }, - { - hostnames: ['rancher.sankofa.nexus', 'argocd.sankofa.nexus', 'grafana.sankofa.nexus', 'vault.sankofa.nexus', 'k8s-api.sankofa.nexus'], - edge: 'Cloudflare Tunnel -> control-plane ingress', - backend: 'Kubernetes control-plane services', - visibility: 'hidden', - status: 'documented', - source: 'cloudflare/tunnel-configs/control-plane.yaml', - }, - ]; +function buildProjectAtlasRoutes(): AtlasRouteRow[] { + const routes: AtlasRouteRow[] = []; + + const zardashtNetwork = fetchProjectAtlasNetworkEcosystem('Nova App / Zardasht dual production'); + for (const entry of zardashtNetwork?.publicTunnelHostnames ?? []) { + routes.push({ + hostnames: [entry.hostname], + edge: + entry.type.toUpperCase() === 'CNAME' + ? `Cloudflare Tunnel -> ${entry.target}` + : `Cloudflare DNS -> ${entry.target}`, + backend: entry.target, + visibility: isInternalRoute(entry.hostname, entry.type) ? 'internal' : 'public', + status: isPendingRoute(entry.hostname, entry.status) ? 'pending' : 'live', + source: 'projectAtlas/manifest/network-architecture.v1.json', + notes: [entry.accountName, entry.type].filter(Boolean).join(' · '), + }); + } + + for (const endpoint of projectAtlasReverseMap.endpoints) { + routes.push({ + hostnames: [endpoint.domain], + edge: endpoint.triagePath, + backend: endpoint.reverseTarget, + visibility: isInternalRoute(endpoint.domain, endpoint.type) ? 'internal' : 'public', + status: isPendingRoute(endpoint.domain, endpoint.reverseNote ?? '') ? 'pending' : 'live', + source: 'projectAtlas/manifest/dns-e2e-reverse-map.v1.json', + notes: endpoint.reverseNote ?? endpoint.checks?.origin ?? undefined, + }); + } + + return dedupeRoutes(routes).sort((a, b) => a.hostnames[0].localeCompare(b.hostnames[0])); } function buildHiddenRows(): AtlasHiddenRow[] { + const nathan = fetchProjectAtlasEcosystem('Nathan / AnakaTech'); + const sankofa = fetchProjectAtlasEcosystem('Sankofa / local Proxmox infrastructure'); + const zardasht = fetchProjectAtlasEcosystem('Nova App / Zardasht dual production'); + const reverseCoverage = projectAtlasNetwork.e2eReverseCoverage; + const cloudflaredLayers = projectAtlasNetwork.cloudflaredLayers ?? []; + const publicIpPlan = fetchProjectAtlasNetworkEcosystem('Nova App / Zardasht dual production')?.publicStaticIpPlan ?? []; + return [ { - label: 'Atlas hidden inventory', - detail: 'Public page can surface routes and hosts that are documented in repo but not exposed in the main nav.', - source: 'portal/src/lib/atlas.ts', + label: 'Project Atlas source-of-truth', + detail: 'Project Atlas is the canonical mapping source for the Sankofa atlas page and is vendored locally for production rendering.', + source: 'portal/src/data/project-atlas/project-atlas.v1.json', }, { - label: 'IT read API', - detail: 'Server-side inventory and drift fetches are backed by IT_READ_API_URL and IT_READ_API_KEY.', - source: 'portal/src/app/api/it/_auth.ts', + label: 'Nathan / AnakaTech', + detail: `${nathan?.status ?? 'unknown'} · ${nathan?.access?.scopeBoundary ?? 'no access boundary recorded'}`, + source: 'portal/src/data/project-atlas/project-atlas.v1.json', }, { - label: 'Control-plane tunnel', - detail: 'portal, keycloak, rancher, argocd, grafana, vault, and k8s-api share the Cloudflare tunnel ingress.', - source: 'cloudflare/tunnel-configs/control-plane.yaml', + label: 'Sankofa / local Proxmox infrastructure', + detail: `${sankofa?.status ?? 'unknown'} · ${sankofa?.nextDependency ?? 'no next dependency recorded'}`, + source: 'portal/src/data/project-atlas/project-atlas.v1.json', }, { - label: 'Proxmox instance DNS', - detail: 'ml110-01 and r630-01 hostnames are documented internal inventory rather than public marketing surfaces.', - source: 'docs/proxmox/DNS_CONFIGURATION.md', + label: 'Nova App / Zardasht dual production', + detail: `${zardasht?.status ?? 'unknown'} · ${zardasht?.access?.scopeBoundary ?? 'no scope boundary recorded'}`, + source: 'portal/src/data/project-atlas/project-atlas.v1.json', + }, + { + label: 'Reverse coverage', + detail: `${reverseCoverage?.endpointCount ?? projectAtlasReverseMap.endpointCount} endpoints mapped with DNS -> edge -> origin -> app trace order.`, + source: 'portal/src/data/project-atlas/network-architecture.v1.json', + }, + { + label: 'Cloudflared layers', + detail: cloudflaredLayers.map((layer) => `${layer.layer}: ${layer.description}`).join(' · '), + source: 'portal/src/data/project-atlas/network-architecture.v1.json', + }, + { + label: 'Public IP plan', + detail: publicIpPlan.map((entry) => `${entry.ip} (${entry.status})`).join(' · '), + source: 'portal/src/data/project-atlas/network-architecture.v1.json', }, ]; } @@ -266,23 +328,23 @@ function buildRevisions(): AtlasRevision[] { return [ { date: '2026-07-28', - title: 'Atlas route published', - detail: 'Added a public /atlas page on the Sankofa apex so the route can be linked from the corporate shell.', + title: 'Project Atlas imported into Sankofa', + detail: 'The Sankofa /atlas page now renders from vendored Project Atlas manifests instead of a separate synthetic dataset.', }, { - date: '2026-06-04', - title: 'Institutional registry published', - detail: 'Documented the primary Sankofa and Phoenix hostnames, including public portal and identity boundaries.', + date: '2026-07-28', + title: 'DNS reverse map synchronized', + detail: 'The 61-endpoint reverse map is now available locally for public rendering and filtering.', }, { - date: '2026-03-27', - title: 'NPM routing authority updated', - detail: 'Route ownership for sankofa.nexus, phoenix.sankofa.nexus, and the-order.sankofa.nexus was consolidated in the NPM routing docs.', + date: '2026-07-28', + title: 'Network architecture synchronized', + detail: 'Cloudflared layers, public ingress, and tunnel-bound hostnames are read from the Project Atlas network manifest.', }, { - date: '2025-12-15', - title: 'Cluster status baseline', - detail: 'The sfvalley-01 Proxmox / Ceph status report captured the original cluster baseline and quorum state.', + date: '2026-07-28', + title: 'Live inventory remains server-side', + detail: 'IT inventory and drift counters continue to come from the portal server read API so the page stays current.', }, ]; } @@ -291,33 +353,33 @@ function buildRecommendations(): AtlasRecommendation[] { return [ { priority: 'P1', - title: 'Publish an atlas snapshot feed', - detail: 'Generate a JSON snapshot of routes, hosts, and revision history so public rendering and incident review use the same payload.', + title: 'Keep Project Atlas as the source of truth', + detail: 'Treat the vendored Project Atlas manifests as the canonical dataset for Sankofa /atlas and refresh them when routing changes.', }, { priority: 'P1', - title: 'Keep live inventory server-side', - detail: 'Continue fetching the IT inventory from the server-side read API so the public page stays current without exposing credentials.', + title: 'Automate manifest sync', + detail: 'Add a small sync step from the `projectAtlas` repo so the production page can stay current without hand-copying JSON.', }, { priority: 'P2', - title: 'Export hidden inventory separately', - detail: 'Add a distinct capture-required section for hidden or operator-only hosts so the public page stays readable while still exhaustive.', + title: 'Add download/export controls', + detail: 'Expose JSON and CSV exports so operators can reuse the atlas for handoffs and incident review.', }, { priority: 'P2', - title: 'Add CSV / JSON export buttons', - detail: 'Allow the atlas to feed handoff, audit, and escalation workflows without copy/paste.', + title: 'Add health badges next', + detail: 'Augment route rows with live edge health once the public probes are wired in.', }, { priority: 'P3', - title: 'Add route health badges', - detail: 'Annotate route rows with health and 404/5xx checks once the checkers are wired to the public edge.', + title: 'Render the markdown atlas snapshot', + detail: 'Surface the human-readable atlas summary alongside the tables if a document-style view is useful to operators.', }, ]; } -async function loadLiveSummary() { +async function loadLiveSummary(liveInventory: unknown | null) { const base = itReadApiBaseUrl(); const apiKey = itReadApiKey(); const readApiConfigured = Boolean(base); @@ -337,18 +399,15 @@ async function loadLiveSummary() { } const root = base.replace(/\/$/, ''); - const [summary, inventory, portMap] = await Promise.all([ + const [summary, portMap] = await Promise.all([ fetchJson(`${root}/v1/summary`, apiKey), - fetchJson(`${root}/v1/inventory/live`, apiKey), fetchJson(`${root}/v1/portmap/joined`, apiKey), ]); const summaryRecord = asRecord(summary); - const inventoryRecord = asRecord(inventory); + const inventoryRecord = asRecord(liveInventory); const portMapRecord = asRecord(portMap); - const guestRows = buildGuestRows(inventoryRecord ?? inventory); - - const liveSummary = summaryRecord && 'artifacts' in summaryRecord ? (summaryRecord.artifacts as RecordLike) : null; + const guestRows = buildGuestRows(liveInventory); return { collectedAt: @@ -360,39 +419,27 @@ async function loadLiveSummary() { : typeof summaryRecord?.guest_count === 'number' ? summaryRecord.guest_count : null, - stoppedCount: - typeof inventoryRecord?.stopped === 'number' ? inventoryRecord.stopped : null, + stoppedCount: typeof inventoryRecord?.stopped === 'number' ? inventoryRecord.stopped : null, portMapState: portMapRecord?.stale ? 'stale' : 'live', portMapNote: toText(portMapRecord?.note, undefined), - inventoryState: inventory ? 'live' : 'unavailable', + inventoryState: inventoryRecord ? 'live' : 'unavailable', summaryState: summary ? 'live' : 'unavailable', readApiConfigured, - // keep the snapshot summary available if the UI wants to expose it later - // without another fetch path. - ...(liveSummary ? { liveArtifacts: liveSummary } : {}), - } as AtlasSnapshot['liveSummary'] & { liveArtifacts?: RecordLike }; + }; } export async function loadAtlasSnapshot(): Promise { - const liveSummary = await loadLiveSummary(); - const routes = buildRoutes(); - const hiddenRows = buildHiddenRows(); - const revisions = buildRevisions(); - const recommendations = buildRecommendations(); - - const liveInventory = await (async () => { - const base = itReadApiBaseUrl(); - const apiKey = itReadApiKey(); - if (!base) return null; - return fetchJson(`${base.replace(/\/$/, '')}/v1/inventory/live`, apiKey); - })(); + const base = itReadApiBaseUrl(); + const apiKey = itReadApiKey(); + const liveInventory = base ? await fetchJson(`${base.replace(/\/$/, '')}/v1/inventory/live`, apiKey) : null; + const liveSummary = await loadLiveSummary(liveInventory); return { - routeRows: routes, + routeRows: buildProjectAtlasRoutes(), guestRows: buildGuestRows(liveInventory), - hiddenRows, - revisions, - recommendations, + hiddenRows: buildHiddenRows(), + revisions: buildRevisions(), + recommendations: buildRecommendations(), liveSummary, }; }