#!/usr/bin/env tsx /** * Generate network topology JSON from entity registry * Usage: tsx scripts/infrastructure/generate-topology-data.ts */ import * as fs from 'fs' import * as path from 'path' import type { NetworkTopology, TopologyNode, TopologyEdge } from '../../src/lib/types/infrastructure' const PROJECT_ROOT = path.resolve(__dirname, '../..') const DATA_DIR = path.join(PROJECT_ROOT, 'docs/infrastructure/data') const ENTITY_REGISTRY = path.join(PROJECT_ROOT, 'docs/infrastructure/ENTITY_REGISTRY.md') // Generate topology data based on entity registry structure function generateTopologyData(): NetworkTopology[] { const topologies: NetworkTopology[] = [] // Cloudflare as root node const cloudflareNode: TopologyNode = { id: 'cloudflare', type: 'region', label: 'Cloudflare Global Network', region: 'Global', entity: 'Cloudflare', position: { x: 400, y: 50 }, metadata: { asn: 'AS13335', dataCenters: 300, }, } // VM 137 - Cloudflare Tunnel const vm137Node: TopologyNode = { id: 'vm-137', type: 'vm', label: 'VM 137 (cloudflare-tunnel-vm)', region: 'Site 2', entity: 'Sankofa Phoenix', position: { x: 300, y: 200 }, metadata: { vmid: 137, host: 'r630-01', ip: '192.168.11.11', function: 'Cloudflare Tunnel Agent', }, } // VM 136 - Nginx Proxy const vm136Node: TopologyNode = { id: 'vm-136', type: 'vm', label: 'VM 136 (nginx-proxy-vm)', region: 'Site 1', entity: 'Sankofa Phoenix', position: { x: 500, y: 200 }, metadata: { vmid: 136, host: 'ml110-01', ip: '192.168.11.10', function: 'Reverse Proxy, SSL Termination', }, } // Regional topologies for SMOM const smomRegions = [ { name: 'Europe', x: 400, y: 350, countries: 35 }, { name: 'Americas', x: 200, y: 350, countries: 26 }, { name: 'Asia-Pacific', x: 600, y: 350, countries: 14 }, { name: 'Africa', x: 400, y: 500, countries: 36 }, { name: 'Middle East', x: 500, y: 500, countries: 4 }, ] smomRegions.forEach((region, index) => { const regionNode: TopologyNode = { id: `region-${region.name.toLowerCase()}`, type: 'region', label: `${region.name} Region`, region: region.name, entity: 'Sovereign Order of Hospitallers', position: { x: region.x, y: region.y }, metadata: { countries: region.countries, priority: index < 2 ? 'High' : 'Medium', }, } const datacenterNode: TopologyNode = { id: `dc-${region.name.toLowerCase()}`, type: 'datacenter', label: `${region.name} Datacenter`, region: region.name, entity: 'Sovereign Order of Hospitallers', position: { x: region.x, y: region.y + 100 }, metadata: { tier: index < 2 ? 'Tier 1' : 'Tier 2', }, } const tunnelNode: TopologyNode = { id: `tunnel-${region.name.toLowerCase()}`, type: 'tunnel', label: `${region.name} Tunnel`, region: region.name, entity: 'Sovereign Order of Hospitallers', position: { x: region.x + 100, y: region.y }, metadata: { tunnelId: `hospitallers-${region.name.toLowerCase()}-tunnel`, networkRoute: `10.${10 + index}.0.0/16`, }, } const edges: TopologyEdge[] = [ { id: `edge-cloudflare-${region.name.toLowerCase()}`, source: 'cloudflare', target: regionNode.id, type: 'tunnel', metadata: { bandwidth: '10Gbps' }, }, { id: `edge-${region.name.toLowerCase()}-dc`, source: regionNode.id, target: datacenterNode.id, type: 'network-route', metadata: {}, }, { id: `edge-${region.name.toLowerCase()}-tunnel`, source: regionNode.id, target: tunnelNode.id, type: 'tunnel', metadata: {}, }, ] topologies.push({ nodes: [cloudflareNode, vm137Node, vm136Node, regionNode, datacenterNode, tunnelNode], edges: [ { id: 'edge-cloudflare-vm137', source: 'cloudflare', target: 'vm-137', type: 'tunnel', metadata: {}, }, { id: 'edge-vm137-vm136', source: 'vm-137', target: 'vm-136', type: 'network-route', metadata: {}, }, ...edges, ], region: region.name, entity: 'Sovereign Order of Hospitallers', lastUpdated: new Date().toISOString(), }) }) return topologies } function main() { const topologies = generateTopologyData() // Write individual topology files topologies.forEach(topology => { const filename = `topology-${topology.region.toLowerCase().replace(/\s+/g, '-')}.json` const filepath = path.join(DATA_DIR, filename) fs.writeFileSync(filepath, JSON.stringify(topology, null, 2)) console.log(`✓ Created ${filename}`) }) // Write combined topology file const combinedFile = path.join(DATA_DIR, 'network_topology.json') fs.writeFileSync(combinedFile, JSON.stringify(topologies, null, 2)) console.log(`✓ Created network_topology.json with ${topologies.length} regional topologies`) } if (require.main === module) { main() }