Files
riotpiao.com/lib/clusterMock.ts
T

184 lines
7.7 KiB
TypeScript
Raw Normal View History

2026-08-18 18:33:49 -07:00
/**
* Layout placeholder fixtures.
*
* Shapes mirror the `atlas` DTOs described in docs/PLAN-atlas.md, and the values
* are transcribed from the real cluster so the layout is sized against real
* cardinality (32 apps, 9 sync waves, ~550 resources).
*
* Redaction rules from the plan are already applied here: no node IPs, no pod
* IPs, no container args, no image tags, no repo URLs, no Secret names.
*/
export type Health = 'healthy' | 'degraded' | 'progressing'
export type Sync = 'synced' | 'outofsync'
export const cluster = {
distro: 'Talos v1.13.3',
kubernetes: 'v1.36.1',
snapshotAge: 2.1,
generation: 88412,
} as const
export type Node = {
name: string
role: string
cpu: number
memoryGi: number
gpu: number
pods: number
health: Health
}
export const nodes: Node[] = [
{ name: 'talos-cp-1', role: 'control-plane', cpu: 8, memoryGi: 16, gpu: 0, pods: 24, health: 'healthy' },
{ name: 'talos-cp-2', role: 'control-plane', cpu: 8, memoryGi: 16, gpu: 0, pods: 31, health: 'healthy' },
{ name: 'talos-cp-3', role: 'control-plane', cpu: 8, memoryGi: 16, gpu: 0, pods: 28, health: 'healthy' },
{ name: 'worker-1', role: 'gpu-node', cpu: 96, memoryGi: 62, gpu: 1, pods: 55, health: 'healthy' },
]
export type Namespace = {
name: string
running: number
total: number
}
export const namespaces: Namespace[] = [
{ name: 'kube-system', running: 21, total: 21 },
{ name: 'longhorn-system', running: 30, total: 31 },
{ name: 'sqs', running: 13, total: 19 },
{ name: 'logging', running: 12, total: 12 },
{ name: 'monitoring', running: 9, total: 11 },
{ name: 'temporal', running: 9, total: 10 },
{ name: 'llm-serving', running: 6, total: 6 },
{ name: 'iam', running: 6, total: 6 },
{ name: 'cicd', running: 6, total: 6 },
{ name: 'argocd', running: 6, total: 8 },
{ name: 'ingress-nginx', running: 4, total: 4 },
{ name: 'cert-manager', running: 3, total: 6 },
{ name: 'api', running: 2, total: 2 },
{ name: 'storage', running: 2, total: 2 },
{ name: 'dashboard', running: 2, total: 2 },
{ name: 'cloudflared', running: 2, total: 2 },
{ name: 'cnpg-system', running: 1, total: 2 },
{ name: 'gpu-system', running: 1, total: 1 },
{ name: 'kserve', running: 1, total: 1 },
{ name: 'reloader', running: 1, total: 1 },
{ name: 'sms', running: 0, total: 1 },
]
export type Model = {
name: string
replicas: number
seqPerReplica: number
contextTokens: number
ready: boolean
}
/** Model identifiers and quantization strategy are deliberately not surfaced. */
export const models: Model[] = [
{ name: 'reasoning', replicas: 2, seqPerReplica: 4, contextTokens: 16384, ready: true },
{ name: 'ornith', replicas: 1, seqPerReplica: 4, contextTokens: 16384, ready: true },
{ name: 'embeddings', replicas: 1, seqPerReplica: 8, contextTokens: 8192, ready: true },
{ name: 'reranker', replicas: 1, seqPerReplica: 8, contextTokens: 8192, ready: true },
{ name: 'verifier', replicas: 1, seqPerReplica: 4, contextTokens: 16384, ready: true },
]
/** `--max-num-seqs=4` x `minReplicas: 2`. The number the whole design is sized against. */
export const SEQUENCE_SLOTS = 8
/** Operator headroom: 2 of 8 slots never handed to visitors. */
export const PUBLIC_SLOT_CAP = 6
export type App = {
name: string
wave: number | null
sync: Sync
health: Health
resources: number
}
export const apps: App[] = [
{ name: 'homelab-root', wave: null, sync: 'synced', health: 'healthy', resources: 31 },
{ name: 'cert-manager', wave: 0, sync: 'synced', health: 'healthy', resources: 47 },
{ name: 'prometheus-crds', wave: 0, sync: 'synced', health: 'healthy', resources: 10 },
{ name: 'reloader', wave: 0, sync: 'synced', health: 'healthy', resources: 6 },
{ name: 'sops-secrets', wave: 0, sync: 'synced', health: 'healthy', resources: 16 },
{ name: 'prometheus', wave: 1, sync: 'synced', health: 'healthy', resources: 68 },
{ name: 'blackbox-exporter', wave: 1, sync: 'synced', health: 'healthy', resources: 17 },
{ name: 'ingress-config', wave: 1, sync: 'synced', health: 'healthy', resources: 14 },
{ name: 'longhorn-config', wave: 1, sync: 'outofsync', health: 'healthy', resources: 12 },
{ name: 'minio-operator', wave: 1, sync: 'synced', health: 'healthy', resources: 9 },
{ name: 'cert-manager-issuers', wave: 1, sync: 'synced', health: 'healthy', resources: 7 },
{ name: 'minio-tenant', wave: 1, sync: 'synced', health: 'healthy', resources: 1 },
{ name: 'monitoring-config', wave: 2, sync: 'synced', health: 'healthy', resources: 24 },
{ name: 'loki', wave: 2, sync: 'synced', health: 'healthy', resources: 16 },
{ name: 'grafana', wave: 2, sync: 'synced', health: 'healthy', resources: 11 },
{ name: 'databases', wave: 2, sync: 'synced', health: 'healthy', resources: 5 },
{ name: 'promtail', wave: 2, sync: 'synced', health: 'healthy', resources: 5 },
{ name: 'authentik', wave: 3, sync: 'synced', health: 'healthy', resources: 13 },
{ name: 'iam-jobs', wave: 3, sync: 'synced', health: 'healthy', resources: 9 },
{ name: 'vault', wave: 3, sync: 'synced', health: 'healthy', resources: 8 },
{ name: 'forgejo-runner', wave: 3, sync: 'synced', health: 'healthy', resources: 4 },
{ name: 'strimzi-operator', wave: 5, sync: 'synced', health: 'healthy', resources: 27 },
{ name: 'kmsvc-redis', wave: 5, sync: 'synced', health: 'healthy', resources: 13 },
{ name: 'queue-crd', wave: 6, sync: 'synced', health: 'healthy', resources: 6 },
{ name: 'kafka-cluster', wave: 6, sync: 'synced', health: 'healthy', resources: 2 },
{ name: 'kong', wave: 7, sync: 'synced', health: 'healthy', resources: 39 },
{ name: 'management-service', wave: 7, sync: 'synced', health: 'healthy', resources: 6 },
{ name: 'temporal', wave: 8, sync: 'synced', health: 'healthy', resources: 16 },
{ name: 'sms', wave: 8, sync: 'synced', health: 'degraded', resources: 7 },
{ name: 'portainer', wave: 8, sync: 'synced', health: 'healthy', resources: 5 },
{ name: 'homarr', wave: 8, sync: 'synced', health: 'healthy', resources: 3 },
{ name: 'cloudflared', wave: 8, sync: 'synced', health: 'healthy', resources: 1 },
]
export const WAVES = [0, 1, 2, 3, 4, 5, 6, 7, 8]
export function appsInWave(wave: number): App[] {
return apps.filter((a) => a.wave === wave)
}
/** Resource kinds for the drill-down panel. Secrets are counted, never named. */
export const resourceKinds: Record<string, Array<{ kind: string; count: number; named: boolean }>> = {
prometheus: [
{ kind: 'PrometheusRule', count: 24, named: true },
{ kind: 'ServiceMonitor', count: 18, named: true },
{ kind: 'Service', count: 9, named: true },
{ kind: 'ConfigMap', count: 6, named: true },
{ kind: 'Deployment', count: 4, named: true },
{ kind: 'ClusterRole', count: 4, named: true },
{ kind: 'Secret', count: 3, named: false },
],
kong: [
{ kind: 'CustomResourceDefinition', count: 14, named: true },
{ kind: 'ClusterRole', count: 8, named: true },
{ kind: 'Service', count: 5, named: true },
{ kind: 'KongPlugin', count: 5, named: true },
{ kind: 'Ingress', count: 4, named: true },
{ kind: 'Secret', count: 3, named: false },
],
'cert-manager': [
{ kind: 'CustomResourceDefinition', count: 12, named: true },
{ kind: 'ClusterRole', count: 11, named: true },
{ kind: 'ClusterRoleBinding', count: 9, named: true },
{ kind: 'ServiceAccount', count: 6, named: true },
{ kind: 'Deployment', count: 3, named: true },
{ kind: 'Service', count: 3, named: true },
{ kind: 'ValidatingWebhookConfiguration', count: 3, named: true },
],
}
export const DEFAULT_KINDS = [
{ kind: 'Service', count: 3, named: true },
{ kind: 'Deployment', count: 2, named: true },
{ kind: 'ConfigMap', count: 2, named: true },
{ kind: 'Secret', count: 1, named: false },
]