docs(hardware): reconcile rack01 to as-mounted layout and document cabling
Rebuild rack01 from the physically remounted hardware: - Correct stale positions/ports/outlets for pp01, pp02, sw01, pdu01-04 - Model shelves as 1U trays (towers stand above without consuming rack U's); add shf02 and empty half-depth shf03/shf04 - Add ups01/ups02; reseat nas01/02 and sw02-05; move srv04-07 onto shf02 - Add `wan` hardware kind; add WAN demarcation hosts wan01 (active) and wan02 (staging) - Document full live network wiring: srv01-07 -> pp02 -> sw01 (LAN) and srv01 eth0 -> pp02 -> pp01 -> wan01 (WAN); keep non-active lines (wan2, working-table patches, sw01 mgmt) in notes only - Regenerate hardware index + rack01 elevation/network/power artifacts Also includes the in-progress generator updates (gen_rack.py, gen_overview.py, Makefile, tests) that the regenerated artifacts depend on. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8f4047cdd7
commit
4dc975062a
38 changed files with 699 additions and 281 deletions
12
Makefile
12
Makefile
|
|
@ -24,7 +24,17 @@ docs-check:
|
||||||
python3 scripts/gen_overview.py --category hardware
|
python3 scripts/gen_overview.py --category hardware
|
||||||
python3 scripts/gen_overview.py --category services
|
python3 scripts/gen_overview.py --category services
|
||||||
python3 scripts/gen_rack.py
|
python3 scripts/gen_rack.py
|
||||||
git diff --exit-code docs/hardware/index.md docs/services/index.md docs/infrastructure/racks/
|
@git diff --exit-code docs/hardware/index.md docs/services/index.md docs/infrastructure/racks/ \
|
||||||
|
|| { \
|
||||||
|
echo; \
|
||||||
|
echo "✗ The generated docs are out of date with the source files."; \
|
||||||
|
echo " The diff above is what 'make docs-index' just regenerated."; \
|
||||||
|
echo " This is what CI checks on push. To fix it:"; \
|
||||||
|
echo " 1. run 'make docs-index'"; \
|
||||||
|
echo " 2. commit the changed files (including the generated ones)"; \
|
||||||
|
echo " Guide: https://docs.makerfloss.eu/guides/editing-hardware-docs/"; \
|
||||||
|
exit 1; \
|
||||||
|
}
|
||||||
|
|
||||||
slides:
|
slides:
|
||||||
./build-slides.sh
|
./build-slides.sh
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ The prefix equals the `kind` field, so the name is self-describing.
|
||||||
| PDU / power strip | `pdu` | `pdu` | `pdu01` |
|
| PDU / power strip | `pdu` | `pdu` | `pdu01` |
|
||||||
| UPS | `ups` | `ups` | `ups01` |
|
| UPS | `ups` | `ups` | `ups01` |
|
||||||
| Shelf | `shelf` | `shf` | `shf01` |
|
| Shelf | `shelf` | `shf` | `shf01` |
|
||||||
|
| WAN uplink / ISP demarcation | `wan` | `wan` | `wan01` |
|
||||||
|
|
||||||
Existing enum kinds not yet in the rack reuse their natural short form when
|
Existing enum kinds not yet in the rack reuse their natural short form when
|
||||||
first used (`ap` → `ap`, `kvm` → `kvm`, `sbc` → `sbc`, `laptop` → `lt`,
|
first used (`ap` → `ap`, `kvm` → `kvm`, `sbc` → `sbc`, `laptop` → `lt`,
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ _Auto-generated from `docs/hardware/*.md` — do not edit by hand. Run `make doc
|
||||||
| [makerfloss.eu](makerfloss.eu.md) | Hetzner HEL1 (cloud) | AMD EPYC (shared vCPU) · 2c | 4 GB | 40 GB NVME | 1 GbE | in-use |
|
| [makerfloss.eu](makerfloss.eu.md) | Hetzner HEL1 (cloud) | AMD EPYC (shared vCPU) · 2c | 4 GB | 40 GB NVME | 1 GbE | in-use |
|
||||||
| [nas01](nas01.md) | The pile | ? | ? | ? | ? | staging |
|
| [nas01](nas01.md) | The pile | ? | ? | ? | ? | staging |
|
||||||
| [nas02](nas02.md) | The pile | ? | ? | ? | ? | staging |
|
| [nas02](nas02.md) | The pile | ? | ? | ? | ? | staging |
|
||||||
| [srv01](srv01.md) | The pile | ? | ? | ? | ? | staging |
|
| [srv01](srv01.md) | The pile | ? | ? | ? | ? | in-use |
|
||||||
| [srv02](srv02.md) | The pile | Intel Core i5-8500 @ 3.00GHz · 6c | 8 GB | 40 GB NVME | 1 GbE | staging |
|
| [srv02](srv02.md) | The pile | Intel Core i5-8500 @ 3.00GHz · 6c | 8 GB | 40 GB NVME | 1 GbE | staging |
|
||||||
| [srv03](srv03.md) | The pile | Intel Core i5-8500 @ 3.00GHz · 6c | 16 GB | 40 GB NVME | 1 GbE | staging |
|
| [srv03](srv03.md) | The pile | Intel Core i5-8500 @ 3.00GHz · 6c | 16 GB | 40 GB NVME | 1 GbE | staging |
|
||||||
| [srv04](srv04.md) | The pile | Intel Core i5-3570K @ 3.40GHz · 4c | 8 GB | 500 GB HDD | 1 GbE | staging |
|
| [srv04](srv04.md) | The pile | Intel Core i5-3570K @ 3.40GHz · 4c | 8 GB | 500 GB HDD | 1 GbE | staging |
|
||||||
|
|
@ -38,13 +38,30 @@ _Auto-generated from `docs/hardware/*.md` — do not edit by hand. Run `make doc
|
||||||
| Hostname | Location | CPU | RAM | Storage | NIC | Status |
|
| Hostname | Location | CPU | RAM | Storage | NIC | Status |
|
||||||
|---|---|---|---|---|---|---|
|
|---|---|---|---|---|---|---|
|
||||||
| [shf01](shf01.md) | | | | | | in-use |
|
| [shf01](shf01.md) | | | | | | in-use |
|
||||||
|
| [shf02](shf02.md) | | | | | | in-use |
|
||||||
|
| [shf03](shf03.md) | | | | | | in-use |
|
||||||
|
| [shf04](shf04.md) | | | | | | in-use |
|
||||||
|
|
||||||
## Switches
|
## Switches
|
||||||
|
|
||||||
| Hostname | Location | CPU | RAM | Storage | NIC | Status |
|
| Hostname | Location | CPU | RAM | Storage | NIC | Status |
|
||||||
|---|---|---|---|---|---|---|
|
|---|---|---|---|---|---|---|
|
||||||
| [sw01](sw01.md) | | | | | | in-use |
|
| [sw01](sw01.md) | | | | | | in-use |
|
||||||
| [sw02](sw02.md) | | | | | | in-use |
|
| [sw02](sw02.md) | | | | | | staging |
|
||||||
| [sw03](sw03.md) | | | | | | in-use |
|
| [sw03](sw03.md) | | | | | | staging |
|
||||||
| [sw04](sw04.md) | | | | | | in-use |
|
| [sw04](sw04.md) | | | | | | staging |
|
||||||
| [sw05](sw05.md) | | | | | | in-use |
|
| [sw05](sw05.md) | | | | | | staging |
|
||||||
|
|
||||||
|
## UPS
|
||||||
|
|
||||||
|
| Hostname | Location | CPU | RAM | Storage | NIC | Status |
|
||||||
|
|---|---|---|---|---|---|---|
|
||||||
|
| [ups01](ups01.md) | | | | | | staging |
|
||||||
|
| [ups02](ups02.md) | | | | | | staging |
|
||||||
|
|
||||||
|
## WAN uplinks
|
||||||
|
|
||||||
|
| Hostname | Location | CPU | RAM | Storage | NIC | Status |
|
||||||
|
|---|---|---|---|---|---|---|
|
||||||
|
| [wan01](wan01.md) | ISP demarcation | | | | | in-use |
|
||||||
|
| [wan02](wan02.md) | ISP demarcation | | | | | staging |
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,13 @@ ram_gb: "?"
|
||||||
storage: "?"
|
storage: "?"
|
||||||
nic_gbps: "?"
|
nic_gbps: "?"
|
||||||
rack: rack01
|
rack: rack01
|
||||||
mounted_on: shf01
|
rack_u: 6
|
||||||
shelf_face: front
|
u_height: 1
|
||||||
shelf_slot: 8
|
rack_face: front
|
||||||
power:
|
power:
|
||||||
- { pdu: pdu01, outlet: 1 }
|
- { pdu: pdu01, outlet: 1 }
|
||||||
- { pdu: pdu02, outlet: 1 }
|
- { pdu: pdu02, outlet: 1 }
|
||||||
links:
|
# links: cabling TBD — to be documented during network wiring
|
||||||
- { local: eth0, peer: sw01, peer_port: 1, speed_gbps: 1 }
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,13 @@ ram_gb: "?"
|
||||||
storage: "?"
|
storage: "?"
|
||||||
nic_gbps: "?"
|
nic_gbps: "?"
|
||||||
rack: rack01
|
rack: rack01
|
||||||
mounted_on: shf01
|
rack_u: 7
|
||||||
shelf_face: front
|
u_height: 1
|
||||||
shelf_slot: 9
|
rack_face: front
|
||||||
power:
|
power:
|
||||||
- { pdu: pdu01, outlet: 1 }
|
- { pdu: pdu01, outlet: 1 }
|
||||||
- { pdu: pdu02, outlet: 1 }
|
- { pdu: pdu02, outlet: 1 }
|
||||||
links:
|
# links: cabling TBD — to be documented during network wiring
|
||||||
- { local: eth0, peer: sw01, peer_port: 1, speed_gbps: 1 }
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ kind: pdu
|
||||||
status: in-use
|
status: in-use
|
||||||
rack: rack01
|
rack: rack01
|
||||||
rack_face: rear
|
rack_face: rear
|
||||||
outlets: 8
|
outlets: 9
|
||||||
rack_u: 1
|
rack_u: 1
|
||||||
u_height: 1
|
u_height: 1
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ kind: pdu
|
||||||
status: in-use
|
status: in-use
|
||||||
rack: rack01
|
rack: rack01
|
||||||
rack_face: rear
|
rack_face: rear
|
||||||
outlets: 8
|
outlets: 5
|
||||||
rack_u: 12
|
rack_u: 12
|
||||||
u_height: 1
|
u_height: 1
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ kind: pdu
|
||||||
status: in-use
|
status: in-use
|
||||||
rack: rack01
|
rack: rack01
|
||||||
rack_face: rear
|
rack_face: rear
|
||||||
outlets: 12
|
outlets: 11
|
||||||
rack_u: 33
|
rack_u: 34
|
||||||
u_height: 1
|
u_height: 1
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ status: in-use
|
||||||
rack: rack01
|
rack: rack01
|
||||||
rack_face: front
|
rack_face: front
|
||||||
outlets: 5
|
outlets: 5
|
||||||
rack_u: 11
|
rack_u: 12
|
||||||
u_height: 1
|
u_height: 1
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,18 @@ hostname: pp01
|
||||||
kind: patch-panel
|
kind: patch-panel
|
||||||
status: in-use
|
status: in-use
|
||||||
rack: rack01
|
rack: rack01
|
||||||
rack_u: 25
|
rack_u: 24
|
||||||
u_height: 1
|
u_height: 1
|
||||||
rack_face: front
|
rack_face: front
|
||||||
ports: 16
|
ports: 9
|
||||||
links:
|
links:
|
||||||
- { local: uplink, peer: sw01, peer_port: 24, speed_gbps: 1 }
|
- { local: "1", peer: wan01, peer_port: 1 }
|
||||||
---
|
---
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
- Link are placeholder values
|
- Port 1 → wan01 (WAN line 1, active). Fed from pp02:1 (srv01 eth0).
|
||||||
|
- Port 2 → wan02 (WAN line 2), set up but non-active.
|
||||||
|
- Port 3 → working table (white cable), non-active.
|
||||||
|
- Port 4 ← sw01:8 (switch management), patched out to the working table
|
||||||
|
(black cable), non-active.
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,24 @@ hostname: pp02
|
||||||
kind: patch-panel
|
kind: patch-panel
|
||||||
status: in-use
|
status: in-use
|
||||||
rack: rack01
|
rack: rack01
|
||||||
rack_u: 26
|
rack_u: 25
|
||||||
u_height: 1
|
u_height: 1
|
||||||
rack_face: front
|
rack_face: front
|
||||||
|
ports: 24
|
||||||
links:
|
links:
|
||||||
- { local: uplink, peer: sw01, peer_port: 24, speed_gbps: 1 }
|
- { local: "1", peer: pp01, peer_port: 1 }
|
||||||
|
- { local: "2", peer: sw01, peer_port: 1 }
|
||||||
|
- { local: "3", peer: sw01, peer_port: 2 }
|
||||||
|
- { local: "4", peer: sw01, peer_port: 3 }
|
||||||
|
- { local: "5", peer: sw01, peer_port: 4 }
|
||||||
|
- { local: "6", peer: sw01, peer_port: 5 }
|
||||||
|
- { local: "7", peer: sw01, peer_port: 6 }
|
||||||
|
- { local: "8", peer: sw01, peer_port: 7 }
|
||||||
---
|
---
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
- Reconstructed from committed rack artifacts; placeholder values.
|
- 24-port patch panel; ports 1–8 are the live feeds.
|
||||||
|
- Port 1 → pp01:1 → wan01 (srv01 eth0, WAN).
|
||||||
|
- Ports 2–8 → sw01:1–7 (LAN): srv01 eth1 (p2), srv02 (p3), srv03 (p4),
|
||||||
|
srv04 (p5), srv05 (p6), srv06 (p7), srv07 (p8).
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,15 @@ hostname: shf01
|
||||||
kind: shelf
|
kind: shelf
|
||||||
status: in-use
|
status: in-use
|
||||||
rack: rack01
|
rack: rack01
|
||||||
rack_u: 37
|
rack_u: 46
|
||||||
u_height: 10
|
u_height: 1
|
||||||
rack_face: both
|
rack_face: both
|
||||||
cluster: tappaas
|
cluster: tappaas
|
||||||
---
|
---
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
- Provisional placeholder shelf holding the TaPPaaS nodes (srv01/srv02 front, srv03 rear).
|
- 1U full-depth tray at U46. Tower PCs stand on it and rise above U46; they are
|
||||||
|
not rail-mounted, so the U's above are not consumed in the rack model.
|
||||||
|
- Front: srv01 (stands ~U37–U46), srv02 (~U39–U46).
|
||||||
|
- Rear: srv03 (~U40–U46).
|
||||||
|
|
|
||||||
17
docs/hardware/shf02.md
Normal file
17
docs/hardware/shf02.md
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
---
|
||||||
|
hostname: shf02
|
||||||
|
kind: shelf
|
||||||
|
status: in-use
|
||||||
|
rack: rack01
|
||||||
|
rack_u: 35
|
||||||
|
u_height: 1
|
||||||
|
rack_face: both
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- 1U full-depth tray at U35. Tower PCs stand on it and rise above U35; they are
|
||||||
|
not rail-mounted, so the U's above are not consumed in the rack model
|
||||||
|
(e.g. pdu03 sits at U34, just above this shelf).
|
||||||
|
- Front: srv07 (stands ~U29–U35), srv04 (~U27–U35).
|
||||||
|
- Rear: srv05 (~U27–U35), srv06 (~U27–U35).
|
||||||
14
docs/hardware/shf03.md
Normal file
14
docs/hardware/shf03.md
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
hostname: shf03
|
||||||
|
kind: shelf
|
||||||
|
status: in-use
|
||||||
|
rack: rack01
|
||||||
|
rack_u: 21
|
||||||
|
u_height: 1
|
||||||
|
rack_face: front
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Half-depth shelf at U21 (front), currently empty.
|
||||||
|
- Paired with shf04 (rear half-depth at the same U).
|
||||||
14
docs/hardware/shf04.md
Normal file
14
docs/hardware/shf04.md
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
hostname: shf04
|
||||||
|
kind: shelf
|
||||||
|
status: in-use
|
||||||
|
rack: rack01
|
||||||
|
rack_u: 21
|
||||||
|
u_height: 1
|
||||||
|
rack_face: rear
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Half-depth shelf at U21 (rear), currently empty.
|
||||||
|
- Paired with shf03 (front half-depth at the same U).
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
hostname: srv01
|
hostname: srv01
|
||||||
kind: server
|
kind: server
|
||||||
status: staging
|
status: in-use
|
||||||
cluster: tappaas
|
cluster: tappaas
|
||||||
location: The pile
|
location: The pile
|
||||||
cpu: "?"
|
cpu: "?"
|
||||||
|
|
@ -16,9 +16,9 @@ shelf_face: front
|
||||||
shelf_slot: 1
|
shelf_slot: 1
|
||||||
power:
|
power:
|
||||||
- { pdu: pdu01, outlet: 1 }
|
- { pdu: pdu01, outlet: 1 }
|
||||||
- { pdu: pdu02, outlet: 1 }
|
|
||||||
links:
|
links:
|
||||||
- { local: eth0, peer: sw01, peer_port: 1, speed_gbps: 1 }
|
- { local: eth0, peer: pp02, peer_port: 1, speed_gbps: 1 }
|
||||||
|
- { local: eth1, peer: pp02, peer_port: 2, speed_gbps: 1 }
|
||||||
---
|
---
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ shelf_slot: 2
|
||||||
power:
|
power:
|
||||||
- { pdu: pdu01, outlet: 2 }
|
- { pdu: pdu01, outlet: 2 }
|
||||||
links:
|
links:
|
||||||
- { local: eth0, peer: pp01, peer_port: 1, speed_gbps: 1 }
|
- { local: eth0, peer: pp02, peer_port: 3, speed_gbps: 1 }
|
||||||
---
|
---
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ shelf_slot: 1
|
||||||
power:
|
power:
|
||||||
- { pdu: pdu01, outlet: 3 }
|
- { pdu: pdu01, outlet: 3 }
|
||||||
links:
|
links:
|
||||||
- { local: eth0, peer: pp01, peer_port: 2, speed_gbps: 1 }
|
- { local: eth0, peer: pp02, peer_port: 4, speed_gbps: 1 }
|
||||||
---
|
---
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,13 @@ storage_gb: 500
|
||||||
storage_type: hdd
|
storage_type: hdd
|
||||||
nic_gbps: 1
|
nic_gbps: 1
|
||||||
rack: rack01
|
rack: rack01
|
||||||
rack_u: 5
|
mounted_on: shf02
|
||||||
u_height: 2
|
shelf_face: front
|
||||||
rack_face: front
|
shelf_slot: 2
|
||||||
power:
|
power:
|
||||||
- { pdu: pdu01, outlet: 4 }
|
- { pdu: pdu01, outlet: 4 }
|
||||||
links:
|
links:
|
||||||
- { local: eth0, peer: pp01, peer_port: 3, speed_gbps: 1 }
|
- { local: eth0, peer: pp02, peer_port: 5, speed_gbps: 1 }
|
||||||
---
|
---
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,13 @@ storage_gb: 500
|
||||||
storage_type: hdd
|
storage_type: hdd
|
||||||
nic_gbps: 1
|
nic_gbps: 1
|
||||||
rack: rack01
|
rack: rack01
|
||||||
rack_u: 5
|
mounted_on: shf02
|
||||||
u_height: 2
|
shelf_face: rear
|
||||||
rack_face: rear
|
shelf_slot: 1
|
||||||
power:
|
power:
|
||||||
- { pdu: pdu01, outlet: 5 }
|
- { pdu: pdu01, outlet: 5 }
|
||||||
links:
|
links:
|
||||||
- { local: eth0, peer: pp01, peer_port: 4, speed_gbps: 1 }
|
- { local: eth0, peer: pp02, peer_port: 6, speed_gbps: 1 }
|
||||||
---
|
---
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,14 @@ ram_gb: "?"
|
||||||
storage: "?"
|
storage: "?"
|
||||||
nic_gbps: "?"
|
nic_gbps: "?"
|
||||||
rack: rack01
|
rack: rack01
|
||||||
mounted_on: shf01
|
mounted_on: shf02
|
||||||
shelf_face: front
|
shelf_face: rear
|
||||||
shelf_slot: 6
|
shelf_slot: 2
|
||||||
power:
|
power:
|
||||||
- { pdu: pdu01, outlet: 1 }
|
- { pdu: pdu01, outlet: 1 }
|
||||||
- { pdu: pdu02, outlet: 1 }
|
- { pdu: pdu02, outlet: 1 }
|
||||||
links:
|
links:
|
||||||
- { local: eth0, peer: sw01, peer_port: 1, speed_gbps: 1 }
|
- { local: eth0, peer: pp02, peer_port: 7, speed_gbps: 1 }
|
||||||
---
|
---
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,14 @@ ram_gb: "?"
|
||||||
storage: "?"
|
storage: "?"
|
||||||
nic_gbps: "?"
|
nic_gbps: "?"
|
||||||
rack: rack01
|
rack: rack01
|
||||||
mounted_on: shf01
|
mounted_on: shf02
|
||||||
shelf_face: front
|
shelf_face: front
|
||||||
shelf_slot: 7
|
shelf_slot: 1
|
||||||
power:
|
power:
|
||||||
- { pdu: pdu01, outlet: 1 }
|
- { pdu: pdu01, outlet: 1 }
|
||||||
- { pdu: pdu02, outlet: 1 }
|
- { pdu: pdu02, outlet: 1 }
|
||||||
links:
|
links:
|
||||||
- { local: eth0, peer: sw01, peer_port: 1, speed_gbps: 1 }
|
- { local: eth0, peer: pp02, peer_port: 8, speed_gbps: 1 }
|
||||||
---
|
---
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,15 @@ hostname: sw01
|
||||||
kind: switch
|
kind: switch
|
||||||
status: in-use
|
status: in-use
|
||||||
rack: rack01
|
rack: rack01
|
||||||
rack_u: 8
|
rack_u: 23
|
||||||
u_height: 1
|
u_height: 1
|
||||||
rack_face: front
|
rack_face: front
|
||||||
ports: 32
|
ports: 10
|
||||||
---
|
---
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
- Provisional placeholder switch. Port assignments are not yet real.
|
- 10 ports: p1–p8 are 1 GbE; sfp1–sfp2 are 2.5 GbE SFP+ (unused today).
|
||||||
|
- p1–p7 carry server uplinks via pp02 (pp02:2–8 → sw01:1–7).
|
||||||
|
- p8 is the management port, patched out via pp01:4 to the working table
|
||||||
|
(black cable) — non-active.
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
hostname: sw02
|
hostname: sw02
|
||||||
kind: switch
|
kind: switch
|
||||||
status: in-use
|
status: staging
|
||||||
rack: rack01
|
rack: rack01
|
||||||
rack_u: 9
|
rack_u: 9
|
||||||
u_height: 1
|
u_height: 1
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
hostname: sw03
|
hostname: sw03
|
||||||
kind: switch
|
kind: switch
|
||||||
status: in-use
|
status: staging
|
||||||
rack: rack01
|
rack: rack01
|
||||||
rack_u: 10
|
rack_u: 10
|
||||||
u_height: 1
|
u_height: 1
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
---
|
---
|
||||||
hostname: sw04
|
hostname: sw04
|
||||||
kind: switch
|
kind: switch
|
||||||
status: in-use
|
status: staging
|
||||||
rack: rack01
|
rack: rack01
|
||||||
rack_u: 32
|
rack_u: 5
|
||||||
u_height: 1
|
u_height: 1
|
||||||
rack_face: front
|
rack_face: front
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
---
|
---
|
||||||
hostname: sw05
|
hostname: sw05
|
||||||
kind: switch
|
kind: switch
|
||||||
status: in-use
|
status: staging
|
||||||
rack: rack01
|
rack: rack01
|
||||||
rack_u: 36
|
rack_u: 8
|
||||||
u_height: 1
|
u_height: 1
|
||||||
rack_face: front
|
rack_face: front
|
||||||
---
|
---
|
||||||
|
|
|
||||||
13
docs/hardware/ups01.md
Normal file
13
docs/hardware/ups01.md
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
---
|
||||||
|
hostname: ups01
|
||||||
|
kind: ups
|
||||||
|
status: staging
|
||||||
|
rack: rack01
|
||||||
|
rack_u: 4
|
||||||
|
u_height: 1
|
||||||
|
rack_face: front
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
-
|
||||||
13
docs/hardware/ups02.md
Normal file
13
docs/hardware/ups02.md
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
---
|
||||||
|
hostname: ups02
|
||||||
|
kind: ups
|
||||||
|
status: staging
|
||||||
|
rack: rack01
|
||||||
|
rack_u: 3
|
||||||
|
u_height: 1
|
||||||
|
rack_face: front
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
-
|
||||||
19
docs/hardware/wan01.md
Normal file
19
docs/hardware/wan01.md
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
---
|
||||||
|
hostname: wan01
|
||||||
|
kind: wan
|
||||||
|
status: in-use
|
||||||
|
location: ISP demarcation
|
||||||
|
ports: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- External WAN uplink — the upstream/ISP side of the WAN cable, where the
|
||||||
|
MakerFLOSS network meets the provider.
|
||||||
|
- Not racked (no `rack:`), like the cloud-FQDN exception in the naming scheme.
|
||||||
|
It exists so the WAN cable has a real peer to terminate on.
|
||||||
|
- Path into the rack: `wan01:1 ← pp01:1 ← pp02:1 ← srv01 eth0`.
|
||||||
|
|
||||||
|
## ToDo
|
||||||
|
|
||||||
|
- Confirm provider / circuit details for this handoff.
|
||||||
13
docs/hardware/wan02.md
Normal file
13
docs/hardware/wan02.md
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
---
|
||||||
|
hostname: wan02
|
||||||
|
kind: wan
|
||||||
|
status: staging
|
||||||
|
location: ISP demarcation
|
||||||
|
ports: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Second WAN uplink line ("wan 2"), set up but not yet active.
|
||||||
|
- Patched from pp01:2 (non-active), so it does not yet appear in the live
|
||||||
|
network diagram.
|
||||||
|
|
@ -202,107 +202,135 @@
|
||||||
<rect x="333" y="41" width="238" height="18" rx="3" fill="#e15759" stroke="#333333" stroke-width="1.5"/>
|
<rect x="333" y="41" width="238" height="18" rx="3" fill="#e15759" stroke="#333333" stroke-width="1.5"/>
|
||||||
<text x="452" y="54" text-anchor="middle" fill="#ffffff">pdu01 (U1)</text>
|
<text x="452" y="54" text-anchor="middle" fill="#ffffff">pdu01 (U1)</text>
|
||||||
</a>
|
</a>
|
||||||
<a href="/hardware/srv04/">
|
<a href="/hardware/ups02/">
|
||||||
<title>srv04 · server · staging · cluster: — · U5–U6</title>
|
<title>ups02 · ups · staging · cluster: — · U3</title>
|
||||||
<rect x="43" y="121" width="238" height="38" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
<rect x="43" y="81" width="238" height="18" rx="3" fill="#edc948" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
<text x="162" y="144" text-anchor="middle" fill="#ffffff">srv04 (U5–U6)</text>
|
<text x="162" y="94" text-anchor="middle" fill="#ffffff">ups02 (U3)</text>
|
||||||
</a>
|
</a>
|
||||||
<a href="/hardware/srv05/">
|
<a href="/hardware/ups01/">
|
||||||
<title>srv05 · server · staging · cluster: — · U5–U6</title>
|
<title>ups01 · ups · staging · cluster: — · U4</title>
|
||||||
<rect x="333" y="121" width="238" height="38" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
<rect x="43" y="101" width="238" height="18" rx="3" fill="#edc948" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
<text x="452" y="144" text-anchor="middle" fill="#ffffff">srv05 (U5–U6)</text>
|
<text x="162" y="114" text-anchor="middle" fill="#ffffff">ups01 (U4)</text>
|
||||||
</a>
|
</a>
|
||||||
<a href="/hardware/sw01/">
|
<a href="/hardware/sw04/">
|
||||||
<title>sw01 · switch · in-use · cluster: — · U8</title>
|
<title>sw04 · switch · staging · cluster: — · U5</title>
|
||||||
<rect x="43" y="181" width="238" height="18" rx="3" fill="#59a14f" stroke="#333333" stroke-width="1.5"/>
|
<rect x="43" y="121" width="238" height="18" rx="3" fill="#59a14f" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
<text x="162" y="194" text-anchor="middle" fill="#ffffff">sw01 (U8)</text>
|
<text x="162" y="134" text-anchor="middle" fill="#ffffff">sw04 (U5)</text>
|
||||||
|
</a>
|
||||||
|
<a href="/hardware/nas01/">
|
||||||
|
<title>nas01 · server · staging · cluster: tappaas · U6</title>
|
||||||
|
<rect x="43" y="141" width="238" height="18" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
|
<text x="162" y="154" text-anchor="middle" fill="#ffffff">nas01 (U6)</text>
|
||||||
|
</a>
|
||||||
|
<a href="/hardware/nas02/">
|
||||||
|
<title>nas02 · server · staging · cluster: tappaas · U7</title>
|
||||||
|
<rect x="43" y="161" width="238" height="18" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
|
<text x="162" y="174" text-anchor="middle" fill="#ffffff">nas02 (U7)</text>
|
||||||
|
</a>
|
||||||
|
<a href="/hardware/sw05/">
|
||||||
|
<title>sw05 · switch · staging · cluster: — · U8</title>
|
||||||
|
<rect x="43" y="181" width="238" height="18" rx="3" fill="#59a14f" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
|
<text x="162" y="194" text-anchor="middle" fill="#ffffff">sw05 (U8)</text>
|
||||||
</a>
|
</a>
|
||||||
<a href="/hardware/sw02/">
|
<a href="/hardware/sw02/">
|
||||||
<title>sw02 · switch · in-use · cluster: — · U9</title>
|
<title>sw02 · switch · staging · cluster: — · U9</title>
|
||||||
<rect x="43" y="201" width="238" height="18" rx="3" fill="#59a14f" stroke="#333333" stroke-width="1.5"/>
|
<rect x="43" y="201" width="238" height="18" rx="3" fill="#59a14f" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
<text x="162" y="214" text-anchor="middle" fill="#ffffff">sw02 (U9)</text>
|
<text x="162" y="214" text-anchor="middle" fill="#ffffff">sw02 (U9)</text>
|
||||||
</a>
|
</a>
|
||||||
<a href="/hardware/sw03/">
|
<a href="/hardware/sw03/">
|
||||||
<title>sw03 · switch · in-use · cluster: — · U10</title>
|
<title>sw03 · switch · staging · cluster: — · U10</title>
|
||||||
<rect x="43" y="221" width="238" height="18" rx="3" fill="#59a14f" stroke="#333333" stroke-width="1.5"/>
|
<rect x="43" y="221" width="238" height="18" rx="3" fill="#59a14f" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
<text x="162" y="234" text-anchor="middle" fill="#ffffff">sw03 (U10)</text>
|
<text x="162" y="234" text-anchor="middle" fill="#ffffff">sw03 (U10)</text>
|
||||||
</a>
|
</a>
|
||||||
<a href="/hardware/pdu04/">
|
|
||||||
<title>pdu04 · pdu · in-use · cluster: — · U11</title>
|
|
||||||
<rect x="43" y="241" width="238" height="18" rx="3" fill="#e15759" stroke="#333333" stroke-width="1.5"/>
|
|
||||||
<text x="162" y="254" text-anchor="middle" fill="#ffffff">pdu04 (U11)</text>
|
|
||||||
</a>
|
|
||||||
<a href="/hardware/pdu02/">
|
<a href="/hardware/pdu02/">
|
||||||
<title>pdu02 · pdu · in-use · cluster: — · U12</title>
|
<title>pdu02 · pdu · in-use · cluster: — · U12</title>
|
||||||
<rect x="333" y="261" width="238" height="18" rx="3" fill="#e15759" stroke="#333333" stroke-width="1.5"/>
|
<rect x="333" y="261" width="238" height="18" rx="3" fill="#e15759" stroke="#333333" stroke-width="1.5"/>
|
||||||
<text x="452" y="274" text-anchor="middle" fill="#ffffff">pdu02 (U12)</text>
|
<text x="452" y="274" text-anchor="middle" fill="#ffffff">pdu02 (U12)</text>
|
||||||
</a>
|
</a>
|
||||||
|
<a href="/hardware/pdu04/">
|
||||||
|
<title>pdu04 · pdu · in-use · cluster: — · U12</title>
|
||||||
|
<rect x="43" y="261" width="238" height="18" rx="3" fill="#e15759" stroke="#333333" stroke-width="1.5"/>
|
||||||
|
<text x="162" y="274" text-anchor="middle" fill="#ffffff">pdu04 (U12)</text>
|
||||||
|
</a>
|
||||||
|
<a href="/hardware/sw01/">
|
||||||
|
<title>sw01 · switch · in-use · cluster: — · U23</title>
|
||||||
|
<rect x="43" y="481" width="238" height="18" rx="3" fill="#59a14f" stroke="#333333" stroke-width="1.5"/>
|
||||||
|
<text x="162" y="494" text-anchor="middle" fill="#ffffff">sw01 (U23)</text>
|
||||||
|
</a>
|
||||||
<a href="/hardware/pp01/">
|
<a href="/hardware/pp01/">
|
||||||
<title>pp01 · patch-panel · in-use · cluster: — · U25</title>
|
<title>pp01 · patch-panel · in-use · cluster: — · U24</title>
|
||||||
<rect x="43" y="521" width="238" height="18" rx="3" fill="#9c755f" stroke="#333333" stroke-width="1.5"/>
|
<rect x="43" y="501" width="238" height="18" rx="3" fill="#9c755f" stroke="#333333" stroke-width="1.5"/>
|
||||||
<text x="162" y="534" text-anchor="middle" fill="#ffffff">pp01 (U25)</text>
|
<text x="162" y="514" text-anchor="middle" fill="#ffffff">pp01 (U24)</text>
|
||||||
</a>
|
</a>
|
||||||
<a href="/hardware/pp02/">
|
<a href="/hardware/pp02/">
|
||||||
<title>pp02 · patch-panel · in-use · cluster: — · U26</title>
|
<title>pp02 · patch-panel · in-use · cluster: — · U25</title>
|
||||||
<rect x="43" y="541" width="238" height="18" rx="3" fill="#9c755f" stroke="#333333" stroke-width="1.5"/>
|
<rect x="43" y="521" width="238" height="18" rx="3" fill="#9c755f" stroke="#333333" stroke-width="1.5"/>
|
||||||
<text x="162" y="554" text-anchor="middle" fill="#ffffff">pp02 (U26)</text>
|
<text x="162" y="534" text-anchor="middle" fill="#ffffff">pp02 (U25)</text>
|
||||||
</a>
|
|
||||||
<a href="/hardware/sw04/">
|
|
||||||
<title>sw04 · switch · in-use · cluster: — · U32</title>
|
|
||||||
<rect x="43" y="661" width="238" height="18" rx="3" fill="#59a14f" stroke="#333333" stroke-width="1.5"/>
|
|
||||||
<text x="162" y="674" text-anchor="middle" fill="#ffffff">sw04 (U32)</text>
|
|
||||||
</a>
|
</a>
|
||||||
<a href="/hardware/pdu03/">
|
<a href="/hardware/pdu03/">
|
||||||
<title>pdu03 · pdu · in-use · cluster: — · U33</title>
|
<title>pdu03 · pdu · in-use · cluster: — · U34</title>
|
||||||
<rect x="333" y="681" width="238" height="18" rx="3" fill="#e15759" stroke="#333333" stroke-width="1.5"/>
|
<rect x="333" y="701" width="238" height="18" rx="3" fill="#e15759" stroke="#333333" stroke-width="1.5"/>
|
||||||
<text x="452" y="694" text-anchor="middle" fill="#ffffff">pdu03 (U33)</text>
|
<text x="452" y="714" text-anchor="middle" fill="#ffffff">pdu03 (U34)</text>
|
||||||
</a>
|
|
||||||
<a href="/hardware/sw05/">
|
|
||||||
<title>sw05 · switch · in-use · cluster: — · U36</title>
|
|
||||||
<rect x="43" y="741" width="238" height="18" rx="3" fill="#59a14f" stroke="#333333" stroke-width="1.5"/>
|
|
||||||
<text x="162" y="754" text-anchor="middle" fill="#ffffff">sw05 (U36)</text>
|
|
||||||
</a>
|
</a>
|
||||||
<a href="/hardware/srv01/">
|
<a href="/hardware/srv01/">
|
||||||
<title>srv01 · server · staging · cluster: tappaas · shf01/front/slot 1</title>
|
<title>srv01 · server · in-use · cluster: tappaas · shf01/front/slot 1</title>
|
||||||
<rect x="43" y="761" width="38" height="192" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
<rect x="43" y="941" width="118" height="12" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5"/>
|
||||||
<text x="62" y="861" text-anchor="middle" fill="#ffffff">srv01</text>
|
<text x="102" y="951" text-anchor="middle" fill="#ffffff">srv01</text>
|
||||||
</a>
|
</a>
|
||||||
<a href="/hardware/srv02/">
|
<a href="/hardware/srv02/">
|
||||||
<title>srv02 · server · staging · cluster: tappaas · shf01/front/slot 2</title>
|
<title>srv02 · server · staging · cluster: tappaas · shf01/front/slot 2</title>
|
||||||
<rect x="83" y="761" width="38" height="192" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
<rect x="163" y="941" width="118" height="12" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
<text x="102" y="861" text-anchor="middle" fill="#ffffff">srv02</text>
|
<text x="222" y="951" text-anchor="middle" fill="#ffffff">srv02</text>
|
||||||
</a>
|
|
||||||
<a href="/hardware/srv06/">
|
|
||||||
<title>srv06 · server · staging · cluster: tappaas · shf01/front/slot 6</title>
|
|
||||||
<rect x="123" y="761" width="38" height="192" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
|
||||||
<text x="142" y="861" text-anchor="middle" fill="#ffffff">srv06</text>
|
|
||||||
</a>
|
|
||||||
<a href="/hardware/srv07/">
|
|
||||||
<title>srv07 · server · staging · cluster: tappaas · shf01/front/slot 7</title>
|
|
||||||
<rect x="163" y="761" width="38" height="192" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
|
||||||
<text x="182" y="861" text-anchor="middle" fill="#ffffff">srv07</text>
|
|
||||||
</a>
|
|
||||||
<a href="/hardware/nas01/">
|
|
||||||
<title>nas01 · server · staging · cluster: tappaas · shf01/front/slot 8</title>
|
|
||||||
<rect x="203" y="761" width="38" height="192" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
|
||||||
<text x="222" y="861" text-anchor="middle" fill="#ffffff">nas01</text>
|
|
||||||
</a>
|
|
||||||
<a href="/hardware/nas02/">
|
|
||||||
<title>nas02 · server · staging · cluster: tappaas · shf01/front/slot 9</title>
|
|
||||||
<rect x="243" y="761" width="38" height="192" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
|
||||||
<text x="262" y="861" text-anchor="middle" fill="#ffffff">nas02</text>
|
|
||||||
</a>
|
</a>
|
||||||
<a href="/hardware/srv03/">
|
<a href="/hardware/srv03/">
|
||||||
<title>srv03 · server · staging · cluster: tappaas · shf01/rear/slot 1</title>
|
<title>srv03 · server · staging · cluster: tappaas · shf01/rear/slot 1</title>
|
||||||
<rect x="333" y="761" width="238" height="192" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
<rect x="333" y="941" width="238" height="12" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
<text x="452" y="861" text-anchor="middle" fill="#ffffff">srv03</text>
|
<text x="452" y="951" text-anchor="middle" fill="#ffffff">srv03</text>
|
||||||
</a>
|
</a>
|
||||||
<a href="/hardware/shf01/">
|
<a href="/hardware/shf01/">
|
||||||
<title>shf01 · shelf · in-use · cluster: tappaas · U37–U46</title>
|
<title>shf01 · shelf · in-use · cluster: tappaas · U46</title>
|
||||||
<rect x="42" y="954" width="240" height="6" fill="#bab0ac" stroke="#333"/>
|
<rect x="42" y="954" width="240" height="6" fill="#bab0ac" stroke="#333"/>
|
||||||
<rect x="332" y="954" width="240" height="6" fill="#bab0ac" stroke="#333"/>
|
<rect x="332" y="954" width="240" height="6" fill="#bab0ac" stroke="#333"/>
|
||||||
<text x="162" y="959" text-anchor="middle" fill="#333" font-size="9">shf01</text>
|
<text x="162" y="959" text-anchor="middle" fill="#333" font-size="9">shf01</text>
|
||||||
</a>
|
</a>
|
||||||
|
<a href="/hardware/srv07/">
|
||||||
|
<title>srv07 · server · staging · cluster: tappaas · shf02/front/slot 1</title>
|
||||||
|
<rect x="43" y="721" width="118" height="12" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
|
<text x="102" y="731" text-anchor="middle" fill="#ffffff">srv07</text>
|
||||||
|
</a>
|
||||||
|
<a href="/hardware/srv04/">
|
||||||
|
<title>srv04 · server · staging · cluster: — · shf02/front/slot 2</title>
|
||||||
|
<rect x="163" y="721" width="118" height="12" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
|
<text x="222" y="731" text-anchor="middle" fill="#ffffff">srv04</text>
|
||||||
|
</a>
|
||||||
|
<a href="/hardware/srv05/">
|
||||||
|
<title>srv05 · server · staging · cluster: — · shf02/rear/slot 1</title>
|
||||||
|
<rect x="333" y="721" width="118" height="12" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
|
<text x="392" y="731" text-anchor="middle" fill="#ffffff">srv05</text>
|
||||||
|
</a>
|
||||||
|
<a href="/hardware/srv06/">
|
||||||
|
<title>srv06 · server · staging · cluster: tappaas · shf02/rear/slot 2</title>
|
||||||
|
<rect x="453" y="721" width="118" height="12" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
|
<text x="512" y="731" text-anchor="middle" fill="#ffffff">srv06</text>
|
||||||
|
</a>
|
||||||
|
<a href="/hardware/shf02/">
|
||||||
|
<title>shf02 · shelf · in-use · cluster: — · U35</title>
|
||||||
|
<rect x="42" y="734" width="240" height="6" fill="#bab0ac" stroke="#333"/>
|
||||||
|
<rect x="332" y="734" width="240" height="6" fill="#bab0ac" stroke="#333"/>
|
||||||
|
<text x="162" y="739" text-anchor="middle" fill="#333" font-size="9">shf02</text>
|
||||||
|
</a>
|
||||||
|
<a href="/hardware/shf03/">
|
||||||
|
<title>shf03 · shelf · in-use · cluster: — · U21</title>
|
||||||
|
<rect x="42" y="454" width="240" height="6" fill="#bab0ac" stroke="#333"/>
|
||||||
|
<rect x="332" y="454" width="240" height="6" fill="#bab0ac" stroke="#333"/>
|
||||||
|
<text x="162" y="459" text-anchor="middle" fill="#333" font-size="9">shf03</text>
|
||||||
|
</a>
|
||||||
|
<a href="/hardware/shf04/">
|
||||||
|
<title>shf04 · shelf · in-use · cluster: — · U21</title>
|
||||||
|
<rect x="42" y="454" width="240" height="6" fill="#bab0ac" stroke="#333"/>
|
||||||
|
<rect x="332" y="454" width="240" height="6" fill="#bab0ac" stroke="#333"/>
|
||||||
|
<text x="162" y="459" text-anchor="middle" fill="#333" font-size="9">shf04</text>
|
||||||
|
</a>
|
||||||
<text x="42" y="1020" font-weight="bold">Legend</text>
|
<text x="42" y="1020" font-weight="bold">Legend</text>
|
||||||
<rect x="42" y="1028" width="12" height="12" fill="#9c755f" stroke="#333"/>
|
<rect x="42" y="1028" width="12" height="12" fill="#9c755f" stroke="#333"/>
|
||||||
<text x="58" y="1038">patch-panel</text>
|
<text x="58" y="1038">patch-panel</text>
|
||||||
|
|
@ -314,6 +342,8 @@
|
||||||
<text x="282" y="1038">shelf</text>
|
<text x="282" y="1038">shelf</text>
|
||||||
<rect x="329" y="1028" width="12" height="12" fill="#59a14f" stroke="#333"/>
|
<rect x="329" y="1028" width="12" height="12" fill="#59a14f" stroke="#333"/>
|
||||||
<text x="345" y="1038">switch</text>
|
<text x="345" y="1038">switch</text>
|
||||||
|
<rect x="399" y="1028" width="12" height="12" fill="#edc948" stroke="#333"/>
|
||||||
|
<text x="415" y="1038">ups</text>
|
||||||
<rect x="42" y="1046" width="12" height="12" fill="#ffffff" stroke="#333333" stroke-width="1.5"/>
|
<rect x="42" y="1046" width="12" height="12" fill="#ffffff" stroke="#333333" stroke-width="1.5"/>
|
||||||
<text x="58" y="1056">in-use</text>
|
<text x="58" y="1056">in-use</text>
|
||||||
<rect x="112" y="1046" width="12" height="12" fill="#ffffff" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
<rect x="112" y="1046" width="12" height="12" fill="#ffffff" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 23 KiB |
|
|
@ -209,107 +209,135 @@ _Auto-generated from `docs/hardware/*.md` (items with `rack: rack01`) — do not
|
||||||
<rect x="333" y="41" width="238" height="18" rx="3" fill="#e15759" stroke="#333333" stroke-width="1.5"/>
|
<rect x="333" y="41" width="238" height="18" rx="3" fill="#e15759" stroke="#333333" stroke-width="1.5"/>
|
||||||
<text x="452" y="54" text-anchor="middle" fill="#ffffff">pdu01 (U1)</text>
|
<text x="452" y="54" text-anchor="middle" fill="#ffffff">pdu01 (U1)</text>
|
||||||
</a>
|
</a>
|
||||||
<a href="/hardware/srv04/">
|
<a href="/hardware/ups02/">
|
||||||
<title>srv04 · server · staging · cluster: — · U5–U6</title>
|
<title>ups02 · ups · staging · cluster: — · U3</title>
|
||||||
<rect x="43" y="121" width="238" height="38" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
<rect x="43" y="81" width="238" height="18" rx="3" fill="#edc948" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
<text x="162" y="144" text-anchor="middle" fill="#ffffff">srv04 (U5–U6)</text>
|
<text x="162" y="94" text-anchor="middle" fill="#ffffff">ups02 (U3)</text>
|
||||||
</a>
|
</a>
|
||||||
<a href="/hardware/srv05/">
|
<a href="/hardware/ups01/">
|
||||||
<title>srv05 · server · staging · cluster: — · U5–U6</title>
|
<title>ups01 · ups · staging · cluster: — · U4</title>
|
||||||
<rect x="333" y="121" width="238" height="38" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
<rect x="43" y="101" width="238" height="18" rx="3" fill="#edc948" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
<text x="452" y="144" text-anchor="middle" fill="#ffffff">srv05 (U5–U6)</text>
|
<text x="162" y="114" text-anchor="middle" fill="#ffffff">ups01 (U4)</text>
|
||||||
</a>
|
</a>
|
||||||
<a href="/hardware/sw01/">
|
<a href="/hardware/sw04/">
|
||||||
<title>sw01 · switch · in-use · cluster: — · U8</title>
|
<title>sw04 · switch · staging · cluster: — · U5</title>
|
||||||
<rect x="43" y="181" width="238" height="18" rx="3" fill="#59a14f" stroke="#333333" stroke-width="1.5"/>
|
<rect x="43" y="121" width="238" height="18" rx="3" fill="#59a14f" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
<text x="162" y="194" text-anchor="middle" fill="#ffffff">sw01 (U8)</text>
|
<text x="162" y="134" text-anchor="middle" fill="#ffffff">sw04 (U5)</text>
|
||||||
|
</a>
|
||||||
|
<a href="/hardware/nas01/">
|
||||||
|
<title>nas01 · server · staging · cluster: tappaas · U6</title>
|
||||||
|
<rect x="43" y="141" width="238" height="18" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
|
<text x="162" y="154" text-anchor="middle" fill="#ffffff">nas01 (U6)</text>
|
||||||
|
</a>
|
||||||
|
<a href="/hardware/nas02/">
|
||||||
|
<title>nas02 · server · staging · cluster: tappaas · U7</title>
|
||||||
|
<rect x="43" y="161" width="238" height="18" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
|
<text x="162" y="174" text-anchor="middle" fill="#ffffff">nas02 (U7)</text>
|
||||||
|
</a>
|
||||||
|
<a href="/hardware/sw05/">
|
||||||
|
<title>sw05 · switch · staging · cluster: — · U8</title>
|
||||||
|
<rect x="43" y="181" width="238" height="18" rx="3" fill="#59a14f" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
|
<text x="162" y="194" text-anchor="middle" fill="#ffffff">sw05 (U8)</text>
|
||||||
</a>
|
</a>
|
||||||
<a href="/hardware/sw02/">
|
<a href="/hardware/sw02/">
|
||||||
<title>sw02 · switch · in-use · cluster: — · U9</title>
|
<title>sw02 · switch · staging · cluster: — · U9</title>
|
||||||
<rect x="43" y="201" width="238" height="18" rx="3" fill="#59a14f" stroke="#333333" stroke-width="1.5"/>
|
<rect x="43" y="201" width="238" height="18" rx="3" fill="#59a14f" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
<text x="162" y="214" text-anchor="middle" fill="#ffffff">sw02 (U9)</text>
|
<text x="162" y="214" text-anchor="middle" fill="#ffffff">sw02 (U9)</text>
|
||||||
</a>
|
</a>
|
||||||
<a href="/hardware/sw03/">
|
<a href="/hardware/sw03/">
|
||||||
<title>sw03 · switch · in-use · cluster: — · U10</title>
|
<title>sw03 · switch · staging · cluster: — · U10</title>
|
||||||
<rect x="43" y="221" width="238" height="18" rx="3" fill="#59a14f" stroke="#333333" stroke-width="1.5"/>
|
<rect x="43" y="221" width="238" height="18" rx="3" fill="#59a14f" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
<text x="162" y="234" text-anchor="middle" fill="#ffffff">sw03 (U10)</text>
|
<text x="162" y="234" text-anchor="middle" fill="#ffffff">sw03 (U10)</text>
|
||||||
</a>
|
</a>
|
||||||
<a href="/hardware/pdu04/">
|
|
||||||
<title>pdu04 · pdu · in-use · cluster: — · U11</title>
|
|
||||||
<rect x="43" y="241" width="238" height="18" rx="3" fill="#e15759" stroke="#333333" stroke-width="1.5"/>
|
|
||||||
<text x="162" y="254" text-anchor="middle" fill="#ffffff">pdu04 (U11)</text>
|
|
||||||
</a>
|
|
||||||
<a href="/hardware/pdu02/">
|
<a href="/hardware/pdu02/">
|
||||||
<title>pdu02 · pdu · in-use · cluster: — · U12</title>
|
<title>pdu02 · pdu · in-use · cluster: — · U12</title>
|
||||||
<rect x="333" y="261" width="238" height="18" rx="3" fill="#e15759" stroke="#333333" stroke-width="1.5"/>
|
<rect x="333" y="261" width="238" height="18" rx="3" fill="#e15759" stroke="#333333" stroke-width="1.5"/>
|
||||||
<text x="452" y="274" text-anchor="middle" fill="#ffffff">pdu02 (U12)</text>
|
<text x="452" y="274" text-anchor="middle" fill="#ffffff">pdu02 (U12)</text>
|
||||||
</a>
|
</a>
|
||||||
|
<a href="/hardware/pdu04/">
|
||||||
|
<title>pdu04 · pdu · in-use · cluster: — · U12</title>
|
||||||
|
<rect x="43" y="261" width="238" height="18" rx="3" fill="#e15759" stroke="#333333" stroke-width="1.5"/>
|
||||||
|
<text x="162" y="274" text-anchor="middle" fill="#ffffff">pdu04 (U12)</text>
|
||||||
|
</a>
|
||||||
|
<a href="/hardware/sw01/">
|
||||||
|
<title>sw01 · switch · in-use · cluster: — · U23</title>
|
||||||
|
<rect x="43" y="481" width="238" height="18" rx="3" fill="#59a14f" stroke="#333333" stroke-width="1.5"/>
|
||||||
|
<text x="162" y="494" text-anchor="middle" fill="#ffffff">sw01 (U23)</text>
|
||||||
|
</a>
|
||||||
<a href="/hardware/pp01/">
|
<a href="/hardware/pp01/">
|
||||||
<title>pp01 · patch-panel · in-use · cluster: — · U25</title>
|
<title>pp01 · patch-panel · in-use · cluster: — · U24</title>
|
||||||
<rect x="43" y="521" width="238" height="18" rx="3" fill="#9c755f" stroke="#333333" stroke-width="1.5"/>
|
<rect x="43" y="501" width="238" height="18" rx="3" fill="#9c755f" stroke="#333333" stroke-width="1.5"/>
|
||||||
<text x="162" y="534" text-anchor="middle" fill="#ffffff">pp01 (U25)</text>
|
<text x="162" y="514" text-anchor="middle" fill="#ffffff">pp01 (U24)</text>
|
||||||
</a>
|
</a>
|
||||||
<a href="/hardware/pp02/">
|
<a href="/hardware/pp02/">
|
||||||
<title>pp02 · patch-panel · in-use · cluster: — · U26</title>
|
<title>pp02 · patch-panel · in-use · cluster: — · U25</title>
|
||||||
<rect x="43" y="541" width="238" height="18" rx="3" fill="#9c755f" stroke="#333333" stroke-width="1.5"/>
|
<rect x="43" y="521" width="238" height="18" rx="3" fill="#9c755f" stroke="#333333" stroke-width="1.5"/>
|
||||||
<text x="162" y="554" text-anchor="middle" fill="#ffffff">pp02 (U26)</text>
|
<text x="162" y="534" text-anchor="middle" fill="#ffffff">pp02 (U25)</text>
|
||||||
</a>
|
|
||||||
<a href="/hardware/sw04/">
|
|
||||||
<title>sw04 · switch · in-use · cluster: — · U32</title>
|
|
||||||
<rect x="43" y="661" width="238" height="18" rx="3" fill="#59a14f" stroke="#333333" stroke-width="1.5"/>
|
|
||||||
<text x="162" y="674" text-anchor="middle" fill="#ffffff">sw04 (U32)</text>
|
|
||||||
</a>
|
</a>
|
||||||
<a href="/hardware/pdu03/">
|
<a href="/hardware/pdu03/">
|
||||||
<title>pdu03 · pdu · in-use · cluster: — · U33</title>
|
<title>pdu03 · pdu · in-use · cluster: — · U34</title>
|
||||||
<rect x="333" y="681" width="238" height="18" rx="3" fill="#e15759" stroke="#333333" stroke-width="1.5"/>
|
<rect x="333" y="701" width="238" height="18" rx="3" fill="#e15759" stroke="#333333" stroke-width="1.5"/>
|
||||||
<text x="452" y="694" text-anchor="middle" fill="#ffffff">pdu03 (U33)</text>
|
<text x="452" y="714" text-anchor="middle" fill="#ffffff">pdu03 (U34)</text>
|
||||||
</a>
|
|
||||||
<a href="/hardware/sw05/">
|
|
||||||
<title>sw05 · switch · in-use · cluster: — · U36</title>
|
|
||||||
<rect x="43" y="741" width="238" height="18" rx="3" fill="#59a14f" stroke="#333333" stroke-width="1.5"/>
|
|
||||||
<text x="162" y="754" text-anchor="middle" fill="#ffffff">sw05 (U36)</text>
|
|
||||||
</a>
|
</a>
|
||||||
<a href="/hardware/srv01/">
|
<a href="/hardware/srv01/">
|
||||||
<title>srv01 · server · staging · cluster: tappaas · shf01/front/slot 1</title>
|
<title>srv01 · server · in-use · cluster: tappaas · shf01/front/slot 1</title>
|
||||||
<rect x="43" y="761" width="38" height="192" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
<rect x="43" y="941" width="118" height="12" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5"/>
|
||||||
<text x="62" y="861" text-anchor="middle" fill="#ffffff">srv01</text>
|
<text x="102" y="951" text-anchor="middle" fill="#ffffff">srv01</text>
|
||||||
</a>
|
</a>
|
||||||
<a href="/hardware/srv02/">
|
<a href="/hardware/srv02/">
|
||||||
<title>srv02 · server · staging · cluster: tappaas · shf01/front/slot 2</title>
|
<title>srv02 · server · staging · cluster: tappaas · shf01/front/slot 2</title>
|
||||||
<rect x="83" y="761" width="38" height="192" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
<rect x="163" y="941" width="118" height="12" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
<text x="102" y="861" text-anchor="middle" fill="#ffffff">srv02</text>
|
<text x="222" y="951" text-anchor="middle" fill="#ffffff">srv02</text>
|
||||||
</a>
|
|
||||||
<a href="/hardware/srv06/">
|
|
||||||
<title>srv06 · server · staging · cluster: tappaas · shf01/front/slot 6</title>
|
|
||||||
<rect x="123" y="761" width="38" height="192" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
|
||||||
<text x="142" y="861" text-anchor="middle" fill="#ffffff">srv06</text>
|
|
||||||
</a>
|
|
||||||
<a href="/hardware/srv07/">
|
|
||||||
<title>srv07 · server · staging · cluster: tappaas · shf01/front/slot 7</title>
|
|
||||||
<rect x="163" y="761" width="38" height="192" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
|
||||||
<text x="182" y="861" text-anchor="middle" fill="#ffffff">srv07</text>
|
|
||||||
</a>
|
|
||||||
<a href="/hardware/nas01/">
|
|
||||||
<title>nas01 · server · staging · cluster: tappaas · shf01/front/slot 8</title>
|
|
||||||
<rect x="203" y="761" width="38" height="192" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
|
||||||
<text x="222" y="861" text-anchor="middle" fill="#ffffff">nas01</text>
|
|
||||||
</a>
|
|
||||||
<a href="/hardware/nas02/">
|
|
||||||
<title>nas02 · server · staging · cluster: tappaas · shf01/front/slot 9</title>
|
|
||||||
<rect x="243" y="761" width="38" height="192" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
|
||||||
<text x="262" y="861" text-anchor="middle" fill="#ffffff">nas02</text>
|
|
||||||
</a>
|
</a>
|
||||||
<a href="/hardware/srv03/">
|
<a href="/hardware/srv03/">
|
||||||
<title>srv03 · server · staging · cluster: tappaas · shf01/rear/slot 1</title>
|
<title>srv03 · server · staging · cluster: tappaas · shf01/rear/slot 1</title>
|
||||||
<rect x="333" y="761" width="238" height="192" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
<rect x="333" y="941" width="238" height="12" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
<text x="452" y="861" text-anchor="middle" fill="#ffffff">srv03</text>
|
<text x="452" y="951" text-anchor="middle" fill="#ffffff">srv03</text>
|
||||||
</a>
|
</a>
|
||||||
<a href="/hardware/shf01/">
|
<a href="/hardware/shf01/">
|
||||||
<title>shf01 · shelf · in-use · cluster: tappaas · U37–U46</title>
|
<title>shf01 · shelf · in-use · cluster: tappaas · U46</title>
|
||||||
<rect x="42" y="954" width="240" height="6" fill="#bab0ac" stroke="#333"/>
|
<rect x="42" y="954" width="240" height="6" fill="#bab0ac" stroke="#333"/>
|
||||||
<rect x="332" y="954" width="240" height="6" fill="#bab0ac" stroke="#333"/>
|
<rect x="332" y="954" width="240" height="6" fill="#bab0ac" stroke="#333"/>
|
||||||
<text x="162" y="959" text-anchor="middle" fill="#333" font-size="9">shf01</text>
|
<text x="162" y="959" text-anchor="middle" fill="#333" font-size="9">shf01</text>
|
||||||
</a>
|
</a>
|
||||||
|
<a href="/hardware/srv07/">
|
||||||
|
<title>srv07 · server · staging · cluster: tappaas · shf02/front/slot 1</title>
|
||||||
|
<rect x="43" y="721" width="118" height="12" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
|
<text x="102" y="731" text-anchor="middle" fill="#ffffff">srv07</text>
|
||||||
|
</a>
|
||||||
|
<a href="/hardware/srv04/">
|
||||||
|
<title>srv04 · server · staging · cluster: — · shf02/front/slot 2</title>
|
||||||
|
<rect x="163" y="721" width="118" height="12" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
|
<text x="222" y="731" text-anchor="middle" fill="#ffffff">srv04</text>
|
||||||
|
</a>
|
||||||
|
<a href="/hardware/srv05/">
|
||||||
|
<title>srv05 · server · staging · cluster: — · shf02/rear/slot 1</title>
|
||||||
|
<rect x="333" y="721" width="118" height="12" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
|
<text x="392" y="731" text-anchor="middle" fill="#ffffff">srv05</text>
|
||||||
|
</a>
|
||||||
|
<a href="/hardware/srv06/">
|
||||||
|
<title>srv06 · server · staging · cluster: tappaas · shf02/rear/slot 2</title>
|
||||||
|
<rect x="453" y="721" width="118" height="12" rx="3" fill="#4c78a8" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
|
<text x="512" y="731" text-anchor="middle" fill="#ffffff">srv06</text>
|
||||||
|
</a>
|
||||||
|
<a href="/hardware/shf02/">
|
||||||
|
<title>shf02 · shelf · in-use · cluster: — · U35</title>
|
||||||
|
<rect x="42" y="734" width="240" height="6" fill="#bab0ac" stroke="#333"/>
|
||||||
|
<rect x="332" y="734" width="240" height="6" fill="#bab0ac" stroke="#333"/>
|
||||||
|
<text x="162" y="739" text-anchor="middle" fill="#333" font-size="9">shf02</text>
|
||||||
|
</a>
|
||||||
|
<a href="/hardware/shf03/">
|
||||||
|
<title>shf03 · shelf · in-use · cluster: — · U21</title>
|
||||||
|
<rect x="42" y="454" width="240" height="6" fill="#bab0ac" stroke="#333"/>
|
||||||
|
<rect x="332" y="454" width="240" height="6" fill="#bab0ac" stroke="#333"/>
|
||||||
|
<text x="162" y="459" text-anchor="middle" fill="#333" font-size="9">shf03</text>
|
||||||
|
</a>
|
||||||
|
<a href="/hardware/shf04/">
|
||||||
|
<title>shf04 · shelf · in-use · cluster: — · U21</title>
|
||||||
|
<rect x="42" y="454" width="240" height="6" fill="#bab0ac" stroke="#333"/>
|
||||||
|
<rect x="332" y="454" width="240" height="6" fill="#bab0ac" stroke="#333"/>
|
||||||
|
<text x="162" y="459" text-anchor="middle" fill="#333" font-size="9">shf04</text>
|
||||||
|
</a>
|
||||||
<text x="42" y="1020" font-weight="bold">Legend</text>
|
<text x="42" y="1020" font-weight="bold">Legend</text>
|
||||||
<rect x="42" y="1028" width="12" height="12" fill="#9c755f" stroke="#333"/>
|
<rect x="42" y="1028" width="12" height="12" fill="#9c755f" stroke="#333"/>
|
||||||
<text x="58" y="1038">patch-panel</text>
|
<text x="58" y="1038">patch-panel</text>
|
||||||
|
|
@ -321,6 +349,8 @@ _Auto-generated from `docs/hardware/*.md` (items with `rack: rack01`) — do not
|
||||||
<text x="282" y="1038">shelf</text>
|
<text x="282" y="1038">shelf</text>
|
||||||
<rect x="329" y="1028" width="12" height="12" fill="#59a14f" stroke="#333"/>
|
<rect x="329" y="1028" width="12" height="12" fill="#59a14f" stroke="#333"/>
|
||||||
<text x="345" y="1038">switch</text>
|
<text x="345" y="1038">switch</text>
|
||||||
|
<rect x="399" y="1028" width="12" height="12" fill="#edc948" stroke="#333"/>
|
||||||
|
<text x="415" y="1038">ups</text>
|
||||||
<rect x="42" y="1046" width="12" height="12" fill="#ffffff" stroke="#333333" stroke-width="1.5"/>
|
<rect x="42" y="1046" width="12" height="12" fill="#ffffff" stroke="#333333" stroke-width="1.5"/>
|
||||||
<text x="58" y="1056">in-use</text>
|
<text x="58" y="1056">in-use</text>
|
||||||
<rect x="112" y="1046" width="12" height="12" fill="#ffffff" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
<rect x="112" y="1046" width="12" height="12" fill="#ffffff" stroke="#333333" stroke-width="1.5" stroke-dasharray="4 2"/>
|
||||||
|
|
@ -338,19 +368,19 @@ _Auto-generated from `docs/hardware/*.md` (items with `rack: rack01`) — do not
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
flowchart LR
|
flowchart LR
|
||||||
pdu01["pdu01<br/>8 outlets"]
|
pdu01["pdu01<br/>9 outlets"]
|
||||||
pdu02["pdu02<br/>8 outlets"]
|
pdu02["pdu02<br/>5 outlets"]
|
||||||
pdu03["pdu03<br/>12 outlets"]
|
pdu03["pdu03<br/>11 outlets"]
|
||||||
pdu04["pdu04<br/>5 outlets"]
|
pdu04["pdu04<br/>5 outlets"]
|
||||||
nas01["nas01"]
|
|
||||||
nas02["nas02"]
|
|
||||||
srv01["srv01"]
|
srv01["srv01"]
|
||||||
srv02["srv02"]
|
srv02["srv02"]
|
||||||
srv03["srv03"]
|
srv03["srv03"]
|
||||||
srv06["srv06"]
|
|
||||||
srv07["srv07"]
|
|
||||||
srv04["srv04"]
|
srv04["srv04"]
|
||||||
srv05["srv05"]
|
srv05["srv05"]
|
||||||
|
srv06["srv06"]
|
||||||
|
srv07["srv07"]
|
||||||
|
nas01["nas01"]
|
||||||
|
nas02["nas02"]
|
||||||
pdu01 -->|outlet 1| nas01
|
pdu01 -->|outlet 1| nas01
|
||||||
pdu01 -->|outlet 1| nas02
|
pdu01 -->|outlet 1| nas02
|
||||||
pdu01 -->|outlet 1| srv01
|
pdu01 -->|outlet 1| srv01
|
||||||
|
|
@ -362,7 +392,6 @@ flowchart LR
|
||||||
pdu01 -->|outlet 5| srv05
|
pdu01 -->|outlet 5| srv05
|
||||||
pdu02 -->|outlet 1| nas01
|
pdu02 -->|outlet 1| nas01
|
||||||
pdu02 -->|outlet 1| nas02
|
pdu02 -->|outlet 1| nas02
|
||||||
pdu02 -->|outlet 1| srv01
|
|
||||||
pdu02 -->|outlet 1| srv06
|
pdu02 -->|outlet 1| srv06
|
||||||
pdu02 -->|outlet 1| srv07
|
pdu02 -->|outlet 1| srv07
|
||||||
style nas01 fill:#4c78a8,stroke:#333,color:#ffffff
|
style nas01 fill:#4c78a8,stroke:#333,color:#ffffff
|
||||||
|
|
@ -397,8 +426,6 @@ flowchart LR
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
flowchart LR
|
flowchart LR
|
||||||
nas01["nas01"]
|
|
||||||
nas02["nas02"]
|
|
||||||
pp01["pp01<br/>patch-panel"]
|
pp01["pp01<br/>patch-panel"]
|
||||||
pp02["pp02<br/>patch-panel"]
|
pp02["pp02<br/>patch-panel"]
|
||||||
srv01["srv01"]
|
srv01["srv01"]
|
||||||
|
|
@ -409,21 +436,24 @@ flowchart LR
|
||||||
srv06["srv06"]
|
srv06["srv06"]
|
||||||
srv07["srv07"]
|
srv07["srv07"]
|
||||||
sw01["sw01<br/>switch"]
|
sw01["sw01<br/>switch"]
|
||||||
nas01 -->|eth0 → p1 · 1G| sw01
|
wan01["wan01"]
|
||||||
nas02 -->|eth0 → p1 · 1G| sw01
|
pp01 -->|1 → p1| wan01
|
||||||
pp01 -->|uplink → p24 · 1G| sw01
|
pp02 -->|1 → p1| pp01
|
||||||
pp02 -->|uplink → p24 · 1G| sw01
|
pp02 -->|2 → p1| sw01
|
||||||
srv01 -->|eth0 → p1 · 1G| sw01
|
pp02 -->|3 → p2| sw01
|
||||||
srv02 -->|eth0 → p1 · 1G| pp01
|
pp02 -->|4 → p3| sw01
|
||||||
srv03 -->|eth0 → p2 · 1G| pp01
|
pp02 -->|5 → p4| sw01
|
||||||
srv04 -->|eth0 → p3 · 1G| pp01
|
pp02 -->|6 → p5| sw01
|
||||||
srv05 -->|eth0 → p4 · 1G| pp01
|
pp02 -->|7 → p6| sw01
|
||||||
srv06 -->|eth0 → p1 · 1G| sw01
|
pp02 -->|8 → p7| sw01
|
||||||
srv07 -->|eth0 → p1 · 1G| sw01
|
srv01 -->|eth0 → p1 · 1G| pp02
|
||||||
style nas01 fill:#4c78a8,stroke:#333,color:#ffffff
|
srv01 -->|eth1 → p2 · 1G| pp02
|
||||||
click nas01 "/hardware/nas01/"
|
srv02 -->|eth0 → p3 · 1G| pp02
|
||||||
style nas02 fill:#4c78a8,stroke:#333,color:#ffffff
|
srv03 -->|eth0 → p4 · 1G| pp02
|
||||||
click nas02 "/hardware/nas02/"
|
srv04 -->|eth0 → p5 · 1G| pp02
|
||||||
|
srv05 -->|eth0 → p6 · 1G| pp02
|
||||||
|
srv06 -->|eth0 → p7 · 1G| pp02
|
||||||
|
srv07 -->|eth0 → p8 · 1G| pp02
|
||||||
style pp01 fill:#9c755f,stroke:#333,color:#ffffff
|
style pp01 fill:#9c755f,stroke:#333,color:#ffffff
|
||||||
click pp01 "/hardware/pp01/"
|
click pp01 "/hardware/pp01/"
|
||||||
style pp02 fill:#9c755f,stroke:#333,color:#ffffff
|
style pp02 fill:#9c755f,stroke:#333,color:#ffffff
|
||||||
|
|
@ -444,6 +474,7 @@ flowchart LR
|
||||||
click srv07 "/hardware/srv07/"
|
click srv07 "/hardware/srv07/"
|
||||||
style sw01 fill:#59a14f,stroke:#333,color:#ffffff
|
style sw01 fill:#59a14f,stroke:#333,color:#ffffff
|
||||||
click sw01 "/hardware/sw01/"
|
click sw01 "/hardware/sw01/"
|
||||||
|
style wan01 fill:#888888,stroke:#333,color:#ffffff
|
||||||
```
|
```
|
||||||
|
|
||||||
## Occupancy
|
## Occupancy
|
||||||
|
|
@ -451,23 +482,28 @@ flowchart LR
|
||||||
| U | Device | Kind | Face | Status |
|
| U | Device | Kind | Face | Status |
|
||||||
|---|---|---|---|---|
|
|---|---|---|---|---|
|
||||||
| U1 | [pdu01](../../hardware/pdu01.md) | pdu | rear | in-use |
|
| U1 | [pdu01](../../hardware/pdu01.md) | pdu | rear | in-use |
|
||||||
| U5–U6 | [srv04](../../hardware/srv04.md) | server | front | staging |
|
| U3 | [ups02](../../hardware/ups02.md) | ups | front | staging |
|
||||||
| U5–U6 | [srv05](../../hardware/srv05.md) | server | rear | staging |
|
| U4 | [ups01](../../hardware/ups01.md) | ups | front | staging |
|
||||||
| U8 | [sw01](../../hardware/sw01.md) | switch | front | in-use |
|
| U5 | [sw04](../../hardware/sw04.md) | switch | front | staging |
|
||||||
| U9 | [sw02](../../hardware/sw02.md) | switch | front | in-use |
|
| U6 | [nas01](../../hardware/nas01.md) | server | front | staging |
|
||||||
| U10 | [sw03](../../hardware/sw03.md) | switch | front | in-use |
|
| U7 | [nas02](../../hardware/nas02.md) | server | front | staging |
|
||||||
| U11 | [pdu04](../../hardware/pdu04.md) | pdu | front | in-use |
|
| U8 | [sw05](../../hardware/sw05.md) | switch | front | staging |
|
||||||
|
| U9 | [sw02](../../hardware/sw02.md) | switch | front | staging |
|
||||||
|
| U10 | [sw03](../../hardware/sw03.md) | switch | front | staging |
|
||||||
| U12 | [pdu02](../../hardware/pdu02.md) | pdu | rear | in-use |
|
| U12 | [pdu02](../../hardware/pdu02.md) | pdu | rear | in-use |
|
||||||
| U25 | [pp01](../../hardware/pp01.md) | patch-panel | front | in-use |
|
| U12 | [pdu04](../../hardware/pdu04.md) | pdu | front | in-use |
|
||||||
| U26 | [pp02](../../hardware/pp02.md) | patch-panel | front | in-use |
|
| U21 | [shf03](../../hardware/shf03.md) | shelf | front | in-use |
|
||||||
| U32 | [sw04](../../hardware/sw04.md) | switch | front | in-use |
|
| U21 | [shf04](../../hardware/shf04.md) | shelf | rear | in-use |
|
||||||
| U33 | [pdu03](../../hardware/pdu03.md) | pdu | rear | in-use |
|
| U23 | [sw01](../../hardware/sw01.md) | switch | front | in-use |
|
||||||
| U36 | [sw05](../../hardware/sw05.md) | switch | front | in-use |
|
| U24 | [pp01](../../hardware/pp01.md) | patch-panel | front | in-use |
|
||||||
| U37–U46 | [shf01](../../hardware/shf01.md) | shelf | both | in-use |
|
| U25 | [pp02](../../hardware/pp02.md) | patch-panel | front | in-use |
|
||||||
| U37–U46 | [srv01](../../hardware/srv01.md) | server | front · shf01/1 | staging |
|
| U34 | [pdu03](../../hardware/pdu03.md) | pdu | rear | in-use |
|
||||||
| U37–U46 | [srv02](../../hardware/srv02.md) | server | front · shf01/2 | staging |
|
| U35 | [shf02](../../hardware/shf02.md) | shelf | both | in-use |
|
||||||
| U37–U46 | [srv06](../../hardware/srv06.md) | server | front · shf01/6 | staging |
|
| U35 | [srv07](../../hardware/srv07.md) | server | front · shf02/1 | staging |
|
||||||
| U37–U46 | [srv07](../../hardware/srv07.md) | server | front · shf01/7 | staging |
|
| U35 | [srv04](../../hardware/srv04.md) | server | front · shf02/2 | staging |
|
||||||
| U37–U46 | [nas01](../../hardware/nas01.md) | server | front · shf01/8 | staging |
|
| U35 | [srv05](../../hardware/srv05.md) | server | rear · shf02/1 | staging |
|
||||||
| U37–U46 | [nas02](../../hardware/nas02.md) | server | front · shf01/9 | staging |
|
| U35 | [srv06](../../hardware/srv06.md) | server | rear · shf02/2 | staging |
|
||||||
| U37–U46 | [srv03](../../hardware/srv03.md) | server | rear · shf01/1 | staging |
|
| U46 | [shf01](../../hardware/shf01.md) | shelf | both | in-use |
|
||||||
|
| U46 | [srv01](../../hardware/srv01.md) | server | front · shf01/1 | in-use |
|
||||||
|
| U46 | [srv02](../../hardware/srv02.md) | server | front · shf01/2 | staging |
|
||||||
|
| U46 | [srv03](../../hardware/srv03.md) | server | rear · shf01/1 | staging |
|
||||||
|
|
|
||||||
|
|
@ -22,11 +22,39 @@ CONFIG_PATH = REPO_ROOT / "scripts" / "overview_config.yml"
|
||||||
|
|
||||||
FRONTMATTER_RE = re.compile(r"^---\s*\n(.*?)\n---\s*\n", re.DOTALL)
|
FRONTMATTER_RE = re.compile(r"^---\s*\n(.*?)\n---\s*\n", re.DOTALL)
|
||||||
|
|
||||||
|
# Shown at the bottom of every error report so a newcomer knows where to look.
|
||||||
|
GUIDE_URL = "https://docs.makerfloss.eu/guides/editing-hardware-docs/"
|
||||||
|
|
||||||
|
|
||||||
class SchemaError(Exception):
|
class SchemaError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def _allowed_hint(field: str, enums: dict) -> str:
|
||||||
|
allowed = enums.get(field)
|
||||||
|
return f" Allowed values: {', '.join(map(str, allowed))}." if allowed else ""
|
||||||
|
|
||||||
|
|
||||||
|
def _example_value(field: str, enums: dict) -> str:
|
||||||
|
allowed = enums.get(field)
|
||||||
|
return str(allowed[0]) if allowed else "..."
|
||||||
|
|
||||||
|
|
||||||
|
def report_errors(errors: list[str], category: str) -> None:
|
||||||
|
"""Print a collected list of problems with orientation for newcomers."""
|
||||||
|
print(
|
||||||
|
f"\ngen_overview: found {len(errors)} problem(s) in the {category} docs:",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
for err in errors:
|
||||||
|
print(f" ✗ {err}", file=sys.stderr)
|
||||||
|
print(
|
||||||
|
"\nFix the field(s) named above, then run 'make docs-index' again.\n"
|
||||||
|
f"Guide: {GUIDE_URL}",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def parse_frontmatter(path: Path) -> dict | None:
|
def parse_frontmatter(path: Path) -> dict | None:
|
||||||
text = path.read_text(encoding="utf-8")
|
text = path.read_text(encoding="utf-8")
|
||||||
m = FRONTMATTER_RE.match(text)
|
m = FRONTMATTER_RE.match(text)
|
||||||
|
|
@ -42,24 +70,33 @@ def parse_frontmatter(path: Path) -> dict | None:
|
||||||
|
|
||||||
|
|
||||||
def validate(path: Path, fm: dict, cfg: dict) -> None:
|
def validate(path: Path, fm: dict, cfg: dict) -> None:
|
||||||
|
enums = cfg.get("enums", {})
|
||||||
|
name = path.name
|
||||||
for field in cfg["required_fields"]:
|
for field in cfg["required_fields"]:
|
||||||
if field not in fm:
|
if field not in fm:
|
||||||
raise SchemaError(f"{path}: missing required field '{field}'")
|
raise SchemaError(
|
||||||
for field, allowed in cfg.get("enums", {}).items():
|
f"{name}: missing required field '{field}'. Add a line like "
|
||||||
|
f"'{field}: {_example_value(field, enums)}' to the frontmatter."
|
||||||
|
f"{_allowed_hint(field, enums)}"
|
||||||
|
)
|
||||||
|
for field, allowed in enums.items():
|
||||||
if field in fm and fm[field] not in allowed:
|
if field in fm and fm[field] not in allowed:
|
||||||
raise SchemaError(
|
raise SchemaError(
|
||||||
f"{path}: {field}={fm[field]!r} not in {allowed}"
|
f"{name}: {field} {fm[field]!r} is not allowed. "
|
||||||
|
f"Use one of: {', '.join(map(str, allowed))}."
|
||||||
)
|
)
|
||||||
key_field = cfg.get("key_field", "hostname")
|
key_field = cfg.get("key_field", "hostname")
|
||||||
if key_field not in fm:
|
if key_field not in fm:
|
||||||
raise SchemaError(
|
raise SchemaError(
|
||||||
f"{path}: missing key field {key_field!r}"
|
f"{name}: missing the '{key_field}' field (the device's id). It must "
|
||||||
|
f"match the filename, e.g. '{key_field}: {path.stem}'."
|
||||||
)
|
)
|
||||||
stem = path.stem
|
stem = path.stem
|
||||||
value = fm[key_field]
|
value = fm[key_field]
|
||||||
if stem != value:
|
if stem != value:
|
||||||
raise SchemaError(
|
raise SchemaError(
|
||||||
f"{path}: filename stem {stem!r} != {key_field} {value!r}"
|
f"{name}: '{key_field}: {value}' does not match the filename '{name}'. "
|
||||||
|
f"Rename the file to '{value}.md', or set {key_field} to '{stem}'."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -222,7 +259,11 @@ def main() -> int:
|
||||||
errors.append(str(e))
|
errors.append(str(e))
|
||||||
continue
|
continue
|
||||||
if fm is None:
|
if fm is None:
|
||||||
print(f"WARNING: {path}: no YAML frontmatter, skipping", file=sys.stderr)
|
print(
|
||||||
|
f"WARNING: {path.name}: no '---' frontmatter block — skipping "
|
||||||
|
f"(it will not appear in the {args.category} index).",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
validate(path, fm, cfg)
|
validate(path, fm, cfg)
|
||||||
|
|
@ -232,8 +273,7 @@ def main() -> int:
|
||||||
items.append(fm)
|
items.append(fm)
|
||||||
|
|
||||||
if errors:
|
if errors:
|
||||||
for err in errors:
|
report_errors(errors, args.category)
|
||||||
print(f"ERROR: {err}", file=sys.stderr)
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
output_file.parent.mkdir(parents=True, exist_ok=True)
|
output_file.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,9 @@ FACES = {"front", "rear", "both", "left", "right"}
|
||||||
ZERO_U_FACES = {"left", "right"}
|
ZERO_U_FACES = {"left", "right"}
|
||||||
SHELF_FACES = {"front", "rear"}
|
SHELF_FACES = {"front", "rear"}
|
||||||
|
|
||||||
|
# Shown at the bottom of every error report so a newcomer knows where to look.
|
||||||
|
GUIDE_URL = "https://docs.makerfloss.eu/guides/editing-hardware-docs/"
|
||||||
|
|
||||||
KIND_COLORS = {
|
KIND_COLORS = {
|
||||||
"server": "#4c78a8",
|
"server": "#4c78a8",
|
||||||
"switch": "#59a14f",
|
"switch": "#59a14f",
|
||||||
|
|
@ -76,45 +79,65 @@ def validate_item(fm: dict) -> None:
|
||||||
name = fm.get("hostname") or fm.get("_path", "?")
|
name = fm.get("hostname") or fm.get("_path", "?")
|
||||||
rack = fm.get("rack")
|
rack = fm.get("rack")
|
||||||
if not isinstance(rack, str) or not rack:
|
if not isinstance(rack, str) or not rack:
|
||||||
raise SchemaError(f"{name}: rack must be a non-empty string")
|
raise SchemaError(f"{name}: 'rack' must name a rack, e.g. 'rack: rack01'.")
|
||||||
if "mounted_on" in fm:
|
if "mounted_on" in fm:
|
||||||
mounted_on = fm.get("mounted_on")
|
mounted_on = fm.get("mounted_on")
|
||||||
if not isinstance(mounted_on, str) or not mounted_on:
|
if not isinstance(mounted_on, str) or not mounted_on:
|
||||||
raise SchemaError(f"{name}: mounted_on must be a non-empty string")
|
raise SchemaError(
|
||||||
|
f"{name}: 'mounted_on' must name the shelf it sits on, "
|
||||||
|
f"e.g. 'mounted_on: shf01'."
|
||||||
|
)
|
||||||
for forbidden in ("rack_u", "u_height", "rack_face"):
|
for forbidden in ("rack_u", "u_height", "rack_face"):
|
||||||
if forbidden in fm:
|
if forbidden in fm:
|
||||||
raise SchemaError(
|
raise SchemaError(
|
||||||
f"{name}: mounted item must omit {forbidden}"
|
f"{name}: a shelf-mounted device must not set '{forbidden}' — "
|
||||||
|
f"it takes its position from the shelf. Use 'shelf_face' and "
|
||||||
|
f"'shelf_slot' instead."
|
||||||
)
|
)
|
||||||
sface = fm.get("shelf_face")
|
sface = fm.get("shelf_face")
|
||||||
if sface not in SHELF_FACES:
|
if sface not in SHELF_FACES:
|
||||||
raise SchemaError(
|
raise SchemaError(
|
||||||
f"{name}: shelf_face={sface!r} not in {sorted(SHELF_FACES)}"
|
f"{name}: shelf_face {sface!r} must be 'front' or 'rear'."
|
||||||
)
|
)
|
||||||
slot = fm.get("shelf_slot")
|
slot = fm.get("shelf_slot")
|
||||||
if not isinstance(slot, int) or slot < 1:
|
if not isinstance(slot, int) or slot < 1:
|
||||||
raise SchemaError(f"{name}: shelf_slot must be an integer >= 1")
|
raise SchemaError(
|
||||||
|
f"{name}: 'shelf_slot' must be a whole number 1 or higher "
|
||||||
|
f"(got {slot!r})."
|
||||||
|
)
|
||||||
return
|
return
|
||||||
face = fm.get("rack_face")
|
face = fm.get("rack_face")
|
||||||
if face not in FACES:
|
if face not in FACES:
|
||||||
raise SchemaError(f"{name}: rack_face={face!r} not in {sorted(FACES)}")
|
raise SchemaError(
|
||||||
|
f"{name}: rack_face {face!r} is not valid. Use 'front', 'rear' or "
|
||||||
|
f"'both' for a U-mounted device, or 'left'/'right' for a 0U side rail."
|
||||||
|
)
|
||||||
if face in ZERO_U_FACES:
|
if face in ZERO_U_FACES:
|
||||||
if "rack_u" in fm or "u_height" in fm:
|
if "rack_u" in fm or "u_height" in fm:
|
||||||
raise SchemaError(
|
raise SchemaError(
|
||||||
f"{name}: 0U item (face={face}) must omit rack_u/u_height"
|
f"{name}: a side-rail device (rack_face: {face}) is 0U — remove "
|
||||||
|
f"'rack_u' and 'u_height'."
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
u = fm.get("rack_u")
|
u = fm.get("rack_u")
|
||||||
h = fm.get("u_height")
|
h = fm.get("u_height")
|
||||||
if not isinstance(u, int) or not isinstance(h, int):
|
if not isinstance(u, int) or not isinstance(h, int):
|
||||||
raise SchemaError(f"{name}: rack_u and u_height must be integers")
|
raise SchemaError(
|
||||||
|
f"{name}: a {face}-mounted device needs whole-number 'rack_u' and "
|
||||||
|
f"'u_height' (e.g. 'rack_u: 12' and 'u_height: 2')."
|
||||||
|
)
|
||||||
if u < 1 or u > RACK_UNITS:
|
if u < 1 or u > RACK_UNITS:
|
||||||
raise SchemaError(f"{name}: rack_u={u} out of range 1..{RACK_UNITS}")
|
raise SchemaError(
|
||||||
|
f"{name}: rack_u={u} is outside the rack — it must be between 1 "
|
||||||
|
f"and {RACK_UNITS}."
|
||||||
|
)
|
||||||
if h < 1:
|
if h < 1:
|
||||||
raise SchemaError(f"{name}: u_height={h} must be >= 1")
|
raise SchemaError(f"{name}: u_height={h} must be at least 1.")
|
||||||
if u + h - 1 > RACK_UNITS:
|
if u + h - 1 > RACK_UNITS:
|
||||||
raise SchemaError(
|
raise SchemaError(
|
||||||
f"{name}: occupies U{u}..U{u + h - 1}, exceeds {RACK_UNITS}U"
|
f"{name}: a {h}U device starting at U{u} runs off the top of the rack "
|
||||||
|
f"(it would need U{u}–U{u + h - 1}, but the rack is only {RACK_UNITS}U). "
|
||||||
|
f"Lower 'rack_u' or 'u_height'."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -136,7 +159,9 @@ def check_overlaps(items: list[dict]) -> None:
|
||||||
key = (f, uu)
|
key = (f, uu)
|
||||||
if key in occupied:
|
if key in occupied:
|
||||||
raise SchemaError(
|
raise SchemaError(
|
||||||
f"U{uu} {f}: {name} overlaps {occupied[key]}"
|
f"U{uu} {f}: {name} overlaps {occupied[key]} — two devices "
|
||||||
|
f"can't share the same U on the same face. Move one to a "
|
||||||
|
f"free U or to the other face."
|
||||||
)
|
)
|
||||||
occupied[key] = name
|
occupied[key] = name
|
||||||
|
|
||||||
|
|
@ -157,23 +182,27 @@ def check_shelves(items: list[dict]) -> None:
|
||||||
target = by_host.get(shelf_name)
|
target = by_host.get(shelf_name)
|
||||||
if target is None:
|
if target is None:
|
||||||
raise SchemaError(
|
raise SchemaError(
|
||||||
f"{name}: mounted_on={shelf_name!r} is not in this rack"
|
f"{name}: mounted_on={shelf_name!r} — no device with that id is in "
|
||||||
|
f"this rack. Check the shelf's hostname."
|
||||||
)
|
)
|
||||||
if target.get("kind") != "shelf":
|
if target.get("kind") != "shelf":
|
||||||
raise SchemaError(
|
raise SchemaError(
|
||||||
f"{name}: mounted_on={shelf_name!r} is not a kind:shelf item"
|
f"{name}: mounted_on={shelf_name!r} is a {target.get('kind')!r}, "
|
||||||
|
f"not a shelf. Only kind:shelf devices can hold mounted gear."
|
||||||
)
|
)
|
||||||
if not isinstance(target.get("rack_u"), int) or not isinstance(
|
if not isinstance(target.get("rack_u"), int) or not isinstance(
|
||||||
target.get("u_height"), int
|
target.get("u_height"), int
|
||||||
):
|
):
|
||||||
raise SchemaError(
|
raise SchemaError(
|
||||||
f"{name}: shelf {shelf_name!r} is not placed (needs rack_u/u_height)"
|
f"{name}: the shelf {shelf_name!r} has no position yet — give it "
|
||||||
|
f"'rack_u' and 'u_height' first."
|
||||||
)
|
)
|
||||||
key = (shelf_name, fm["shelf_face"], fm["shelf_slot"])
|
key = (shelf_name, fm["shelf_face"], fm["shelf_slot"])
|
||||||
if key in occupied:
|
if key in occupied:
|
||||||
raise SchemaError(
|
raise SchemaError(
|
||||||
f"{shelf_name} {fm['shelf_face']} slot {fm['shelf_slot']}: "
|
f"{shelf_name} {fm['shelf_face']} slot {fm['shelf_slot']}: "
|
||||||
f"{name} overlaps {occupied[key]}"
|
f"{name} overlaps {occupied[key]} — each shelf face and slot holds "
|
||||||
|
f"one device."
|
||||||
)
|
)
|
||||||
occupied[key] = name
|
occupied[key] = name
|
||||||
|
|
||||||
|
|
@ -206,30 +235,44 @@ def validate_links(items: list[dict], hw_index: dict[str, dict]) -> None:
|
||||||
continue
|
continue
|
||||||
name = fm.get("hostname", "?")
|
name = fm.get("hostname", "?")
|
||||||
if not isinstance(links, list):
|
if not isinstance(links, list):
|
||||||
raise SchemaError(f"{name}: links must be a list")
|
raise SchemaError(
|
||||||
|
f"{name}: 'links' must be a list of cables like "
|
||||||
|
f"'- {{ local: eth0, peer: sw01, peer_port: 1 }}'."
|
||||||
|
)
|
||||||
for link in links:
|
for link in links:
|
||||||
if not isinstance(link, dict):
|
if not isinstance(link, dict):
|
||||||
raise SchemaError(f"{name}: links entry must be a mapping")
|
raise SchemaError(
|
||||||
|
f"{name}: each 'links' entry must look like "
|
||||||
|
f"'{{ local: eth0, peer: sw01, peer_port: 1 }}'."
|
||||||
|
)
|
||||||
local = link.get("local")
|
local = link.get("local")
|
||||||
peer = link.get("peer")
|
peer = link.get("peer")
|
||||||
peer_port = link.get("peer_port")
|
peer_port = link.get("peer_port")
|
||||||
if not isinstance(local, str) or not local:
|
if not isinstance(local, str) or not local:
|
||||||
raise SchemaError(f"{name}: links entry needs a non-empty 'local'")
|
raise SchemaError(
|
||||||
|
f"{name}: a 'links' entry needs a 'local' port name, "
|
||||||
|
f"e.g. 'local: eth0'."
|
||||||
|
)
|
||||||
if not isinstance(peer, str) or not peer:
|
if not isinstance(peer, str) or not peer:
|
||||||
raise SchemaError(f"{name}: links entry needs a non-empty 'peer'")
|
raise SchemaError(
|
||||||
|
f"{name}: a 'links' entry needs a 'peer' device, "
|
||||||
|
f"e.g. 'peer: sw01'."
|
||||||
|
)
|
||||||
if not isinstance(peer_port, int):
|
if not isinstance(peer_port, int):
|
||||||
raise SchemaError(
|
raise SchemaError(
|
||||||
f"{name}: links entry for {peer} needs an integer 'peer_port'"
|
f"{name}: the link to {peer} needs a whole-number 'peer_port'."
|
||||||
)
|
)
|
||||||
target = hw_index.get(peer)
|
target = hw_index.get(peer)
|
||||||
if target is None:
|
if target is None:
|
||||||
raise SchemaError(
|
raise SchemaError(
|
||||||
f"{name}: links peer={peer!r} is not a known hardware file"
|
f"{name}: link points at peer={peer!r}, but no hardware file "
|
||||||
|
f"has that id. Check the peer hostname."
|
||||||
)
|
)
|
||||||
ports = target.get("ports")
|
ports = target.get("ports")
|
||||||
if isinstance(ports, int) and (peer_port < 1 or peer_port > ports):
|
if isinstance(ports, int) and (peer_port < 1 or peer_port > ports):
|
||||||
raise SchemaError(
|
raise SchemaError(
|
||||||
f"{name}: peer_port {peer_port} out of range 1..{ports} on {peer}"
|
f"{name}: peer_port {peer_port} doesn't exist on {peer} — it "
|
||||||
|
f"has {ports} port(s) (valid 1–{ports})."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -253,7 +296,7 @@ def validate_power(items: list[dict]) -> None:
|
||||||
outlets = fm.get("outlets")
|
outlets = fm.get("outlets")
|
||||||
if not isinstance(outlets, int) or outlets < 1:
|
if not isinstance(outlets, int) or outlets < 1:
|
||||||
raise SchemaError(
|
raise SchemaError(
|
||||||
f"{name}: kind:pdu must declare a positive integer 'outlets'"
|
f"{name}: a PDU must say how many outlets it has, e.g. 'outlets: 8'."
|
||||||
)
|
)
|
||||||
for fm in items:
|
for fm in items:
|
||||||
feeds = fm.get("power")
|
feeds = fm.get("power")
|
||||||
|
|
@ -261,27 +304,38 @@ def validate_power(items: list[dict]) -> None:
|
||||||
continue
|
continue
|
||||||
name = fm.get("hostname", "?")
|
name = fm.get("hostname", "?")
|
||||||
if not isinstance(feeds, list):
|
if not isinstance(feeds, list):
|
||||||
raise SchemaError(f"{name}: power must be a list")
|
raise SchemaError(
|
||||||
|
f"{name}: 'power' must be a list of feeds like "
|
||||||
|
f"'- {{ pdu: pdu01, outlet: 1 }}'."
|
||||||
|
)
|
||||||
for feed in feeds:
|
for feed in feeds:
|
||||||
if not isinstance(feed, dict):
|
if not isinstance(feed, dict):
|
||||||
raise SchemaError(f"{name}: power entry must be a mapping")
|
raise SchemaError(
|
||||||
|
f"{name}: each 'power' feed must look like "
|
||||||
|
f"'{{ pdu: pdu01, outlet: 1 }}'."
|
||||||
|
)
|
||||||
pdu = feed.get("pdu")
|
pdu = feed.get("pdu")
|
||||||
outlet = feed.get("outlet")
|
outlet = feed.get("outlet")
|
||||||
if not isinstance(pdu, str) or not pdu:
|
if not isinstance(pdu, str) or not pdu:
|
||||||
raise SchemaError(f"{name}: power entry needs a non-empty 'pdu'")
|
raise SchemaError(
|
||||||
|
f"{name}: a 'power' feed needs a 'pdu' name, "
|
||||||
|
f"e.g. '{{ pdu: pdu01, outlet: 1 }}'."
|
||||||
|
)
|
||||||
if not isinstance(outlet, int):
|
if not isinstance(outlet, int):
|
||||||
raise SchemaError(
|
raise SchemaError(
|
||||||
f"{name}: power entry for {pdu} needs an integer 'outlet'"
|
f"{name}: the 'power' feed to {pdu} needs a whole-number 'outlet'."
|
||||||
)
|
)
|
||||||
target = pdus.get(pdu)
|
target = pdus.get(pdu)
|
||||||
if target is None:
|
if target is None:
|
||||||
raise SchemaError(
|
raise SchemaError(
|
||||||
f"{name}: power pdu={pdu!r} is not a known kind:pdu file"
|
f"{name}: power feed points at pdu={pdu!r}, but no kind:pdu "
|
||||||
|
f"device has that id. Check the PDU hostname."
|
||||||
)
|
)
|
||||||
count = target["outlets"]
|
count = target["outlets"]
|
||||||
if outlet < 1 or outlet > count:
|
if outlet < 1 or outlet > count:
|
||||||
raise SchemaError(
|
raise SchemaError(
|
||||||
f"{name}: outlet {outlet} out of range 1..{count} on {pdu}"
|
f"{name}: outlet {outlet} doesn't exist on {pdu} — it has "
|
||||||
|
f"{count} outlet(s) (valid 1–{count})."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -752,6 +806,22 @@ def render_page(rack: str, items: list[dict]) -> str:
|
||||||
return "\n".join(lines).rstrip() + "\n"
|
return "\n".join(lines).rstrip() + "\n"
|
||||||
|
|
||||||
|
|
||||||
|
def report_errors(errors: list[str]) -> None:
|
||||||
|
"""Print a collected list of problems with orientation for newcomers."""
|
||||||
|
print(
|
||||||
|
f"\ngen_rack: found {len(errors)} problem(s) in docs/hardware/:",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
for err in errors:
|
||||||
|
print(f" ✗ {err}", file=sys.stderr)
|
||||||
|
print(
|
||||||
|
"\nEach line is '<device>: what's wrong'. Fix the named frontmatter "
|
||||||
|
"field(s),\nthen run 'make docs-index' again.\n"
|
||||||
|
f"Guide: {GUIDE_URL}",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def generate(hardware_dir: Path, output_dir: Path) -> int:
|
def generate(hardware_dir: Path, output_dir: Path) -> int:
|
||||||
items = load_rack_items(hardware_dir)
|
items = load_rack_items(hardware_dir)
|
||||||
hw_index = load_hardware_index(hardware_dir)
|
hw_index = load_hardware_index(hardware_dir)
|
||||||
|
|
@ -778,8 +848,7 @@ def generate(hardware_dir: Path, output_dir: Path) -> int:
|
||||||
errors.append(f"{rack}: {e}")
|
errors.append(f"{rack}: {e}")
|
||||||
|
|
||||||
if errors:
|
if errors:
|
||||||
for err in errors:
|
report_errors(errors)
|
||||||
print(f"ERROR: {err}", file=sys.stderr)
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
output_dir.mkdir(parents=True, exist_ok=True)
|
output_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ hardware:
|
||||||
- kind
|
- kind
|
||||||
- status
|
- status
|
||||||
enums:
|
enums:
|
||||||
kind: [server, laptop, sbc, switch, ap, desktop, pdu, patch-panel, shelf, blank, ups, kvm]
|
kind: [server, laptop, sbc, switch, ap, desktop, pdu, patch-panel, shelf, blank, ups, kvm, wan]
|
||||||
status: [in-use, staging, spare, broken, donated]
|
status: [in-use, staging, spare, broken, donated]
|
||||||
storage_type: [nvme, ssd, hdd, mixed]
|
storage_type: [nvme, ssd, hdd, mixed]
|
||||||
group_by: kind
|
group_by: kind
|
||||||
|
|
@ -33,6 +33,7 @@ hardware:
|
||||||
blank: Blank panels
|
blank: Blank panels
|
||||||
ups: UPS
|
ups: UPS
|
||||||
kvm: KVM
|
kvm: KVM
|
||||||
|
wan: WAN uplinks
|
||||||
sort_by: hostname
|
sort_by: hostname
|
||||||
columns:
|
columns:
|
||||||
- { header: Hostname, kind: key-link, field: hostname }
|
- { header: Hostname, kind: key-link, field: hostname }
|
||||||
|
|
|
||||||
48
tests/test_gen_overview.py
Normal file
48
tests/test_gen_overview.py
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
import gen_overview
|
||||||
|
|
||||||
|
|
||||||
|
CFG = {
|
||||||
|
"required_fields": ["hostname", "kind", "status"],
|
||||||
|
"enums": {
|
||||||
|
"kind": ["server", "switch", "pdu"],
|
||||||
|
"status": ["in-use", "staging", "spare"],
|
||||||
|
},
|
||||||
|
"key_field": "hostname",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def validate(stem, fm):
|
||||||
|
from pathlib import Path
|
||||||
|
gen_overview.validate(Path(f"{stem}.md"), fm, CFG)
|
||||||
|
|
||||||
|
|
||||||
|
def test_missing_required_field_names_field_and_lists_allowed():
|
||||||
|
with pytest.raises(gen_overview.SchemaError) as ei:
|
||||||
|
validate("srv06", {"hostname": "srv06", "kind": "server"})
|
||||||
|
msg = str(ei.value)
|
||||||
|
assert "status" in msg # which field
|
||||||
|
assert "in-use" in msg # an allowed value, so a novice knows what to type
|
||||||
|
|
||||||
|
|
||||||
|
def test_enum_violation_lists_allowed_values():
|
||||||
|
with pytest.raises(gen_overview.SchemaError) as ei:
|
||||||
|
validate("x", {"hostname": "x", "kind": "router", "status": "in-use"})
|
||||||
|
msg = str(ei.value)
|
||||||
|
assert "router" in msg # the offending value
|
||||||
|
assert "server" in msg # an allowed value
|
||||||
|
|
||||||
|
|
||||||
|
def test_filename_mismatch_explains_the_rename():
|
||||||
|
with pytest.raises(gen_overview.SchemaError) as ei:
|
||||||
|
validate("srv06", {"hostname": "srv07", "kind": "server", "status": "in-use"})
|
||||||
|
msg = str(ei.value).lower()
|
||||||
|
assert "srv07.md" in msg or "rename" in msg
|
||||||
|
|
||||||
|
|
||||||
|
def test_error_report_points_to_the_guide(capsys):
|
||||||
|
gen_overview.report_errors(["srv06.md: missing required field 'status'"], "hardware")
|
||||||
|
err = capsys.readouterr().err
|
||||||
|
assert "make docs-index" in err
|
||||||
|
assert gen_overview.GUIDE_URL in err
|
||||||
|
|
@ -744,3 +744,47 @@ def test_network_graph_off_rack_peer_has_no_click():
|
||||||
assert "style router0 fill:" in out # off-rack peer is still colored
|
assert "style router0 fill:" in out # off-rack peer is still colored
|
||||||
assert 'click router0 "' not in out # but it is NOT clickable
|
assert 'click router0 "' not in out # but it is NOT clickable
|
||||||
assert 'click srv01 "/hardware/srv01/"' in out
|
assert 'click srv01 "/hardware/srv01/"' in out
|
||||||
|
|
||||||
|
|
||||||
|
# --- novice-friendly error messages ---------------------------------------
|
||||||
|
|
||||||
|
def test_overlap_message_explains_the_conflict():
|
||||||
|
items = [
|
||||||
|
item(hostname="a", rack_u=1, u_height=2, rack_face="front"),
|
||||||
|
item(hostname="b", rack_u=2, u_height=1, rack_face="front"),
|
||||||
|
]
|
||||||
|
with pytest.raises(gen_rack.SchemaError) as ei:
|
||||||
|
gen_rack.check_overlaps(items)
|
||||||
|
msg = str(ei.value).lower()
|
||||||
|
assert "overlap" in msg
|
||||||
|
assert "same u" in msg or "free u" in msg or "other face" in msg # tells them how to fix
|
||||||
|
|
||||||
|
|
||||||
|
def test_zero_u_message_tells_user_to_drop_units():
|
||||||
|
with pytest.raises(gen_rack.SchemaError) as ei:
|
||||||
|
gen_rack.validate_item(item(rack_face="left", rack_u=1, u_height=1))
|
||||||
|
msg = str(ei.value).lower()
|
||||||
|
assert "rack_u" in msg and "remove" in msg
|
||||||
|
|
||||||
|
|
||||||
|
def test_bad_face_message_lists_valid_faces():
|
||||||
|
with pytest.raises(gen_rack.SchemaError) as ei:
|
||||||
|
gen_rack.validate_item(item(rack_u=1, u_height=1, rack_face="sideways"))
|
||||||
|
msg = str(ei.value)
|
||||||
|
assert "front" in msg and "left" in msg # both U-mounted and 0U options shown
|
||||||
|
|
||||||
|
|
||||||
|
def test_generate_error_output_is_novice_friendly(tmp_path, capsys):
|
||||||
|
hw = tmp_path / "hardware"
|
||||||
|
out = tmp_path / "out"
|
||||||
|
hw.mkdir()
|
||||||
|
_write_item(
|
||||||
|
hw, "srv01",
|
||||||
|
"---\nhostname: srv01\nkind: server\nstatus: in-use\n"
|
||||||
|
"rack: rack01\nrack_face: front\n---\n", # front face but no rack_u/u_height
|
||||||
|
)
|
||||||
|
rc = gen_rack.generate(hw, out)
|
||||||
|
err = capsys.readouterr().err
|
||||||
|
assert rc == 1
|
||||||
|
assert "make docs-index" in err
|
||||||
|
assert gen_rack.GUIDE_URL in err
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue