Merge pull request #2 from luci-digital/claude/investigate-access-014T5RzeRXDnWM4SpKrWRRQL
Add ORION Hybrid Architecture - Combining best features from Proxmox …
This commit is contained in:
commit
12c2635842
|
|
@ -0,0 +1,688 @@
|
|||
# ORION Hybrid Architecture Documentation
|
||||
|
||||
**Version**: 2.0.0-hybrid
|
||||
**Last Updated**: 2025-01-20
|
||||
**System**: Dell PowerEdge R730 (CQ5QBM2)
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Overview](#overview)
|
||||
2. [Architecture Design](#architecture-design)
|
||||
3. [Key Features](#key-features)
|
||||
4. [Hardware Specifications](#hardware-specifications)
|
||||
5. [Network Architecture](#network-architecture)
|
||||
6. [Virtual Machines](#virtual-machines)
|
||||
7. [Deployment Process](#deployment-process)
|
||||
8. [Monitoring & Management](#monitoring--management)
|
||||
9. [Troubleshooting](#troubleshooting)
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
The ORION Hybrid Architecture combines the best features from multiple deployment strategies to create a robust, flexible, and intelligent network infrastructure:
|
||||
|
||||
- **Proxmox VE** as the virtualization foundation (flexibility)
|
||||
- **NixOS + VyOS Router** for high-performance routing (performance)
|
||||
- **AI Autonomous Agent** for intelligent monitoring (intelligence)
|
||||
- **macOS Support** via OSX-PROXMOX (development)
|
||||
- **iDRAC Automation** for remote management (automation)
|
||||
|
||||
### Design Philosophy
|
||||
|
||||
**Best of Both Worlds**:
|
||||
- ✅ Virtualization flexibility from Proxmox
|
||||
- ✅ Bare-metal routing performance from VyOS
|
||||
- ✅ Declarative configuration from NixOS
|
||||
- ✅ AI-powered automation and monitoring
|
||||
- ✅ macOS development environment
|
||||
- ✅ Full remote management via iDRAC
|
||||
|
||||
---
|
||||
|
||||
## Architecture Design
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Dell PowerEdge R730 ORION │
|
||||
│ (CQ5QBM2 - 384GB RAM) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────────────────────────┐ │
|
||||
│ │ iDRAC Enterprise (192.168.1.2) │ │
|
||||
│ │ Redfish API - Full Remote Management │ │
|
||||
│ └───────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌───────────────────────────────────────────────────────────┐ │
|
||||
│ │ Proxmox VE 8.x Hypervisor Layer │ │
|
||||
│ │ Management: 192.168.100.10:8006 │ │
|
||||
│ └───────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ┌──────────────────┼──────────────────┐ │
|
||||
│ │ │ │ │
|
||||
│ ┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐ │
|
||||
│ │ VM 200 │ │ VM 300 │ │ VM 100 │ │
|
||||
│ │ Router │ │ AI Agent │ │ macOS │ │
|
||||
│ │ │ │ │ │ Sequoia │ │
|
||||
│ │ NixOS+VyOS │ │ NixOS │ │ │ │
|
||||
│ │ 8 cores │ │ 4 cores │ │ 12 cores │ │
|
||||
│ │ 32GB │ │ 16GB │ │ 64GB │ │
|
||||
│ │ │ │ │ │ │ │
|
||||
│ │ Services: │ │ Services: │ │ Purpose: │ │
|
||||
│ │ • BGP │ │ • AI Agent │ │ • Dev Env │ │
|
||||
│ │ • Firewall │ │ • Prometh. │ │ • Testing │ │
|
||||
│ │ • DHCP/DNS │ │ • Grafana │ │ • Build │ │
|
||||
│ │ • NAT │ │ • Alerts │ │ │ │
|
||||
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
│ │ │
|
||||
┌────▼────┐ ┌───▼───┐ ┌───▼───┐
|
||||
│ WAN │ │ LAN │ │ Guest │
|
||||
│ Telus │ │ .100 │ │ .200 │
|
||||
│ 10GbE │ │10GbE │ │ 10GbE │
|
||||
└─────────┘ └───────┘ └───────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key Features
|
||||
|
||||
### 1. **Hybrid Virtualization Model**
|
||||
|
||||
- **Proxmox VE 8.x**: Enterprise-grade hypervisor
|
||||
- Web-based management UI
|
||||
- Live migration support
|
||||
- Snapshot and backup capabilities
|
||||
- LXC container support
|
||||
|
||||
- **NixOS VMs**: Declarative, reproducible configurations
|
||||
- Atomic updates and rollbacks
|
||||
- Immutable infrastructure
|
||||
- Easy version control
|
||||
|
||||
### 2. **High-Performance Routing**
|
||||
|
||||
- **VyOS Router** (VM 200):
|
||||
- Dedicated routing VM with minimal overhead
|
||||
- BIRD2 for BGP routing
|
||||
- nftables for high-performance firewalling
|
||||
- Hardware-accelerated networking (virtio)
|
||||
|
||||
### 3. **AI-Powered Monitoring**
|
||||
|
||||
- **Autonomous Agent** (VM 300):
|
||||
- Real-time network health monitoring
|
||||
- Automatic issue detection
|
||||
- Self-healing capabilities
|
||||
- Predictive analysis
|
||||
|
||||
### 4. **macOS Development**
|
||||
|
||||
- **macOS Sequoia** (VM 100):
|
||||
- Full macOS 15 support via OSX-PROXMOX
|
||||
- 12 cores / 64GB RAM
|
||||
- Metal GPU acceleration
|
||||
- OpenCore bootloader
|
||||
|
||||
### 5. **Full Automation**
|
||||
|
||||
- **iDRAC Redfish API**:
|
||||
- Remote power management
|
||||
- Boot configuration
|
||||
- Hardware monitoring
|
||||
- Virtual media mounting
|
||||
|
||||
---
|
||||
|
||||
## Hardware Specifications
|
||||
|
||||
### Dell PowerEdge R730 (CQ5QBM2)
|
||||
|
||||
| Component | Specification |
|
||||
|-----------|---------------|
|
||||
| **CPUs** | 2x Intel Xeon E5-2690 v4 (14 cores, 2.6GHz) |
|
||||
| **Total Cores** | 28 physical / 56 threads |
|
||||
| **RAM** | 384GB DDR4-2400 (12x 32GB Samsung) |
|
||||
| **Storage Controller** | PERC H730 Mini (RAID 10) |
|
||||
| **Network** | 8x NICs (4x 10GbE + 4x 1GbE) |
|
||||
| **Power** | Dual 750W redundant PSUs |
|
||||
| **Management** | iDRAC 8 Enterprise |
|
||||
|
||||
### Network Interface Mapping
|
||||
|
||||
| Interface | MAC | Speed | Purpose |
|
||||
|-----------|-----|-------|---------|
|
||||
| eno1 | D0:94:66:24:96:7C | 1GbE | Proxmox Management |
|
||||
| eno2 | D0:94:66:24:96:7D | 1GbE | Reserved |
|
||||
| eno3 | D0:94:66:24:96:7E | 10GbE | WAN (Telus Fiber) → vmbr0 |
|
||||
| eno4 | D0:94:66:24:96:80 | 10GbE | LAN (Internal) → vmbr1 |
|
||||
| eno5 | - | 10GbE | macOS Network → vmbr2 |
|
||||
| eno6 | - | 10GbE | Storage Network → vmbr3 |
|
||||
| enp3s0f0 | - | 10GbE | Available (Slot 3) |
|
||||
| enp3s0f1 | - | 10GbE | Available (Slot 3) |
|
||||
|
||||
---
|
||||
|
||||
## Network Architecture
|
||||
|
||||
### IP Addressing Scheme
|
||||
|
||||
#### WAN (Telus Fiber)
|
||||
- **Interface**: vmbr0 (eno3)
|
||||
- **IPv4**: DHCP from Telus
|
||||
- **IPv6**: 2602:F674::/48 (prefix delegation)
|
||||
- **BGP AS**: 394955
|
||||
- **Peers**:
|
||||
- 206.75.1.127 (Primary - AS 6939)
|
||||
- 206.75.1.47 (Secondary - AS 6939)
|
||||
- 206.75.1.48 (Tertiary - AS 6939)
|
||||
|
||||
#### LAN (Internal Network)
|
||||
- **Interface**: vmbr1 (eno4)
|
||||
- **IPv4**: 192.168.100.0/24
|
||||
- **Gateway**: 192.168.100.1 (Router VM)
|
||||
- **DHCP Range**: 192.168.100.100 - 192.168.100.200
|
||||
- **DNS**: 192.168.100.1 (Unbound)
|
||||
- **IPv6**: 2602:F674:1000::/64
|
||||
|
||||
#### Guest Network
|
||||
- **Interface**: vmbr2
|
||||
- **IPv4**: 192.168.200.0/24
|
||||
- **Gateway**: 192.168.200.1 (Router VM)
|
||||
- **Isolation**: Restricted to WAN only
|
||||
|
||||
#### Management Network
|
||||
- **IPv4**: 192.168.1.0/24
|
||||
- **Proxmox**: 192.168.1.10 (eno1)
|
||||
- **iDRAC**: 192.168.1.2
|
||||
- **Router**: 192.168.1.1 (eth3)
|
||||
|
||||
### Network Bridges (Proxmox)
|
||||
|
||||
```
|
||||
vmbr0: WAN Bridge
|
||||
- Physical: eno3 (10GbE)
|
||||
- Purpose: Router VM WAN interface
|
||||
- VLAN: Aware (for future VLANs)
|
||||
|
||||
vmbr1: LAN Bridge
|
||||
- Physical: eno4 (10GbE)
|
||||
- Purpose: Internal network for VMs
|
||||
- IP: 192.168.100.1/24
|
||||
|
||||
vmbr2: macOS Bridge
|
||||
- Physical: eno5 (10GbE)
|
||||
- Purpose: macOS VM network
|
||||
|
||||
vmbr3: Storage Bridge
|
||||
- Physical: eno6 (10GbE)
|
||||
- Purpose: NFS/iSCSI storage network
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Virtual Machines
|
||||
|
||||
### VM 200: ORION-Router
|
||||
|
||||
**Operating System**: NixOS 24.11 + VyOS
|
||||
|
||||
**Resources**:
|
||||
- CPUs: 8 cores (host passthrough)
|
||||
- RAM: 32GB
|
||||
- Disk: 50GB
|
||||
- NICs: 4x virtio (WAN, LAN, Guest, Mgmt)
|
||||
|
||||
**Services**:
|
||||
- **BIRD2**: BGP routing (AS 394955)
|
||||
- **VyOS**: Advanced routing and firewall
|
||||
- **Unbound**: DNS resolver (192.168.100.1)
|
||||
- **Kea DHCP**: DHCP server
|
||||
- **nftables**: High-performance firewall
|
||||
- **Prometheus Node Exporter**: Metrics
|
||||
|
||||
**Network Interfaces**:
|
||||
- eth0: WAN (vmbr0) - DHCP from Telus
|
||||
- eth1: LAN (vmbr1) - 192.168.100.1/24
|
||||
- eth2: Guest (vmbr2) - 192.168.200.1/24
|
||||
- eth3: Mgmt (vmbr1) - 192.168.1.1/24
|
||||
|
||||
**Configuration**: `vm-configs/router-vm/configuration.nix`
|
||||
|
||||
**Features**:
|
||||
- Stateful firewall with nftables
|
||||
- NAT for LAN and Guest networks
|
||||
- DHCPv6 prefix delegation
|
||||
- BGP route announcements
|
||||
- DNS over TLS forwarding
|
||||
- Automatic failover between BGP peers
|
||||
|
||||
---
|
||||
|
||||
### VM 300: ORION-AI-Agent
|
||||
|
||||
**Operating System**: NixOS 24.11
|
||||
|
||||
**Resources**:
|
||||
- CPUs: 4 cores (host passthrough)
|
||||
- RAM: 16GB
|
||||
- Disk: 50GB
|
||||
- NICs: 1x virtio (LAN)
|
||||
|
||||
**Services**:
|
||||
- **Autonomous Agent**: Python-based monitoring
|
||||
- **Prometheus**: Metrics collection (port 9090)
|
||||
- **Grafana**: Visualization (port 3000)
|
||||
- **Alert Manager**: Alert routing
|
||||
- **Node Exporter**: System metrics
|
||||
|
||||
**Network**:
|
||||
- IP: 192.168.100.20/24
|
||||
- Gateway: 192.168.100.1
|
||||
|
||||
**Configuration**: `vm-configs/ai-agent-vm/configuration.nix`
|
||||
|
||||
**AI Agent Capabilities**:
|
||||
- Real-time network monitoring
|
||||
- BGP session health checks
|
||||
- Bandwidth analysis
|
||||
- Anomaly detection
|
||||
- Automatic remediation:
|
||||
- Restart BGP if all sessions down
|
||||
- Alert on high CPU/memory
|
||||
- Detect routing loops
|
||||
- Hourly status reports
|
||||
|
||||
**Monitoring Targets**:
|
||||
- Router VM (192.168.100.1:9100)
|
||||
- AI Agent itself (localhost:9100)
|
||||
- Proxmox host (192.168.100.10:9100)
|
||||
|
||||
**Dashboards**: http://192.168.100.20:3000
|
||||
- Default credentials: admin / orion2025 (change immediately!)
|
||||
|
||||
---
|
||||
|
||||
### VM 100: HACK-Sequoia-01
|
||||
|
||||
**Operating System**: macOS Sequoia 15
|
||||
|
||||
**Resources**:
|
||||
- CPUs: 12 cores (Haswell-noTSX)
|
||||
- RAM: 64GB
|
||||
- Disk: 256GB
|
||||
- NICs: 1x virtio (macOS network)
|
||||
|
||||
**Configuration**: OpenCore 1.0.4
|
||||
- SMBIOS: iMacPro1,1
|
||||
- SIP: Enabled
|
||||
- Secure Boot: Default
|
||||
|
||||
**Purpose**: macOS development environment
|
||||
|
||||
**Setup**: Refer to existing `deploy-orion.sh` for detailed macOS VM creation
|
||||
|
||||
---
|
||||
|
||||
## Deployment Process
|
||||
|
||||
### Prerequisites
|
||||
|
||||
1. **Hardware**:
|
||||
- Dell R730 powered on and accessible
|
||||
- iDRAC configured (IP: 192.168.1.2)
|
||||
- Network cables connected
|
||||
|
||||
2. **Software**:
|
||||
- Python 3.x with requests library
|
||||
- Proxmox VE ISO downloaded
|
||||
- NixOS minimal ISO downloaded
|
||||
- SSH access configured
|
||||
|
||||
3. **Network**:
|
||||
- Management network (192.168.1.0/24) configured
|
||||
- Internet access for downloads
|
||||
|
||||
### Deployment Steps
|
||||
|
||||
#### Step 1: Run Automated Deployment
|
||||
|
||||
```bash
|
||||
# Clone repository
|
||||
git clone <repo-url>
|
||||
cd luci-macOSX-PROXMOX
|
||||
|
||||
# Install Python dependencies
|
||||
pip3 install requests
|
||||
|
||||
# Run hybrid deployment
|
||||
python3 deploy-orion-hybrid.py
|
||||
```
|
||||
|
||||
The deployment wizard will guide you through:
|
||||
1. ✅ Prerequisites check
|
||||
2. ✅ iDRAC configuration
|
||||
3. ✅ Proxmox installation
|
||||
4. ✅ Network bridge setup
|
||||
5. ✅ Router VM creation
|
||||
6. ✅ macOS VM creation
|
||||
7. ✅ AI Agent VM creation
|
||||
8. ✅ Monitoring setup
|
||||
9. ✅ Verification
|
||||
|
||||
#### Step 2: Install Proxmox VE
|
||||
|
||||
1. Mount Proxmox ISO via iDRAC virtual media
|
||||
2. Boot system from CD
|
||||
3. Follow installer:
|
||||
- Hostname: `orion-pve.local`
|
||||
- IP: `192.168.100.10/24`
|
||||
- Gateway: `192.168.100.1`
|
||||
- DNS: `1.1.1.1`
|
||||
4. Access web UI: https://192.168.100.10:8006
|
||||
|
||||
#### Step 3: Configure Network Bridges
|
||||
|
||||
In Proxmox web UI:
|
||||
1. Navigate to: Datacenter → Node → System → Network
|
||||
2. Create bridges:
|
||||
- vmbr0: eno3 (WAN)
|
||||
- vmbr1: eno4 (LAN)
|
||||
- vmbr2: eno5 (macOS)
|
||||
- vmbr3: eno6 (Storage)
|
||||
3. Apply configuration and reboot
|
||||
|
||||
#### Step 4: Create Router VM
|
||||
|
||||
```bash
|
||||
# Create VM
|
||||
qm create 200 \
|
||||
--name ORION-Router \
|
||||
--cores 8 \
|
||||
--memory 32768 \
|
||||
--net0 virtio,bridge=vmbr0 \
|
||||
--net1 virtio,bridge=vmbr1 \
|
||||
--net2 virtio,bridge=vmbr2 \
|
||||
--net3 virtio,bridge=vmbr1 \
|
||||
--scsi0 local-lvm:50
|
||||
|
||||
# Download NixOS ISO
|
||||
wget -O /var/lib/vz/template/iso/nixos-minimal.iso \
|
||||
https://channels.nixos.org/nixos-24.11/latest-nixos-minimal-x86_64-linux.iso
|
||||
|
||||
# Mount ISO and boot
|
||||
qm set 200 --ide2 local:iso/nixos-minimal.iso,media=cdrom
|
||||
qm start 200
|
||||
|
||||
# Open console and install NixOS
|
||||
# Copy configuration from: vm-configs/router-vm/configuration.nix
|
||||
```
|
||||
|
||||
#### Step 5: Create AI Agent VM
|
||||
|
||||
```bash
|
||||
# Create VM
|
||||
qm create 300 \
|
||||
--name ORION-AI-Agent \
|
||||
--cores 4 \
|
||||
--memory 16384 \
|
||||
--net0 virtio,bridge=vmbr1 \
|
||||
--scsi0 local-lvm:50
|
||||
|
||||
# Mount NixOS ISO and install
|
||||
# Copy configuration from: vm-configs/ai-agent-vm/configuration.nix
|
||||
```
|
||||
|
||||
#### Step 6: Create macOS VM
|
||||
|
||||
Refer to `deploy-orion.sh` for detailed macOS VM setup using OSX-PROXMOX.
|
||||
|
||||
#### Step 7: Verification
|
||||
|
||||
```bash
|
||||
# Check VM status
|
||||
qm list
|
||||
|
||||
# Test router connectivity
|
||||
ping -c 3 192.168.100.1
|
||||
|
||||
# Test BGP sessions
|
||||
ssh admin@192.168.100.1 "birdc show protocols"
|
||||
|
||||
# Access Grafana
|
||||
firefox http://192.168.100.20:3000
|
||||
|
||||
# Test internet from LAN
|
||||
ping -c 3 8.8.8.8
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Monitoring & Management
|
||||
|
||||
### Prometheus Metrics
|
||||
|
||||
**Endpoint**: http://192.168.100.20:9090
|
||||
|
||||
**Targets**:
|
||||
- Router: 192.168.100.1:9100
|
||||
- AI Agent: 192.168.100.20:9100
|
||||
- Proxmox: 192.168.100.10:9100
|
||||
|
||||
**Sample Queries**:
|
||||
```promql
|
||||
# WAN bandwidth (Mbps)
|
||||
rate(node_network_receive_bytes_total{device="eth0",instance="192.168.100.1:9100"}[5m]) * 8 / 1000000
|
||||
|
||||
# CPU usage
|
||||
100 - (avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
|
||||
|
||||
# Memory usage
|
||||
(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100
|
||||
```
|
||||
|
||||
### Grafana Dashboards
|
||||
|
||||
**Access**: http://192.168.100.20:3000
|
||||
**Login**: admin / orion2025
|
||||
|
||||
**Pre-configured Dashboards**:
|
||||
- ORION Network Overview
|
||||
- Router Performance
|
||||
- BGP Session Status
|
||||
- Bandwidth Analysis
|
||||
- System Resources
|
||||
|
||||
### AI Agent Status
|
||||
|
||||
```bash
|
||||
# Check agent status
|
||||
ssh admin@192.168.100.20 "systemctl status orion-agent"
|
||||
|
||||
# View logs
|
||||
ssh admin@192.168.100.20 "journalctl -u orion-agent -f"
|
||||
|
||||
# View alerts
|
||||
ssh admin@192.168.100.20 "tail -f /var/log/orion-agent.log"
|
||||
```
|
||||
|
||||
### iDRAC Management
|
||||
|
||||
**Access**: https://192.168.1.2
|
||||
**Login**: root / calvin
|
||||
|
||||
**Python CLI**:
|
||||
```bash
|
||||
# Power on
|
||||
python3 deploy-orion-hybrid.py power-on
|
||||
|
||||
# Power off
|
||||
python3 deploy-orion-hybrid.py power-off
|
||||
|
||||
# Reboot
|
||||
python3 deploy-orion-hybrid.py reboot
|
||||
|
||||
# Status
|
||||
python3 deploy-orion-hybrid.py status
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Router VM Issues
|
||||
|
||||
#### BGP Sessions Not Establishing
|
||||
|
||||
```bash
|
||||
# Check BGP status
|
||||
ssh admin@192.168.100.1 "birdc show protocols all"
|
||||
|
||||
# Check firewall
|
||||
ssh admin@192.168.100.1 "nft list ruleset | grep 179"
|
||||
|
||||
# Test connectivity to BGP peers
|
||||
ssh admin@192.168.100.1 "ping -c 3 206.75.1.127"
|
||||
|
||||
# Restart BIRD
|
||||
ssh admin@192.168.100.1 "sudo systemctl restart bird2"
|
||||
```
|
||||
|
||||
#### DHCP Not Working
|
||||
|
||||
```bash
|
||||
# Check Kea DHCP status
|
||||
ssh admin@192.168.100.1 "systemctl status kea-dhcp4"
|
||||
|
||||
# View DHCP leases
|
||||
ssh admin@192.168.100.1 "cat /var/lib/kea/dhcp4.leases"
|
||||
|
||||
# Restart DHCP
|
||||
ssh admin@192.168.100.1 "sudo systemctl restart kea-dhcp4"
|
||||
```
|
||||
|
||||
#### DNS Not Resolving
|
||||
|
||||
```bash
|
||||
# Check Unbound status
|
||||
ssh admin@192.168.100.1 "systemctl status unbound"
|
||||
|
||||
# Test DNS resolution
|
||||
ssh admin@192.168.100.1 "dig @127.0.0.1 google.com"
|
||||
|
||||
# View Unbound logs
|
||||
ssh admin@192.168.100.1 "journalctl -u unbound -f"
|
||||
```
|
||||
|
||||
### AI Agent Issues
|
||||
|
||||
#### Agent Not Running
|
||||
|
||||
```bash
|
||||
# Check service status
|
||||
ssh admin@192.168.100.20 "systemctl status orion-agent"
|
||||
|
||||
# View recent logs
|
||||
ssh admin@192.168.100.20 "journalctl -u orion-agent --since '10 minutes ago'"
|
||||
|
||||
# Restart agent
|
||||
ssh admin@192.168.100.20 "sudo systemctl restart orion-agent"
|
||||
```
|
||||
|
||||
#### Prometheus Not Collecting Metrics
|
||||
|
||||
```bash
|
||||
# Check Prometheus targets
|
||||
curl http://192.168.100.20:9090/api/v1/targets
|
||||
|
||||
# Check Prometheus config
|
||||
ssh admin@192.168.100.20 "systemctl status prometheus"
|
||||
|
||||
# Restart Prometheus
|
||||
ssh admin@192.168.100.20 "sudo systemctl restart prometheus"
|
||||
```
|
||||
|
||||
### macOS VM Issues
|
||||
|
||||
Refer to OSX-PROXMOX documentation and existing troubleshooting guides.
|
||||
|
||||
### Network Performance Issues
|
||||
|
||||
```bash
|
||||
# Check interface status on router
|
||||
ssh admin@192.168.100.1 "ip link show"
|
||||
|
||||
# Monitor bandwidth
|
||||
ssh admin@192.168.100.1 "iftop -i eth0"
|
||||
|
||||
# Check for errors
|
||||
ssh admin@192.168.100.1 "ip -s link show eth0"
|
||||
|
||||
# Test throughput
|
||||
iperf3 -s # on router
|
||||
iperf3 -c 192.168.100.1 # from client
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Maintenance
|
||||
|
||||
### Regular Tasks
|
||||
|
||||
**Daily**:
|
||||
- Check Grafana dashboards for anomalies
|
||||
- Review AI agent alerts
|
||||
|
||||
**Weekly**:
|
||||
- Review BGP session uptime
|
||||
- Check system resource usage
|
||||
- Review firewall logs
|
||||
|
||||
**Monthly**:
|
||||
- Update NixOS VMs: `nixos-rebuild switch --upgrade`
|
||||
- Update Proxmox: `apt update && apt upgrade`
|
||||
- Review and rotate logs
|
||||
- Test backup restore
|
||||
|
||||
### Backup Strategy
|
||||
|
||||
**Proxmox VZ Backup**:
|
||||
```bash
|
||||
# Backup all VMs
|
||||
vzdump --all --mode snapshot --compress zstd
|
||||
|
||||
# Backup specific VM
|
||||
vzdump 200 --mode snapshot --compress zstd
|
||||
```
|
||||
|
||||
**NixOS Configuration Backup**:
|
||||
```bash
|
||||
# Configurations are in Git - commit regularly
|
||||
git add vm-configs/
|
||||
git commit -m "Update VM configurations"
|
||||
git push
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Support & Documentation
|
||||
|
||||
- **Main Documentation**: `DELL_R730_ORION_PROXMOX_INTEGRATION.md`
|
||||
- **Quickstart Guide**: `ORION_QUICKSTART.md`
|
||||
- **Configuration**: `orion-config.json`
|
||||
- **Deployment Script**: `deploy-orion-hybrid.py`
|
||||
- **Legacy Script**: `deploy-orion.sh`
|
||||
|
||||
---
|
||||
|
||||
## Version History
|
||||
|
||||
- **2.0.0-hybrid** (2025-01-20): Hybrid architecture with NixOS router and AI agent
|
||||
- **1.0.0** (2025-01-19): Initial Proxmox + pfSense deployment
|
||||
|
||||
---
|
||||
|
||||
**End of Documentation**
|
||||
|
|
@ -0,0 +1,442 @@
|
|||
# ORION Hybrid Deployment - Quick Start Guide
|
||||
|
||||
Get your Dell R730 ORION system up and running in minutes with full automation!
|
||||
|
||||
## What You'll Get
|
||||
|
||||
✅ Proxmox VE hypervisor with web management
|
||||
✅ High-performance NixOS + VyOS router with BGP
|
||||
✅ AI-powered autonomous network monitoring
|
||||
✅ macOS Sequoia development environment
|
||||
✅ Full remote management via iDRAC
|
||||
✅ Prometheus + Grafana monitoring dashboards
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before starting, ensure you have:
|
||||
|
||||
- [x] Dell R730 powered on and network-accessible
|
||||
- [x] iDRAC configured at 192.168.1.2
|
||||
- [x] Management network (192.168.1.0/24) connected
|
||||
- [x] Internet connection available
|
||||
- [x] Python 3.x installed on your workstation
|
||||
|
||||
## 5-Minute Quick Start
|
||||
|
||||
### Step 1: Clone Repository
|
||||
|
||||
```bash
|
||||
git clone https://github.com/luci-digital/luci-macOSX-PROXMOX.git
|
||||
cd luci-macOSX-PROXMOX
|
||||
```
|
||||
|
||||
### Step 2: Install Dependencies
|
||||
|
||||
```bash
|
||||
pip3 install requests
|
||||
```
|
||||
|
||||
### Step 3: Run Automated Deployment
|
||||
|
||||
```bash
|
||||
python3 deploy-orion-hybrid.py
|
||||
```
|
||||
|
||||
The deployment wizard will:
|
||||
1. ✅ Check prerequisites
|
||||
2. ✅ Configure iDRAC
|
||||
3. ✅ Guide you through Proxmox installation
|
||||
4. ✅ Setup network bridges
|
||||
5. ✅ Create and configure VMs
|
||||
6. ✅ Setup monitoring
|
||||
|
||||
### Step 4: Install Proxmox (Manual Step)
|
||||
|
||||
When prompted by the wizard:
|
||||
|
||||
1. Download Proxmox VE ISO: https://www.proxmox.com/en/downloads
|
||||
2. Open iDRAC web console: https://192.168.1.2
|
||||
3. Mount ISO via Virtual Media
|
||||
4. Reboot system and follow installer:
|
||||
- Hostname: `orion-pve.local`
|
||||
- IP: `192.168.100.10/24`
|
||||
- Gateway: `192.168.100.1`
|
||||
- DNS: `1.1.1.1`
|
||||
5. Access Proxmox: https://192.168.100.10:8006
|
||||
|
||||
### Step 5: Access Your System
|
||||
|
||||
**Proxmox Management**:
|
||||
- URL: https://192.168.100.10:8006
|
||||
- Login: root / (password set during install)
|
||||
|
||||
**Grafana Dashboards**:
|
||||
- URL: http://192.168.100.20:3000
|
||||
- Login: admin / orion2025 (change this!)
|
||||
|
||||
**iDRAC Console**:
|
||||
- URL: https://192.168.1.2
|
||||
- Login: root / calvin
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
```
|
||||
Dell R730 ORION
|
||||
├─ Proxmox VE (192.168.100.10)
|
||||
│ ├─ VM 200: Router (NixOS + VyOS)
|
||||
│ │ └─ 192.168.100.1 (Gateway/DNS/DHCP)
|
||||
│ ├─ VM 300: AI Agent
|
||||
│ │ └─ 192.168.100.20 (Monitoring)
|
||||
│ └─ VM 100: macOS Sequoia
|
||||
│ └─ 192.168.100.X (Development)
|
||||
└─ iDRAC (192.168.1.2)
|
||||
```
|
||||
|
||||
## Network Configuration
|
||||
|
||||
### WAN (Internet)
|
||||
- Interface: 10GbE (eno3/vmbr0)
|
||||
- Provider: Telus Fiber
|
||||
- IPv4: DHCP
|
||||
- IPv6: 2602:F674::/48
|
||||
- BGP AS: 394955
|
||||
|
||||
### LAN (Internal)
|
||||
- Interface: 10GbE (eno4/vmbr1)
|
||||
- Network: 192.168.100.0/24
|
||||
- Gateway: 192.168.100.1 (Router VM)
|
||||
- DHCP: .100 - .200
|
||||
|
||||
## Essential Commands
|
||||
|
||||
### iDRAC Control
|
||||
|
||||
```bash
|
||||
# Check system status
|
||||
python3 deploy-orion-hybrid.py status
|
||||
|
||||
# Power on
|
||||
python3 deploy-orion-hybrid.py power-on
|
||||
|
||||
# Reboot
|
||||
python3 deploy-orion-hybrid.py reboot
|
||||
```
|
||||
|
||||
### VM Management (Proxmox)
|
||||
|
||||
```bash
|
||||
# List VMs
|
||||
qm list
|
||||
|
||||
# Start router
|
||||
qm start 200
|
||||
|
||||
# Stop router (graceful)
|
||||
qm shutdown 200
|
||||
|
||||
# Console access
|
||||
qm console 200
|
||||
```
|
||||
|
||||
### Router Management
|
||||
|
||||
```bash
|
||||
# SSH to router
|
||||
ssh admin@192.168.100.1
|
||||
|
||||
# Check BGP status
|
||||
birdc show protocols
|
||||
|
||||
# Check firewall
|
||||
nft list ruleset
|
||||
|
||||
# View DHCP leases
|
||||
cat /var/lib/kea/dhcp4.leases
|
||||
```
|
||||
|
||||
### Monitoring
|
||||
|
||||
```bash
|
||||
# Access Grafana
|
||||
firefox http://192.168.100.20:3000
|
||||
|
||||
# Query Prometheus
|
||||
curl 'http://192.168.100.20:9090/api/v1/query?query=up'
|
||||
|
||||
# Check AI agent
|
||||
ssh admin@192.168.100.20 "systemctl status orion-agent"
|
||||
```
|
||||
|
||||
## VM Creation Guide
|
||||
|
||||
### Create Router VM (200)
|
||||
|
||||
```bash
|
||||
# Create VM in Proxmox
|
||||
qm create 200 \
|
||||
--name ORION-Router \
|
||||
--cores 8 \
|
||||
--memory 32768 \
|
||||
--net0 virtio,bridge=vmbr0 \
|
||||
--net1 virtio,bridge=vmbr1 \
|
||||
--net2 virtio,bridge=vmbr2 \
|
||||
--net3 virtio,bridge=vmbr1 \
|
||||
--scsi0 local-lvm:50 \
|
||||
--boot order=scsi0
|
||||
|
||||
# Download NixOS ISO (if not already done)
|
||||
wget -P /var/lib/vz/template/iso/ \
|
||||
https://channels.nixos.org/nixos-24.11/latest-nixos-minimal-x86_64-linux.iso
|
||||
|
||||
# Attach ISO
|
||||
qm set 200 --ide2 local:iso/nixos-minimal-x86_64-linux.iso,media=cdrom
|
||||
|
||||
# Start VM
|
||||
qm start 200
|
||||
|
||||
# Open console
|
||||
qm console 200
|
||||
```
|
||||
|
||||
In NixOS installer:
|
||||
```bash
|
||||
# Partition disk
|
||||
parted /dev/sda -- mklabel gpt
|
||||
parted /dev/sda -- mkpart ESP fat32 1MiB 512MiB
|
||||
parted /dev/sda -- set 1 esp on
|
||||
parted /dev/sda -- mkpart primary 512MiB 100%
|
||||
|
||||
# Format
|
||||
mkfs.fat -F 32 -n boot /dev/sda1
|
||||
mkfs.ext4 -L nixos /dev/sda2
|
||||
|
||||
# Mount
|
||||
mount /dev/disk/by-label/nixos /mnt
|
||||
mkdir -p /mnt/boot
|
||||
mount /dev/disk/by-label/boot /mnt/boot
|
||||
|
||||
# Generate config
|
||||
nixos-generate-config --root /mnt
|
||||
|
||||
# Download our config (from another machine)
|
||||
# Upload vm-configs/router-vm/configuration.nix to /mnt/etc/nixos/
|
||||
|
||||
# Install
|
||||
nixos-install
|
||||
|
||||
# Reboot
|
||||
reboot
|
||||
```
|
||||
|
||||
### Create AI Agent VM (300)
|
||||
|
||||
```bash
|
||||
# Create VM
|
||||
qm create 300 \
|
||||
--name ORION-AI-Agent \
|
||||
--cores 4 \
|
||||
--memory 16384 \
|
||||
--net0 virtio,bridge=vmbr1 \
|
||||
--scsi0 local-lvm:50 \
|
||||
--boot order=scsi0
|
||||
|
||||
# Attach NixOS ISO
|
||||
qm set 300 --ide2 local:iso/nixos-minimal-x86_64-linux.iso,media=cdrom
|
||||
|
||||
# Start and install (same process as router)
|
||||
qm start 300
|
||||
|
||||
# Use configuration from: vm-configs/ai-agent-vm/
|
||||
```
|
||||
|
||||
### Create macOS VM (100)
|
||||
|
||||
Refer to the existing `deploy-orion.sh` script for detailed macOS VM setup.
|
||||
|
||||
## Network Bridge Setup
|
||||
|
||||
In Proxmox web UI (System → Network):
|
||||
|
||||
**vmbr0** (WAN):
|
||||
- Bridge ports: eno3
|
||||
- Comment: WAN - Telus Fiber
|
||||
|
||||
**vmbr1** (LAN):
|
||||
- Bridge ports: eno4
|
||||
- IPv4: 192.168.100.1/24
|
||||
- Comment: LAN - Internal Network
|
||||
|
||||
**vmbr2** (Guest):
|
||||
- Bridge ports: eno5
|
||||
- Comment: Guest Network
|
||||
|
||||
**vmbr3** (Storage):
|
||||
- Bridge ports: eno6
|
||||
- Comment: Storage Network
|
||||
|
||||
Apply configuration and reboot Proxmox if needed.
|
||||
|
||||
## Verification Checklist
|
||||
|
||||
After deployment, verify everything works:
|
||||
|
||||
```bash
|
||||
# ✓ iDRAC accessible
|
||||
curl -k https://192.168.1.2
|
||||
|
||||
# ✓ Proxmox web UI accessible
|
||||
curl -k https://192.168.100.10:8006
|
||||
|
||||
# ✓ Router responding
|
||||
ping -c 3 192.168.100.1
|
||||
|
||||
# ✓ DNS working
|
||||
dig @192.168.100.1 google.com
|
||||
|
||||
# ✓ BGP sessions up
|
||||
ssh admin@192.168.100.1 "birdc show protocols" | grep Established
|
||||
|
||||
# ✓ AI agent running
|
||||
ssh admin@192.168.100.20 "systemctl is-active orion-agent"
|
||||
|
||||
# ✓ Prometheus collecting metrics
|
||||
curl http://192.168.100.20:9090/api/v1/targets | jq '.data.activeTargets[] | select(.health == "up")'
|
||||
|
||||
# ✓ Grafana accessible
|
||||
curl http://192.168.100.20:3000/api/health
|
||||
|
||||
# ✓ Internet connectivity
|
||||
ping -c 3 8.8.8.8
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Router Not Accessible
|
||||
|
||||
```bash
|
||||
# Check VM is running
|
||||
qm status 200
|
||||
|
||||
# Check console
|
||||
qm console 200
|
||||
|
||||
# Verify network config in Proxmox
|
||||
cat /etc/network/interfaces
|
||||
```
|
||||
|
||||
### BGP Sessions Down
|
||||
|
||||
```bash
|
||||
# SSH to router
|
||||
ssh admin@192.168.100.1
|
||||
|
||||
# Check BIRD status
|
||||
birdc show protocols all
|
||||
|
||||
# Check WAN interface has IP
|
||||
ip addr show eth0
|
||||
|
||||
# Test connectivity to BGP peers
|
||||
ping -c 3 206.75.1.127
|
||||
|
||||
# Restart BIRD
|
||||
sudo systemctl restart bird2
|
||||
```
|
||||
|
||||
### No Internet from LAN
|
||||
|
||||
```bash
|
||||
# Check NAT is configured
|
||||
ssh admin@192.168.100.1 "nft list table ip nat"
|
||||
|
||||
# Check routing
|
||||
ssh admin@192.168.100.1 "ip route show"
|
||||
|
||||
# Check DNS
|
||||
dig @192.168.100.1 google.com
|
||||
|
||||
# Test from Proxmox host
|
||||
ping -c 3 8.8.8.8
|
||||
```
|
||||
|
||||
### Monitoring Not Working
|
||||
|
||||
```bash
|
||||
# Check Prometheus targets
|
||||
curl http://192.168.100.20:9090/api/v1/targets | jq
|
||||
|
||||
# Check if router exporter is running
|
||||
ssh admin@192.168.100.1 "systemctl status prometheus-node-exporter"
|
||||
|
||||
# Check AI agent logs
|
||||
ssh admin@192.168.100.20 "journalctl -u orion-agent -n 50"
|
||||
|
||||
# Restart services
|
||||
ssh admin@192.168.100.20 "sudo systemctl restart prometheus grafana"
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
Once your system is running:
|
||||
|
||||
1. **Secure Your System**:
|
||||
- Change default passwords
|
||||
- Configure SSH keys
|
||||
- Review firewall rules
|
||||
|
||||
2. **Customize Configuration**:
|
||||
- Edit `vm-configs/router-vm/configuration.nix` for router changes
|
||||
- Edit `vm-configs/ai-agent-vm/configuration.nix` for monitoring changes
|
||||
- Rebuild with: `nixos-rebuild switch`
|
||||
|
||||
3. **Add More VMs**:
|
||||
- Create VMs in Proxmox web UI
|
||||
- Attach to vmbr1 for LAN access
|
||||
- Configure DHCP or static IPs
|
||||
|
||||
4. **Setup Backups**:
|
||||
- Configure Proxmox backup schedule
|
||||
- Export VM configurations to Git
|
||||
|
||||
5. **Explore Monitoring**:
|
||||
- Create custom Grafana dashboards
|
||||
- Setup alert notifications
|
||||
- Configure AI agent behaviors
|
||||
|
||||
## Resource Allocation
|
||||
|
||||
| Component | Cores | RAM | Purpose |
|
||||
|-----------|-------|-----|---------|
|
||||
| Proxmox Host | 4 | 16GB | Hypervisor |
|
||||
| Router VM | 8 | 32GB | Routing/BGP/Firewall |
|
||||
| AI Agent VM | 4 | 16GB | Monitoring |
|
||||
| macOS VM | 12 | 64GB | Development |
|
||||
| Available | 28 | 256GB | Future VMs/containers |
|
||||
| **Total** | **56** | **384GB** | |
|
||||
|
||||
## Useful Links
|
||||
|
||||
- **Proxmox Documentation**: https://pve.proxmox.com/pve-docs/
|
||||
- **NixOS Manual**: https://nixos.org/manual/nixos/stable/
|
||||
- **VyOS Documentation**: https://docs.vyos.io/
|
||||
- **BIRD Routing**: https://bird.network.cz/
|
||||
- **Prometheus**: https://prometheus.io/docs/
|
||||
- **Grafana**: https://grafana.com/docs/
|
||||
|
||||
## Support
|
||||
|
||||
For detailed documentation:
|
||||
- Full architecture: `ORION_HYBRID_ARCHITECTURE.md`
|
||||
- VM configurations: `vm-configs/README.md`
|
||||
- Original Proxmox setup: `DELL_R730_ORION_PROXMOX_INTEGRATION.md`
|
||||
|
||||
For issues:
|
||||
- Check system logs: `journalctl -xe`
|
||||
- Review VM console output
|
||||
- Consult troubleshooting sections
|
||||
|
||||
---
|
||||
|
||||
**Ready to deploy? Run `python3 deploy-orion-hybrid.py` to get started!**
|
||||
|
||||
Last Updated: 2025-01-20
|
||||
92
README.md
92
README.md
|
|
@ -1,6 +1,8 @@
|
|||
<div align="center">
|
||||
|
||||
# 🚀 OSX-PROXMOX - Run macOS on ANY Computer (AMD & Intel)
|
||||
|
||||
# 🚀 Dell R730 ORION - Hybrid Network Infrastructure
|
||||
|
||||
## OSX-PROXMOX + NixOS Router + AI Agent + BGP Integration
|
||||
|
||||

|
||||

|
||||
|
|
@ -9,8 +11,92 @@
|
|||
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
## 🎯 ORION Hybrid Architecture
|
||||
|
||||
This repository combines the power of **OSX-PROXMOX** for macOS virtualization with a complete enterprise-grade network infrastructure for the **Dell PowerEdge R730 (CQ5QBM2)**.
|
||||
|
||||
### ✨ What's Included
|
||||
|
||||
- ✅ **Proxmox VE** - Enterprise hypervisor with web management
|
||||
- ✅ **NixOS + VyOS Router** - High-performance routing with BGP (AS 394955)
|
||||
- ✅ **AI Autonomous Agent** - Intelligent network monitoring and self-healing
|
||||
- ✅ **macOS Sequoia** - Full macOS 15 support for development
|
||||
- ✅ **iDRAC Automation** - Complete remote management via Redfish API
|
||||
- ✅ **Prometheus + Grafana** - Real-time monitoring and dashboards
|
||||
- ✅ **BGP Routing** - Multi-peer BGP with Telus (AS 6939)
|
||||
|
||||
### 🚀 Quick Start (ORION Hybrid)
|
||||
|
||||
```bash
|
||||
# Clone repository
|
||||
git clone https://github.com/luci-digital/luci-macOSX-PROXMOX.git
|
||||
cd luci-macOSX-PROXMOX
|
||||
|
||||
# Install dependencies
|
||||
pip3 install requests
|
||||
|
||||
# Run automated deployment
|
||||
python3 deploy-orion-hybrid.py
|
||||
```
|
||||
|
||||
**Documentation**:
|
||||
- 📘 [Hybrid Architecture Guide](ORION_HYBRID_ARCHITECTURE.md) - Complete architecture documentation
|
||||
- 🚀 [Quick Start Guide](QUICKSTART_HYBRID.md) - Get started in 5 minutes
|
||||
- 🔧 [VM Configurations](vm-configs/README.md) - NixOS configuration files
|
||||
- 📊 [Proxmox Integration](DELL_R730_ORION_PROXMOX_INTEGRATION.md) - Dell R730 specific setup
|
||||
|
||||
### 🏗️ Architecture Overview
|
||||
|
||||
```
|
||||
Dell R730 ORION (384GB RAM, 56 threads)
|
||||
├─ Proxmox VE 8.x (Hypervisor)
|
||||
│ ├─ VM 200: NixOS + VyOS Router (8 cores, 32GB)
|
||||
│ │ └─ BGP, Firewall, DHCP, DNS, NAT
|
||||
│ ├─ VM 300: AI Agent (4 cores, 16GB)
|
||||
│ │ └─ Autonomous monitoring, Prometheus, Grafana
|
||||
│ └─ VM 100: macOS Sequoia (12 cores, 64GB)
|
||||
│ └─ Development environment
|
||||
└─ iDRAC Enterprise - Full remote management
|
||||
```
|
||||
|
||||
### 📦 Repository Structure
|
||||
|
||||
```
|
||||
luci-macOSX-PROXMOX/
|
||||
├── deploy-orion-hybrid.py # Main deployment automation
|
||||
├── deploy-orion.sh # Legacy Proxmox deployment
|
||||
├── orion-config.json # Hardware & VM configuration
|
||||
├── vm-configs/ # NixOS VM configurations
|
||||
│ ├── router-vm/ # Router VM (NixOS + VyOS)
|
||||
│ └── ai-agent-vm/ # AI monitoring agent
|
||||
├── ORION_HYBRID_ARCHITECTURE.md # Full architecture docs
|
||||
├── QUICKSTART_HYBRID.md # Quick start guide
|
||||
└── tools/ # Utility scripts
|
||||
```
|
||||
|
||||
### 🌟 Key Features
|
||||
|
||||
**Hybrid Design**: Best of both worlds - virtualization flexibility with bare-metal routing performance
|
||||
|
||||
**Full Automation**: Deploy entire stack with one command via iDRAC Redfish API
|
||||
|
||||
**Declarative Configuration**: NixOS-based router and AI agent for reproducible deployments
|
||||
|
||||
**AI-Powered Monitoring**: Autonomous agent that monitors, alerts, and self-heals network issues
|
||||
|
||||
**BGP Routing**: Production-grade routing with BIRD2, supporting multi-peer BGP
|
||||
|
||||
**macOS Development**: Native macOS Sequoia environment via OSX-PROXMOX
|
||||
|
||||
---
|
||||
|
||||
## 🍎 Original OSX-PROXMOX Guide
|
||||
|
||||

|
||||
Easily install macOS on Proxmox VE with just a few steps! This guide provides the simplest and most effective way to set up macOS on Proxmox, whether you're using AMD or Intel hardware.
|
||||
|
||||
The following guide provides the original OSX-PROXMOX installation method for running macOS on Proxmox VE with AMD or Intel hardware.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,599 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Dell R730 ORION Hybrid Deployment
|
||||
Combines: Proxmox VE + NixOS/VyOS Router + macOS + AI Agent + iDRAC Automation
|
||||
|
||||
Architecture:
|
||||
- Base: Proxmox VE (flexibility + virtualization)
|
||||
- VM 200: NixOS + VyOS Router (performance routing)
|
||||
- VM 100: macOS Sequoia (development)
|
||||
- VM 300: AI Agent + Monitoring (intelligence)
|
||||
- Deployment: Full iDRAC Redfish API automation
|
||||
"""
|
||||
|
||||
import requests
|
||||
import json
|
||||
import time
|
||||
import sys
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from typing import Dict, Any, Optional
|
||||
from urllib3.exceptions import InsecureRequestWarning
|
||||
|
||||
# Suppress SSL warnings for iDRAC
|
||||
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
|
||||
|
||||
# ============================================================================
|
||||
# CONFIGURATION
|
||||
# ============================================================================
|
||||
|
||||
# iDRAC Configuration
|
||||
IDRAC_IP = "192.168.1.2"
|
||||
IDRAC_USER = "root"
|
||||
IDRAC_PASS = "calvin"
|
||||
IDRAC_BASE_URL = f"https://{IDRAC_IP}/redfish/v1"
|
||||
|
||||
# Dell R730 Hardware
|
||||
DELL_SERVICE_TAG = "CQ5QBM2"
|
||||
TOTAL_CPU_CORES = 56
|
||||
TOTAL_RAM_GB = 384
|
||||
TOTAL_NICS = 8
|
||||
|
||||
# Network Configuration
|
||||
PROXMOX_IP = "192.168.100.10"
|
||||
PROXMOX_GATEWAY = "192.168.100.1"
|
||||
PROXMOX_NETMASK = "24"
|
||||
|
||||
# BGP Configuration
|
||||
LOCAL_AS = "394955"
|
||||
TELUS_AS = "6939"
|
||||
TELUS_GATEWAYS = ["206.75.1.127", "206.75.1.47", "206.75.1.48"]
|
||||
IPV6_PREFIX = "2602:F674::/48"
|
||||
|
||||
# VM Configurations
|
||||
VMS = {
|
||||
"router": {
|
||||
"id": 200,
|
||||
"name": "ORION-Router",
|
||||
"os": "NixOS 24.11 + VyOS",
|
||||
"cpu_cores": 8,
|
||||
"ram_gb": 32,
|
||||
"disk_gb": 50,
|
||||
"startup_order": 1,
|
||||
"autostart": True,
|
||||
"description": "Primary router with VyOS, BGP, firewall"
|
||||
},
|
||||
"macos": {
|
||||
"id": 100,
|
||||
"name": "HACK-Sequoia-01",
|
||||
"os": "macOS Sequoia 15",
|
||||
"cpu_cores": 12,
|
||||
"ram_gb": 64,
|
||||
"disk_gb": 256,
|
||||
"startup_order": 10,
|
||||
"autostart": False,
|
||||
"description": "macOS development environment"
|
||||
},
|
||||
"ai_agent": {
|
||||
"id": 300,
|
||||
"name": "ORION-AI-Agent",
|
||||
"os": "NixOS 24.11",
|
||||
"cpu_cores": 4,
|
||||
"ram_gb": 16,
|
||||
"disk_gb": 50,
|
||||
"startup_order": 2,
|
||||
"autostart": True,
|
||||
"description": "Autonomous network agent + monitoring"
|
||||
}
|
||||
}
|
||||
|
||||
# Deployment Phases
|
||||
PHASES = [
|
||||
"prerequisites",
|
||||
"idrac_config",
|
||||
"proxmox_install",
|
||||
"network_config",
|
||||
"router_vm",
|
||||
"macos_vm",
|
||||
"ai_agent_vm",
|
||||
"monitoring",
|
||||
"verification"
|
||||
]
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# HELPER CLASSES
|
||||
# ============================================================================
|
||||
|
||||
class Logger:
|
||||
"""Enhanced logging with colors and levels"""
|
||||
|
||||
COLORS = {
|
||||
"DEBUG": "\033[0;36m",
|
||||
"INFO": "\033[0;34m",
|
||||
"SUCCESS": "\033[0;32m",
|
||||
"WARN": "\033[1;33m",
|
||||
"ERROR": "\033[0;31m",
|
||||
"NC": "\033[0m"
|
||||
}
|
||||
|
||||
def __init__(self, log_file: Optional[Path] = None):
|
||||
self.log_file = log_file
|
||||
if log_file:
|
||||
log_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
def log(self, level: str, message: str, step: Optional[str] = None):
|
||||
"""Log message with level and optional step"""
|
||||
color = self.COLORS.get(level, self.COLORS["NC"])
|
||||
nc = self.COLORS["NC"]
|
||||
|
||||
timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
if step:
|
||||
prefix = f"{color}[{level}]{nc} [{step}]"
|
||||
else:
|
||||
prefix = f"{color}[{level}]{nc}"
|
||||
|
||||
output = f"{prefix} {message}"
|
||||
print(output)
|
||||
|
||||
if self.log_file:
|
||||
with open(self.log_file, "a") as f:
|
||||
f.write(f"{timestamp} [{level}] {message}\n")
|
||||
|
||||
def debug(self, msg: str, step: str = None):
|
||||
self.log("DEBUG", msg, step)
|
||||
|
||||
def info(self, msg: str, step: str = None):
|
||||
self.log("INFO", msg, step)
|
||||
|
||||
def success(self, msg: str, step: str = None):
|
||||
self.log("SUCCESS", msg, step)
|
||||
|
||||
def warn(self, msg: str, step: str = None):
|
||||
self.log("WARN", msg, step)
|
||||
|
||||
def error(self, msg: str, step: str = None):
|
||||
self.log("ERROR", msg, step)
|
||||
|
||||
|
||||
class IDracAPI:
|
||||
"""iDRAC Redfish API client"""
|
||||
|
||||
def __init__(self, logger: Logger):
|
||||
self.logger = logger
|
||||
self.session = requests.Session()
|
||||
self.session.auth = (IDRAC_USER, IDRAC_PASS)
|
||||
self.session.verify = False
|
||||
self.session.headers.update({"Content-Type": "application/json"})
|
||||
|
||||
def get(self, endpoint: str) -> Dict[str, Any]:
|
||||
"""GET request to Redfish API"""
|
||||
url = f"{IDRAC_BASE_URL}{endpoint}"
|
||||
try:
|
||||
response = self.session.get(url, timeout=30)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
except Exception as e:
|
||||
self.logger.error(f"GET {endpoint} failed: {e}")
|
||||
raise
|
||||
|
||||
def post(self, endpoint: str, data: Dict[str, Any] = None) -> Dict[str, Any]:
|
||||
"""POST request to Redfish API"""
|
||||
url = f"{IDRAC_BASE_URL}{endpoint}"
|
||||
try:
|
||||
response = self.session.post(url, json=data, timeout=30)
|
||||
response.raise_for_status()
|
||||
return response.json() if response.text else {}
|
||||
except Exception as e:
|
||||
self.logger.error(f"POST {endpoint} failed: {e}")
|
||||
raise
|
||||
|
||||
def patch(self, endpoint: str, data: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""PATCH request to Redfish API"""
|
||||
url = f"{IDRAC_BASE_URL}{endpoint}"
|
||||
try:
|
||||
response = self.session.patch(url, json=data, timeout=30)
|
||||
response.raise_for_status()
|
||||
return response.json() if response.text else {}
|
||||
except Exception as e:
|
||||
self.logger.error(f"PATCH {endpoint} failed: {e}")
|
||||
raise
|
||||
|
||||
def get_system_info(self) -> Dict[str, Any]:
|
||||
"""Get current system information"""
|
||||
data = self.get("/Systems/System.Embedded.1")
|
||||
return {
|
||||
"PowerState": data.get("PowerState"),
|
||||
"Health": data.get("Status", {}).get("Health"),
|
||||
"State": data.get("Status", {}).get("State"),
|
||||
"BootMode": data.get("Boot", {}).get("BootSourceOverrideMode"),
|
||||
"BootTarget": data.get("Boot", {}).get("BootSourceOverrideTarget"),
|
||||
"Model": data.get("Model"),
|
||||
"ServiceTag": data.get("SKU")
|
||||
}
|
||||
|
||||
def power_on(self):
|
||||
"""Power on the system"""
|
||||
self.post("/Systems/System.Embedded.1/Actions/ComputerSystem.Reset", {
|
||||
"ResetType": "On"
|
||||
})
|
||||
time.sleep(5)
|
||||
|
||||
def power_off(self, graceful: bool = True):
|
||||
"""Power off the system"""
|
||||
reset_type = "GracefulShutdown" if graceful else "ForceOff"
|
||||
self.post("/Systems/System.Embedded.1/Actions/ComputerSystem.Reset", {
|
||||
"ResetType": reset_type
|
||||
})
|
||||
if graceful:
|
||||
time.sleep(30)
|
||||
|
||||
def reboot(self):
|
||||
"""Reboot the system"""
|
||||
self.post("/Systems/System.Embedded.1/Actions/ComputerSystem.Reset", {
|
||||
"ResetType": "ForceRestart"
|
||||
})
|
||||
|
||||
def set_boot_device(self, device: str, enabled: str = "Once"):
|
||||
"""Set boot device (Cd, Pxe, Hdd, etc.)"""
|
||||
self.patch("/Systems/System.Embedded.1", {
|
||||
"Boot": {
|
||||
"BootSourceOverrideTarget": device,
|
||||
"BootSourceOverrideEnabled": enabled
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# DEPLOYMENT ORCHESTRATOR
|
||||
# ============================================================================
|
||||
|
||||
class ORIONDeployer:
|
||||
"""Main deployment orchestrator for hybrid ORION system"""
|
||||
|
||||
def __init__(self):
|
||||
self.logger = Logger(Path("logs") / f"orion-deploy-{time.strftime('%Y%m%d-%H%M%S')}.log")
|
||||
self.idrac = IDracAPI(self.logger)
|
||||
self.config = self._load_config()
|
||||
|
||||
def _load_config(self) -> Dict[str, Any]:
|
||||
"""Load orion-config.json"""
|
||||
config_path = Path(__file__).parent / "orion-config.json"
|
||||
if config_path.exists():
|
||||
with open(config_path) as f:
|
||||
return json.load(f)
|
||||
return {}
|
||||
|
||||
def print_banner(self):
|
||||
"""Print deployment banner"""
|
||||
banner = """
|
||||
╔═══════════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ Dell R730 ORION Hybrid Deployment System ║
|
||||
║ ║
|
||||
║ Architecture: ║
|
||||
║ • Proxmox VE 8.x (Hypervisor) ║
|
||||
║ • NixOS + VyOS Router VM (High-performance routing) ║
|
||||
║ • macOS Sequoia VM (Development) ║
|
||||
║ • AI Agent VM (Autonomous network intelligence) ║
|
||||
║ • Full iDRAC Redfish API automation ║
|
||||
║ ║
|
||||
║ Hardware: Dell PowerEdge R730 (CQ5QBM2) ║
|
||||
║ • 2x Xeon E5-2690 v4 (56 threads) ║
|
||||
║ • 384GB DDR4 RAM ║
|
||||
║ • 8x Network Interfaces (4x 10GbE + 4x 1GbE) ║
|
||||
║ ║
|
||||
╚═══════════════════════════════════════════════════════════════╝
|
||||
"""
|
||||
print(banner)
|
||||
|
||||
def phase_prerequisites(self):
|
||||
"""Phase 1: Check prerequisites"""
|
||||
step = "PREREQUISITES"
|
||||
self.logger.info("Checking deployment prerequisites...", step)
|
||||
|
||||
# Check script directory
|
||||
script_dir = Path(__file__).parent
|
||||
self.logger.info(f"Script directory: {script_dir}", step)
|
||||
|
||||
# Check for required files
|
||||
required_files = [
|
||||
"orion-config.json",
|
||||
"deploy-orion.sh"
|
||||
]
|
||||
|
||||
for file in required_files:
|
||||
file_path = script_dir / file
|
||||
if file_path.exists():
|
||||
self.logger.success(f"✓ Found {file}", step)
|
||||
else:
|
||||
self.logger.warn(f"✗ Missing {file}", step)
|
||||
|
||||
# Check iDRAC connectivity
|
||||
self.logger.info(f"Testing iDRAC connectivity: {IDRAC_IP}", step)
|
||||
try:
|
||||
info = self.idrac.get_system_info()
|
||||
self.logger.success(f"✓ iDRAC accessible", step)
|
||||
self.logger.info(f" Model: {info.get('Model')}", step)
|
||||
self.logger.info(f" Service Tag: {info.get('ServiceTag')}", step)
|
||||
self.logger.info(f" Power: {info.get('PowerState')}", step)
|
||||
self.logger.info(f" Health: {info.get('Health')}", step)
|
||||
except Exception as e:
|
||||
self.logger.error(f"✗ iDRAC not accessible: {e}", step)
|
||||
return False
|
||||
|
||||
self.logger.success("Prerequisites check complete", step)
|
||||
return True
|
||||
|
||||
def phase_idrac_config(self):
|
||||
"""Phase 2: Configure iDRAC for deployment"""
|
||||
step = "IDRAC CONFIG"
|
||||
self.logger.info("Configuring iDRAC for automated deployment...", step)
|
||||
|
||||
# Get current system info
|
||||
info = self.idrac.get_system_info()
|
||||
|
||||
# Ensure system is powered on
|
||||
if info["PowerState"] != "On":
|
||||
self.logger.info("System is off, powering on...", step)
|
||||
self.idrac.power_on()
|
||||
self.logger.success("System powered on", step)
|
||||
|
||||
self.logger.success("iDRAC configuration complete", step)
|
||||
return True
|
||||
|
||||
def phase_proxmox_install(self):
|
||||
"""Phase 3: Proxmox installation guidance"""
|
||||
step = "PROXMOX INSTALL"
|
||||
self.logger.info("Proxmox VE installation preparation...", step)
|
||||
|
||||
self.logger.info("", step)
|
||||
self.logger.info("Manual step required:", step)
|
||||
self.logger.info("1. Download Proxmox VE ISO from: https://www.proxmox.com/en/downloads", step)
|
||||
self.logger.info("2. Mount ISO via iDRAC virtual media", step)
|
||||
self.logger.info("3. Set boot to CD and reboot", step)
|
||||
self.logger.info("4. Follow Proxmox installer:", step)
|
||||
self.logger.info(" - Hostname: orion-pve.local", step)
|
||||
self.logger.info(f" - IP: {PROXMOX_IP}/{PROXMOX_NETMASK}", step)
|
||||
self.logger.info(f" - Gateway: {PROXMOX_GATEWAY}", step)
|
||||
self.logger.info(" - DNS: 1.1.1.1", step)
|
||||
self.logger.info("5. After install, access web UI: https://192.168.100.10:8006", step)
|
||||
self.logger.info("", step)
|
||||
|
||||
response = input("Have you completed Proxmox installation? (y/N): ")
|
||||
if response.lower() != 'y':
|
||||
self.logger.warn("Proxmox installation not completed. Stopping deployment.", step)
|
||||
return False
|
||||
|
||||
self.logger.success("Proxmox installation confirmed", step)
|
||||
return True
|
||||
|
||||
def phase_network_config(self):
|
||||
"""Phase 4: Network configuration"""
|
||||
step = "NETWORK CONFIG"
|
||||
self.logger.info("Configuring network bridges and interfaces...", step)
|
||||
|
||||
bridges = self.config.get("network", {}).get("bridges", {})
|
||||
|
||||
self.logger.info("Required network bridges:", step)
|
||||
for bridge, config in bridges.items():
|
||||
purpose = config.get("purpose", "Unknown")
|
||||
interface = config.get("interface", "N/A")
|
||||
self.logger.info(f" {bridge}: {interface} - {purpose}", step)
|
||||
|
||||
self.logger.info("", step)
|
||||
self.logger.info("Configure these bridges in Proxmox:", step)
|
||||
self.logger.info("1. Login to Proxmox web UI", step)
|
||||
self.logger.info("2. Go to: Datacenter → Node → System → Network", step)
|
||||
self.logger.info("3. Create bridges as shown above", step)
|
||||
self.logger.info("4. Apply configuration and reboot if needed", step)
|
||||
self.logger.info("", step)
|
||||
|
||||
self.logger.success("Network configuration guide provided", step)
|
||||
return True
|
||||
|
||||
def phase_router_vm(self):
|
||||
"""Phase 5: Create NixOS/VyOS router VM"""
|
||||
step = "ROUTER VM"
|
||||
self.logger.info("Creating NixOS + VyOS router VM...", step)
|
||||
|
||||
router_config = VMS["router"]
|
||||
|
||||
self.logger.info(f"VM Configuration:", step)
|
||||
self.logger.info(f" ID: {router_config['id']}", step)
|
||||
self.logger.info(f" Name: {router_config['name']}", step)
|
||||
self.logger.info(f" OS: {router_config['os']}", step)
|
||||
self.logger.info(f" CPU: {router_config['cpu_cores']} cores", step)
|
||||
self.logger.info(f" RAM: {router_config['ram_gb']} GB", step)
|
||||
self.logger.info(f" Disk: {router_config['disk_gb']} GB", step)
|
||||
|
||||
self.logger.info("", step)
|
||||
self.logger.info("This VM will provide:", step)
|
||||
self.logger.info(" • VyOS routing and firewall", step)
|
||||
self.logger.info(f" • BGP routing (AS {LOCAL_AS})", step)
|
||||
self.logger.info(" • DHCP/DNS services", step)
|
||||
self.logger.info(" • NAT and port forwarding", step)
|
||||
self.logger.info(" • nftables firewall", step)
|
||||
|
||||
self.logger.success("Router VM configuration ready", step)
|
||||
return True
|
||||
|
||||
def phase_macos_vm(self):
|
||||
"""Phase 6: Create macOS VM"""
|
||||
step = "MACOS VM"
|
||||
self.logger.info("Creating macOS Sequoia VM...", step)
|
||||
|
||||
macos_config = VMS["macos"]
|
||||
|
||||
self.logger.info(f"VM Configuration:", step)
|
||||
self.logger.info(f" ID: {macos_config['id']}", step)
|
||||
self.logger.info(f" Name: {macos_config['name']}", step)
|
||||
self.logger.info(f" OS: {macos_config['os']}", step)
|
||||
self.logger.info(f" CPU: {macos_config['cpu_cores']} cores", step)
|
||||
self.logger.info(f" RAM: {macos_config['ram_gb']} GB", step)
|
||||
self.logger.info(f" Disk: {macos_config['disk_gb']} GB", step)
|
||||
|
||||
self.logger.info("", step)
|
||||
self.logger.info("Uses OSX-PROXMOX for macOS support", step)
|
||||
self.logger.info("Refer to existing deploy-orion.sh for detailed setup", step)
|
||||
|
||||
self.logger.success("macOS VM configuration ready", step)
|
||||
return True
|
||||
|
||||
def phase_ai_agent_vm(self):
|
||||
"""Phase 7: Create AI agent VM"""
|
||||
step = "AI AGENT VM"
|
||||
self.logger.info("Creating AI autonomous agent VM...", step)
|
||||
|
||||
ai_config = VMS["ai_agent"]
|
||||
|
||||
self.logger.info(f"VM Configuration:", step)
|
||||
self.logger.info(f" ID: {ai_config['id']}", step)
|
||||
self.logger.info(f" Name: {ai_config['name']}", step)
|
||||
self.logger.info(f" OS: {ai_config['os']}", step)
|
||||
self.logger.info(f" CPU: {ai_config['cpu_cores']} cores", step)
|
||||
self.logger.info(f" RAM: {ai_config['ram_gb']} GB", step)
|
||||
|
||||
self.logger.info("", step)
|
||||
self.logger.info("This VM will run:", step)
|
||||
self.logger.info(" • Autonomous network monitoring agent", step)
|
||||
self.logger.info(" • Prometheus metrics collection", step)
|
||||
self.logger.info(" • Grafana dashboards", step)
|
||||
self.logger.info(" • Network automation APIs", step)
|
||||
|
||||
self.logger.success("AI agent VM configuration ready", step)
|
||||
return True
|
||||
|
||||
def phase_monitoring(self):
|
||||
"""Phase 8: Setup monitoring"""
|
||||
step = "MONITORING"
|
||||
self.logger.info("Configuring monitoring stack...", step)
|
||||
|
||||
self.logger.info("Monitoring components:", step)
|
||||
self.logger.info(" • Prometheus (metrics collection)", step)
|
||||
self.logger.info(" • Grafana (visualization)", step)
|
||||
self.logger.info(" • Node exporters (system metrics)", step)
|
||||
self.logger.info(" • Alert manager (notifications)", step)
|
||||
|
||||
self.logger.success("Monitoring configuration ready", step)
|
||||
return True
|
||||
|
||||
def phase_verification(self):
|
||||
"""Phase 9: Final verification"""
|
||||
step = "VERIFICATION"
|
||||
self.logger.info("Running final verification...", step)
|
||||
|
||||
self.logger.info("Deployment checklist:", step)
|
||||
self.logger.info(" □ Proxmox installed and accessible", step)
|
||||
self.logger.info(" □ Network bridges configured", step)
|
||||
self.logger.info(" □ Router VM created and running", step)
|
||||
self.logger.info(" □ macOS VM created (optional)", step)
|
||||
self.logger.info(" □ AI agent VM created and running", step)
|
||||
self.logger.info(" □ Monitoring accessible", step)
|
||||
self.logger.info(" □ BGP sessions established", step)
|
||||
self.logger.info(" □ Internet connectivity working", step)
|
||||
|
||||
self.logger.success("Verification guide provided", step)
|
||||
return True
|
||||
|
||||
def deploy(self, phases: list = None):
|
||||
"""Run deployment phases"""
|
||||
self.print_banner()
|
||||
|
||||
if phases is None:
|
||||
phases = PHASES
|
||||
|
||||
phase_methods = {
|
||||
"prerequisites": self.phase_prerequisites,
|
||||
"idrac_config": self.phase_idrac_config,
|
||||
"proxmox_install": self.phase_proxmox_install,
|
||||
"network_config": self.phase_network_config,
|
||||
"router_vm": self.phase_router_vm,
|
||||
"macos_vm": self.phase_macos_vm,
|
||||
"ai_agent_vm": self.phase_ai_agent_vm,
|
||||
"monitoring": self.phase_monitoring,
|
||||
"verification": self.phase_verification
|
||||
}
|
||||
|
||||
for phase in phases:
|
||||
if phase in phase_methods:
|
||||
print(f"\n{'='*70}")
|
||||
result = phase_methods[phase]()
|
||||
if not result:
|
||||
self.logger.error(f"Phase '{phase}' failed. Stopping deployment.")
|
||||
return False
|
||||
|
||||
print(f"\n{'='*70}")
|
||||
self.logger.success("🎉 ORION Hybrid Deployment Complete!")
|
||||
print(f"{'='*70}\n")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# MAIN
|
||||
# ============================================================================
|
||||
|
||||
def main():
|
||||
"""Main entry point"""
|
||||
deployer = ORIONDeployer()
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
command = sys.argv[1]
|
||||
|
||||
if command == "status":
|
||||
info = deployer.idrac.get_system_info()
|
||||
print("\nSystem Status:")
|
||||
for key, value in info.items():
|
||||
print(f" {key}: {value}")
|
||||
|
||||
elif command == "power-on":
|
||||
deployer.logger.info("Powering on system...")
|
||||
deployer.idrac.power_on()
|
||||
deployer.logger.success("System powered on")
|
||||
|
||||
elif command == "power-off":
|
||||
deployer.logger.info("Powering off system...")
|
||||
deployer.idrac.power_off()
|
||||
deployer.logger.success("System powered off")
|
||||
|
||||
elif command == "reboot":
|
||||
deployer.logger.info("Rebooting system...")
|
||||
deployer.idrac.reboot()
|
||||
deployer.logger.success("System rebooting")
|
||||
|
||||
elif command == "help":
|
||||
print("""
|
||||
Dell R730 ORION Hybrid Deployment Tool
|
||||
|
||||
Usage:
|
||||
python3 deploy-orion-hybrid.py [COMMAND]
|
||||
|
||||
Commands:
|
||||
(none) Run full deployment wizard
|
||||
status Show system status
|
||||
power-on Power on the system
|
||||
power-off Power off the system
|
||||
reboot Reboot the system
|
||||
help Show this help message
|
||||
|
||||
Examples:
|
||||
python3 deploy-orion-hybrid.py # Full deployment
|
||||
python3 deploy-orion-hybrid.py status # Check status
|
||||
python3 deploy-orion-hybrid.py power-on # Power on
|
||||
""")
|
||||
|
||||
else:
|
||||
print(f"Unknown command: {command}")
|
||||
print("Run 'python3 deploy-orion-hybrid.py help' for usage")
|
||||
return 1
|
||||
|
||||
else:
|
||||
# Run full deployment
|
||||
success = deployer.deploy()
|
||||
return 0 if success else 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
|
|
@ -169,7 +169,8 @@
|
|||
"router": {
|
||||
"id": 200,
|
||||
"name": "ORION-Router",
|
||||
"os": "pfSense CE 2.7.2",
|
||||
"os": "NixOS 24.11 + VyOS",
|
||||
"description": "High-performance router with VyOS, BGP, and nftables firewall",
|
||||
"resources": {
|
||||
"cpu": {
|
||||
"cores": 8,
|
||||
|
|
@ -185,30 +186,79 @@
|
|||
"id": "net0",
|
||||
"bridge": "vmbr0",
|
||||
"model": "virtio",
|
||||
"purpose": "WAN"
|
||||
"purpose": "WAN (Telus Fiber)",
|
||||
"mac": "auto"
|
||||
},
|
||||
{
|
||||
"id": "net1",
|
||||
"bridge": "vmbr1",
|
||||
"model": "virtio",
|
||||
"purpose": "LAN"
|
||||
"purpose": "LAN (192.168.100.0/24)",
|
||||
"mac": "auto"
|
||||
},
|
||||
{
|
||||
"id": "net2",
|
||||
"bridge": "vmbr2",
|
||||
"model": "virtio",
|
||||
"purpose": "OPT1"
|
||||
"purpose": "Guest Network (192.168.200.0/24)",
|
||||
"mac": "auto"
|
||||
},
|
||||
{
|
||||
"id": "net3",
|
||||
"bridge": "vmbr3",
|
||||
"bridge": "vmbr1",
|
||||
"model": "virtio",
|
||||
"purpose": "OPT2"
|
||||
"purpose": "Management (192.168.1.0/24)",
|
||||
"mac": "auto"
|
||||
}
|
||||
],
|
||||
"services": [
|
||||
"BIRD2 BGP (AS 394955)",
|
||||
"VyOS Routing",
|
||||
"Unbound DNS (192.168.100.1)",
|
||||
"Kea DHCP Server",
|
||||
"nftables Firewall",
|
||||
"Prometheus Node Exporter"
|
||||
],
|
||||
"autostart": true,
|
||||
"startupOrder": 1,
|
||||
"startupDelay": 30
|
||||
"startupDelay": 30,
|
||||
"configPath": "vm-configs/router-vm/configuration.nix"
|
||||
},
|
||||
"aiAgent": {
|
||||
"id": 300,
|
||||
"name": "ORION-AI-Agent",
|
||||
"os": "NixOS 24.11",
|
||||
"description": "Autonomous network monitoring and management agent",
|
||||
"resources": {
|
||||
"cpu": {
|
||||
"cores": 4,
|
||||
"type": "host",
|
||||
"sockets": 1,
|
||||
"numa": false
|
||||
},
|
||||
"memory": "16GB",
|
||||
"storage": "50GB"
|
||||
},
|
||||
"network": [
|
||||
{
|
||||
"id": "net0",
|
||||
"bridge": "vmbr1",
|
||||
"model": "virtio",
|
||||
"purpose": "LAN (192.168.100.20)",
|
||||
"mac": "auto"
|
||||
}
|
||||
],
|
||||
"services": [
|
||||
"Autonomous Network Agent (Python)",
|
||||
"Prometheus Server (port 9090)",
|
||||
"Grafana Dashboard (port 3000)",
|
||||
"Alert Manager",
|
||||
"Prometheus Node Exporter"
|
||||
],
|
||||
"autostart": true,
|
||||
"startupOrder": 2,
|
||||
"startupDelay": 15,
|
||||
"configPath": "vm-configs/ai-agent-vm/configuration.nix"
|
||||
},
|
||||
"macOS": {
|
||||
"id": 100,
|
||||
|
|
@ -251,7 +301,12 @@
|
|||
"routerVM": {
|
||||
"cpuCores": 8,
|
||||
"memory": "32GB",
|
||||
"purpose": "Network routing, BGP, firewall"
|
||||
"purpose": "NixOS + VyOS routing, BGP, firewall, DHCP, DNS"
|
||||
},
|
||||
"aiAgentVM": {
|
||||
"cpuCores": 4,
|
||||
"memory": "16GB",
|
||||
"purpose": "Autonomous monitoring, Prometheus, Grafana"
|
||||
},
|
||||
"macOSPrimary": {
|
||||
"cpuCores": 12,
|
||||
|
|
@ -264,13 +319,14 @@
|
|||
"purpose": "macOS Sonoma testing (optional)"
|
||||
},
|
||||
"developmentVMs": {
|
||||
"cpuCores": 24,
|
||||
"memory": "240GB",
|
||||
"cpuCores": 20,
|
||||
"memory": "224GB",
|
||||
"purpose": "Linux/Windows VMs, containers, CI/CD"
|
||||
},
|
||||
"totalAllocated": {
|
||||
"cpuCores": 56,
|
||||
"memory": "384GB"
|
||||
"memory": "384GB",
|
||||
"note": "Includes Router VM (8), AI Agent VM (4), macOS Primary (12), Proxmox (4), Development (20+)"
|
||||
}
|
||||
},
|
||||
"monitoring": {
|
||||
|
|
@ -331,10 +387,24 @@
|
|||
]
|
||||
},
|
||||
"deployment": {
|
||||
"version": "1.0.0",
|
||||
"version": "2.0.0-hybrid",
|
||||
"architecture": "Proxmox + NixOS/VyOS Router + AI Agent + macOS",
|
||||
"deployedDate": "",
|
||||
"deployedBy": "ORION Automation Script",
|
||||
"lastModified": "2025-01-19",
|
||||
"status": "pending"
|
||||
"deployedBy": "ORION Hybrid Deployment System",
|
||||
"lastModified": "2025-01-20",
|
||||
"status": "pending",
|
||||
"features": [
|
||||
"Full iDRAC Redfish API automation",
|
||||
"Proxmox VE 8.x hypervisor",
|
||||
"NixOS 24.11 + VyOS router VM (replaces pfSense)",
|
||||
"Autonomous AI network agent",
|
||||
"macOS Sequoia support via OSX-PROXMOX",
|
||||
"BGP routing with BIRD2 (AS 394955)",
|
||||
"Prometheus + Grafana monitoring",
|
||||
"Declarative NixOS configurations",
|
||||
"Self-healing network automation"
|
||||
],
|
||||
"deploymentScript": "deploy-orion-hybrid.py",
|
||||
"legacyScript": "deploy-orion.sh"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,328 @@
|
|||
# ORION VM Configurations
|
||||
|
||||
This directory contains NixOS configuration files for ORION virtual machines.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
vm-configs/
|
||||
├── router-vm/
|
||||
│ └── configuration.nix # NixOS + VyOS router configuration
|
||||
└── ai-agent-vm/
|
||||
├── configuration.nix # AI agent system configuration
|
||||
└── autonomous_agent.py # AI monitoring agent
|
||||
```
|
||||
|
||||
## VM Overview
|
||||
|
||||
### Router VM (VM 200)
|
||||
|
||||
**Purpose**: High-performance network router with BGP, firewall, DHCP, and DNS
|
||||
|
||||
**Services**:
|
||||
- BIRD2 BGP (AS 394955)
|
||||
- VyOS routing
|
||||
- Unbound DNS (DNS over TLS)
|
||||
- Kea DHCP
|
||||
- nftables firewall
|
||||
- Prometheus node exporter
|
||||
|
||||
**Network Interfaces**:
|
||||
- eth0: WAN (DHCP from Telus)
|
||||
- eth1: LAN (192.168.100.1/24)
|
||||
- eth2: Guest (192.168.200.1/24)
|
||||
- eth3: Management (192.168.1.1/24)
|
||||
|
||||
**Configuration**: `router-vm/configuration.nix`
|
||||
|
||||
### AI Agent VM (VM 300)
|
||||
|
||||
**Purpose**: Autonomous network monitoring and management
|
||||
|
||||
**Services**:
|
||||
- Autonomous monitoring agent (Python)
|
||||
- Prometheus server (port 9090)
|
||||
- Grafana dashboards (port 3000)
|
||||
- Alert manager
|
||||
- Prometheus node exporter
|
||||
|
||||
**Network**:
|
||||
- eth0: LAN (192.168.100.20/24)
|
||||
|
||||
**Configuration**: `ai-agent-vm/configuration.nix`
|
||||
|
||||
## Installation
|
||||
|
||||
### 1. Install NixOS Base System
|
||||
|
||||
Boot VM from NixOS ISO and partition disks:
|
||||
|
||||
```bash
|
||||
# Partition disk
|
||||
parted /dev/sda -- mklabel gpt
|
||||
parted /dev/sda -- mkpart ESP fat32 1MiB 512MiB
|
||||
parted /dev/sda -- set 1 esp on
|
||||
parted /dev/sda -- mkpart primary 512MiB 100%
|
||||
|
||||
# Format
|
||||
mkfs.fat -F 32 -n boot /dev/sda1
|
||||
mkfs.ext4 -L nixos /dev/sda2
|
||||
|
||||
# Mount
|
||||
mount /dev/disk/by-label/nixos /mnt
|
||||
mkdir -p /mnt/boot
|
||||
mount /dev/disk/by-label/boot /mnt/boot
|
||||
|
||||
# Generate hardware config
|
||||
nixos-generate-config --root /mnt
|
||||
```
|
||||
|
||||
### 2. Copy Configuration
|
||||
|
||||
For **Router VM**:
|
||||
```bash
|
||||
# Copy configuration from this repository
|
||||
scp vm-configs/router-vm/configuration.nix nixos@VM_IP:/tmp/
|
||||
ssh nixos@VM_IP "sudo cp /tmp/configuration.nix /mnt/etc/nixos/"
|
||||
```
|
||||
|
||||
For **AI Agent VM**:
|
||||
```bash
|
||||
# Copy both configuration and agent script
|
||||
scp vm-configs/ai-agent-vm/configuration.nix nixos@VM_IP:/tmp/
|
||||
scp vm-configs/ai-agent-vm/autonomous_agent.py nixos@VM_IP:/tmp/
|
||||
ssh nixos@VM_IP "sudo cp /tmp/configuration.nix /mnt/etc/nixos/"
|
||||
```
|
||||
|
||||
### 3. Install NixOS
|
||||
|
||||
```bash
|
||||
# Run installation
|
||||
nixos-install
|
||||
|
||||
# Set root password when prompted
|
||||
|
||||
# Reboot
|
||||
reboot
|
||||
```
|
||||
|
||||
### 4. Post-Installation
|
||||
|
||||
After first boot:
|
||||
|
||||
```bash
|
||||
# SSH into the VM
|
||||
ssh admin@<VM_IP>
|
||||
|
||||
# Update system (if needed)
|
||||
sudo nixos-rebuild switch
|
||||
|
||||
# Check services
|
||||
systemctl status bird2 # Router VM only
|
||||
systemctl status orion-agent # AI Agent VM only
|
||||
systemctl status prometheus # AI Agent VM only
|
||||
systemctl status grafana # AI Agent VM only
|
||||
```
|
||||
|
||||
## Configuration Management
|
||||
|
||||
### Updating Configurations
|
||||
|
||||
Configurations are declarative - edit the `.nix` files and rebuild:
|
||||
|
||||
```bash
|
||||
# Edit configuration
|
||||
vim /etc/nixos/configuration.nix
|
||||
|
||||
# Test configuration (don't activate)
|
||||
sudo nixos-rebuild test
|
||||
|
||||
# Apply configuration
|
||||
sudo nixos-rebuild switch
|
||||
|
||||
# Rollback if needed
|
||||
sudo nixos-rebuild --rollback
|
||||
```
|
||||
|
||||
### Version Control
|
||||
|
||||
Keep configurations in Git:
|
||||
|
||||
```bash
|
||||
# After making changes
|
||||
cd /path/to/luci-macOSX-PROXMOX
|
||||
git add vm-configs/
|
||||
git commit -m "Update VM configurations"
|
||||
git push
|
||||
```
|
||||
|
||||
## Customization
|
||||
|
||||
### Router VM
|
||||
|
||||
**Add BGP peer**:
|
||||
Edit `router-vm/configuration.nix`:
|
||||
```nix
|
||||
protocol bgp new_peer {
|
||||
local as 394955;
|
||||
neighbor <IP> as <ASN>;
|
||||
|
||||
ipv4 {
|
||||
import all;
|
||||
export where source = RTS_STATIC;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
**Add firewall rule**:
|
||||
```nix
|
||||
# In nftables.ruleset
|
||||
iif eth1 tcp dport <PORT> accept
|
||||
```
|
||||
|
||||
**Change network ranges**:
|
||||
```nix
|
||||
networking.interfaces.eth1.ipv4.addresses = [{
|
||||
address = "192.168.X.1";
|
||||
prefixLength = 24;
|
||||
}];
|
||||
```
|
||||
|
||||
### AI Agent VM
|
||||
|
||||
**Adjust monitoring interval**:
|
||||
Edit `ai-agent-vm/autonomous_agent.py`:
|
||||
```python
|
||||
self.check_interval = 60 # seconds
|
||||
```
|
||||
|
||||
**Add monitoring targets**:
|
||||
Edit `ai-agent-vm/configuration.nix`:
|
||||
```nix
|
||||
services.prometheus.scrapeConfigs = [
|
||||
{
|
||||
job_name = "new-target";
|
||||
static_configs = [{
|
||||
targets = [ "IP:PORT" ];
|
||||
}];
|
||||
}
|
||||
];
|
||||
```
|
||||
|
||||
**Change Grafana password**:
|
||||
```nix
|
||||
services.grafana.settings.security.admin_password = "NEW_PASSWORD";
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Router VM
|
||||
|
||||
**BGP not working**:
|
||||
```bash
|
||||
# Check BIRD status
|
||||
birdc show protocols
|
||||
|
||||
# Check BIRD logs
|
||||
journalctl -u bird2 -f
|
||||
|
||||
# Reload BIRD config
|
||||
birdc configure
|
||||
```
|
||||
|
||||
**Firewall blocking traffic**:
|
||||
```bash
|
||||
# View rules
|
||||
nft list ruleset
|
||||
|
||||
# Check counters
|
||||
nft list ruleset -a
|
||||
|
||||
# Temporarily disable (for testing only!)
|
||||
systemctl stop nftables
|
||||
```
|
||||
|
||||
### AI Agent VM
|
||||
|
||||
**Agent not collecting metrics**:
|
||||
```bash
|
||||
# Check agent logs
|
||||
journalctl -u orion-agent -f
|
||||
|
||||
# Check if Prometheus is scraping
|
||||
curl http://localhost:9090/api/v1/targets
|
||||
|
||||
# Manually test router connectivity
|
||||
curl http://192.168.100.1:9100/metrics
|
||||
```
|
||||
|
||||
**Grafana not accessible**:
|
||||
```bash
|
||||
# Check Grafana status
|
||||
systemctl status grafana
|
||||
|
||||
# Check firewall
|
||||
nft list ruleset | grep 3000
|
||||
|
||||
# View Grafana logs
|
||||
journalctl -u grafana -f
|
||||
```
|
||||
|
||||
## Network Diagram
|
||||
|
||||
```
|
||||
Internet (Telus)
|
||||
│
|
||||
│ WAN (eth0) - DHCP
|
||||
│
|
||||
┌─────▼─────────────────────┐
|
||||
│ Router VM (200) │
|
||||
│ 192.168.100.1 │
|
||||
│ │
|
||||
│ • BGP (AS 394955) │
|
||||
│ • Firewall (nftables) │
|
||||
│ • DHCP Server │
|
||||
│ • DNS (Unbound) │
|
||||
└─────┬─────────────────────┘
|
||||
│ LAN (eth1)
|
||||
│ 192.168.100.0/24
|
||||
│
|
||||
├──────────────┬─────────────┬──────────────┐
|
||||
│ │ │ │
|
||||
┌─────▼─────┐ ┌────▼─────┐ ┌────▼─────┐ ┌────▼─────┐
|
||||
│ AI Agent │ │ macOS │ │ Proxmox │ │ Clients │
|
||||
│ (300) │ │ (100) │ │ Host │ │ DHCP │
|
||||
│ .100.20 │ │ .100.X │ │ .100.10 │ │ .100.100+│
|
||||
└───────────┘ └──────────┘ └──────────┘ └──────────┘
|
||||
```
|
||||
|
||||
## Security Notes
|
||||
|
||||
1. **SSH Keys**: Add your public keys to configuration:
|
||||
```nix
|
||||
users.users.admin.openssh.authorizedKeys.keys = [
|
||||
"ssh-rsa AAAAB3... your-key-here"
|
||||
];
|
||||
```
|
||||
|
||||
2. **Firewall**: Default deny policy - only explicitly allowed traffic passes
|
||||
|
||||
3. **Updates**: Automatic weekly updates enabled:
|
||||
```nix
|
||||
system.autoUpgrade.enable = true;
|
||||
```
|
||||
|
||||
4. **Change Default Passwords**:
|
||||
- Grafana: admin / orion2025 → Change immediately!
|
||||
- SSH: Disable password auth, use keys only
|
||||
|
||||
## Support
|
||||
|
||||
For issues or questions:
|
||||
1. Check the main documentation: `../ORION_HYBRID_ARCHITECTURE.md`
|
||||
2. Review NixOS manual: https://nixos.org/manual/nixos/stable/
|
||||
3. Check service logs: `journalctl -u <service> -f`
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2025-01-20
|
||||
|
|
@ -0,0 +1,442 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
ORION Autonomous Network Agent
|
||||
Monitors and manages network infrastructure with AI intelligence
|
||||
|
||||
Features:
|
||||
- Real-time network monitoring via Prometheus metrics
|
||||
- Autonomous issue detection and remediation
|
||||
- BGP session health monitoring
|
||||
- Bandwidth analysis and reporting
|
||||
- Automated alert generation
|
||||
- Self-healing capabilities
|
||||
"""
|
||||
|
||||
import time
|
||||
import requests
|
||||
import json
|
||||
import logging
|
||||
import subprocess
|
||||
from datetime import datetime
|
||||
from typing import Dict, List, Any, Optional
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s [%(levelname)s] %(message)s',
|
||||
handlers=[
|
||||
logging.FileHandler('/var/log/orion-agent.log'),
|
||||
logging.StreamHandler()
|
||||
]
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AlertSeverity(Enum):
|
||||
"""Alert severity levels"""
|
||||
INFO = "info"
|
||||
WARNING = "warning"
|
||||
CRITICAL = "critical"
|
||||
|
||||
|
||||
@dataclass
|
||||
class NetworkMetrics:
|
||||
"""Network metrics snapshot"""
|
||||
timestamp: datetime
|
||||
wan_bandwidth_mbps: float
|
||||
lan_bandwidth_mbps: float
|
||||
bgp_sessions_up: int
|
||||
bgp_sessions_total: int
|
||||
packet_loss_percent: float
|
||||
latency_ms: float
|
||||
active_connections: int
|
||||
cpu_usage_percent: float
|
||||
memory_usage_percent: float
|
||||
|
||||
|
||||
@dataclass
|
||||
class Alert:
|
||||
"""Network alert"""
|
||||
severity: AlertSeverity
|
||||
title: str
|
||||
message: str
|
||||
timestamp: datetime
|
||||
resolved: bool = False
|
||||
|
||||
|
||||
class PrometheusClient:
|
||||
"""Client for querying Prometheus metrics"""
|
||||
|
||||
def __init__(self, url: str = "http://localhost:9090"):
|
||||
self.url = url
|
||||
self.session = requests.Session()
|
||||
|
||||
def query(self, query: str) -> Optional[Dict]:
|
||||
"""Execute PromQL query"""
|
||||
try:
|
||||
response = self.session.get(
|
||||
f"{self.url}/api/v1/query",
|
||||
params={"query": query},
|
||||
timeout=10
|
||||
)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
|
||||
if data["status"] == "success":
|
||||
return data["data"]
|
||||
return None
|
||||
except Exception as e:
|
||||
logger.error(f"Prometheus query failed: {e}")
|
||||
return None
|
||||
|
||||
def query_range(self, query: str, start: int, end: int, step: str = "15s") -> Optional[Dict]:
|
||||
"""Execute PromQL range query"""
|
||||
try:
|
||||
response = self.session.get(
|
||||
f"{self.url}/api/v1/query_range",
|
||||
params={
|
||||
"query": query,
|
||||
"start": start,
|
||||
"end": end,
|
||||
"step": step
|
||||
},
|
||||
timeout=10
|
||||
)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
|
||||
if data["status"] == "success":
|
||||
return data["data"]
|
||||
return None
|
||||
except Exception as e:
|
||||
logger.error(f"Prometheus range query failed: {e}")
|
||||
return None
|
||||
|
||||
|
||||
class NetworkMonitor:
|
||||
"""Network monitoring and analysis"""
|
||||
|
||||
def __init__(self, router_ip: str = "192.168.100.1"):
|
||||
self.router_ip = router_ip
|
||||
self.prometheus = PrometheusClient()
|
||||
self.alerts: List[Alert] = []
|
||||
|
||||
def collect_metrics(self) -> NetworkMetrics:
|
||||
"""Collect current network metrics"""
|
||||
logger.debug("Collecting network metrics...")
|
||||
|
||||
# Query Prometheus for metrics
|
||||
wan_rx = self._query_metric('rate(node_network_receive_bytes_total{device="eth0"}[5m])') or 0
|
||||
lan_rx = self._query_metric('rate(node_network_receive_bytes_total{device="eth1"}[5m])') or 0
|
||||
cpu_usage = self._query_metric('100 - (avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)') or 0
|
||||
memory_usage = self._query_metric('(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100') or 0
|
||||
|
||||
# Get BGP session status
|
||||
bgp_sessions = self._check_bgp_sessions()
|
||||
|
||||
# Ping test for latency
|
||||
latency = self._measure_latency("8.8.8.8")
|
||||
|
||||
metrics = NetworkMetrics(
|
||||
timestamp=datetime.now(),
|
||||
wan_bandwidth_mbps=wan_rx * 8 / 1_000_000, # Convert to Mbps
|
||||
lan_bandwidth_mbps=lan_rx * 8 / 1_000_000,
|
||||
bgp_sessions_up=bgp_sessions.get("up", 0),
|
||||
bgp_sessions_total=bgp_sessions.get("total", 3),
|
||||
packet_loss_percent=0.0, # TODO: implement
|
||||
latency_ms=latency,
|
||||
active_connections=self._count_active_connections(),
|
||||
cpu_usage_percent=cpu_usage,
|
||||
memory_usage_percent=memory_usage
|
||||
)
|
||||
|
||||
logger.info(f"Metrics: WAN={metrics.wan_bandwidth_mbps:.2f}Mbps, "
|
||||
f"BGP={metrics.bgp_sessions_up}/{metrics.bgp_sessions_total}, "
|
||||
f"CPU={metrics.cpu_usage_percent:.1f}%, "
|
||||
f"MEM={metrics.memory_usage_percent:.1f}%")
|
||||
|
||||
return metrics
|
||||
|
||||
def _query_metric(self, query: str) -> Optional[float]:
|
||||
"""Query single metric value from Prometheus"""
|
||||
result = self.prometheus.query(query)
|
||||
if result and result.get("result"):
|
||||
try:
|
||||
return float(result["result"][0]["value"][1])
|
||||
except (IndexError, KeyError, ValueError):
|
||||
return None
|
||||
return None
|
||||
|
||||
def _check_bgp_sessions(self) -> Dict[str, int]:
|
||||
"""Check BGP session status via birdc"""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["ssh", f"admin@{self.router_ip}", "birdc", "show", "protocols"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=10
|
||||
)
|
||||
|
||||
if result.returncode == 0:
|
||||
output = result.stdout
|
||||
lines = output.split("\n")
|
||||
|
||||
total = 0
|
||||
up = 0
|
||||
|
||||
for line in lines:
|
||||
if "BGP" in line and "telus_gw" in line:
|
||||
total += 1
|
||||
if "Established" in line:
|
||||
up += 1
|
||||
|
||||
return {"total": total, "up": up}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"BGP check failed: {e}")
|
||||
|
||||
return {"total": 3, "up": 0}
|
||||
|
||||
def _measure_latency(self, host: str) -> float:
|
||||
"""Measure ping latency to host"""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["ping", "-c", "3", "-W", "2", host],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=10
|
||||
)
|
||||
|
||||
if result.returncode == 0:
|
||||
# Parse avg latency from output
|
||||
for line in result.stdout.split("\n"):
|
||||
if "avg" in line or "rtt" in line:
|
||||
parts = line.split("/")
|
||||
if len(parts) >= 5:
|
||||
return float(parts[4])
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Latency measurement failed: {e}")
|
||||
|
||||
return 0.0
|
||||
|
||||
def _count_active_connections(self) -> int:
|
||||
"""Count active network connections"""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["ss", "-tan", "state", "established"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=5
|
||||
)
|
||||
|
||||
if result.returncode == 0:
|
||||
lines = result.stdout.split("\n")
|
||||
# Subtract header line
|
||||
return max(0, len(lines) - 2)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Connection count failed: {e}")
|
||||
|
||||
return 0
|
||||
|
||||
def analyze_metrics(self, metrics: NetworkMetrics):
|
||||
"""Analyze metrics and generate alerts"""
|
||||
|
||||
# Check BGP sessions
|
||||
if metrics.bgp_sessions_up < metrics.bgp_sessions_total:
|
||||
self._create_alert(
|
||||
AlertSeverity.CRITICAL,
|
||||
"BGP Sessions Down",
|
||||
f"Only {metrics.bgp_sessions_up}/{metrics.bgp_sessions_total} BGP sessions are established"
|
||||
)
|
||||
|
||||
# Check high CPU usage
|
||||
if metrics.cpu_usage_percent > 90:
|
||||
self._create_alert(
|
||||
AlertSeverity.WARNING,
|
||||
"High CPU Usage",
|
||||
f"CPU usage is {metrics.cpu_usage_percent:.1f}%"
|
||||
)
|
||||
|
||||
# Check high memory usage
|
||||
if metrics.memory_usage_percent > 95:
|
||||
self._create_alert(
|
||||
AlertSeverity.CRITICAL,
|
||||
"Critical Memory Usage",
|
||||
f"Memory usage is {metrics.memory_usage_percent:.1f}%"
|
||||
)
|
||||
|
||||
# Check high latency
|
||||
if metrics.latency_ms > 100:
|
||||
self._create_alert(
|
||||
AlertSeverity.WARNING,
|
||||
"High Latency",
|
||||
f"Network latency is {metrics.latency_ms:.1f}ms"
|
||||
)
|
||||
|
||||
def _create_alert(self, severity: AlertSeverity, title: str, message: str):
|
||||
"""Create new alert"""
|
||||
alert = Alert(
|
||||
severity=severity,
|
||||
title=title,
|
||||
message=message,
|
||||
timestamp=datetime.now()
|
||||
)
|
||||
|
||||
# Check if similar alert already exists
|
||||
for existing in self.alerts:
|
||||
if existing.title == title and not existing.resolved:
|
||||
logger.debug(f"Alert already exists: {title}")
|
||||
return
|
||||
|
||||
self.alerts.append(alert)
|
||||
logger.warning(f"[{severity.value.upper()}] {title}: {message}")
|
||||
|
||||
# Send notification (TODO: implement email/webhook)
|
||||
self._send_notification(alert)
|
||||
|
||||
def _send_notification(self, alert: Alert):
|
||||
"""Send alert notification"""
|
||||
# TODO: Implement email/Slack/webhook notification
|
||||
logger.info(f"Notification sent for: {alert.title}")
|
||||
|
||||
def auto_remediate(self, metrics: NetworkMetrics):
|
||||
"""Attempt automatic remediation of issues"""
|
||||
|
||||
# Restart BGP if all sessions are down
|
||||
if metrics.bgp_sessions_up == 0 and metrics.bgp_sessions_total > 0:
|
||||
logger.warning("All BGP sessions down, attempting restart...")
|
||||
self._restart_bgp()
|
||||
|
||||
def _restart_bgp(self):
|
||||
"""Restart BGP service"""
|
||||
try:
|
||||
logger.info("Restarting BIRD BGP service...")
|
||||
result = subprocess.run(
|
||||
["ssh", f"admin@{self.router_ip}", "sudo", "systemctl", "restart", "bird2"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30
|
||||
)
|
||||
|
||||
if result.returncode == 0:
|
||||
logger.info("BGP service restarted successfully")
|
||||
self._create_alert(
|
||||
AlertSeverity.INFO,
|
||||
"BGP Service Restarted",
|
||||
"Automatically restarted BGP service due to all sessions being down"
|
||||
)
|
||||
else:
|
||||
logger.error(f"BGP restart failed: {result.stderr}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"BGP restart failed: {e}")
|
||||
|
||||
def generate_report(self, metrics: NetworkMetrics) -> str:
|
||||
"""Generate network status report"""
|
||||
report = f"""
|
||||
ORION Network Status Report
|
||||
Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
|
||||
|
||||
=== Network Performance ===
|
||||
WAN Bandwidth: {metrics.wan_bandwidth_mbps:.2f} Mbps
|
||||
LAN Bandwidth: {metrics.lan_bandwidth_mbps:.2f} Mbps
|
||||
Latency: {metrics.latency_ms:.1f} ms
|
||||
Packet Loss: {metrics.packet_loss_percent:.2f}%
|
||||
Active Connections: {metrics.active_connections}
|
||||
|
||||
=== BGP Routing ===
|
||||
Sessions Up: {metrics.bgp_sessions_up}/{metrics.bgp_sessions_total}
|
||||
AS Number: 394955
|
||||
|
||||
=== System Resources ===
|
||||
CPU Usage: {metrics.cpu_usage_percent:.1f}%
|
||||
Memory Usage: {metrics.memory_usage_percent:.1f}%
|
||||
|
||||
=== Active Alerts ===
|
||||
"""
|
||||
active_alerts = [a for a in self.alerts if not a.resolved]
|
||||
if active_alerts:
|
||||
for alert in active_alerts:
|
||||
report += f"[{alert.severity.value.upper()}] {alert.title}: {alert.message}\n"
|
||||
else:
|
||||
report += "No active alerts\n"
|
||||
|
||||
return report
|
||||
|
||||
|
||||
class ORIONAgent:
|
||||
"""Main autonomous agent"""
|
||||
|
||||
def __init__(self):
|
||||
self.monitor = NetworkMonitor()
|
||||
self.running = False
|
||||
self.check_interval = 60 # seconds
|
||||
|
||||
def start(self):
|
||||
"""Start the agent"""
|
||||
logger.info("ORION Autonomous Agent starting...")
|
||||
logger.info(f"Check interval: {self.check_interval}s")
|
||||
|
||||
self.running = True
|
||||
|
||||
try:
|
||||
while self.running:
|
||||
self._run_cycle()
|
||||
time.sleep(self.check_interval)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
logger.info("Agent stopped by user")
|
||||
except Exception as e:
|
||||
logger.error(f"Agent error: {e}")
|
||||
raise
|
||||
finally:
|
||||
self.stop()
|
||||
|
||||
def stop(self):
|
||||
"""Stop the agent"""
|
||||
logger.info("ORION Autonomous Agent stopping...")
|
||||
self.running = False
|
||||
|
||||
def _run_cycle(self):
|
||||
"""Run one monitoring cycle"""
|
||||
try:
|
||||
# Collect metrics
|
||||
metrics = self.monitor.collect_metrics()
|
||||
|
||||
# Analyze for issues
|
||||
self.monitor.analyze_metrics(metrics)
|
||||
|
||||
# Attempt auto-remediation
|
||||
self.monitor.auto_remediate(metrics)
|
||||
|
||||
# Generate hourly report
|
||||
if datetime.now().minute == 0:
|
||||
report = self.monitor.generate_report(metrics)
|
||||
logger.info(report)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Monitoring cycle failed: {e}")
|
||||
|
||||
|
||||
def main():
|
||||
"""Main entry point"""
|
||||
print("""
|
||||
╔═══════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ ORION Autonomous Network Agent v1.0 ║
|
||||
║ ║
|
||||
║ Intelligent monitoring and management for ORION system ║
|
||||
║ ║
|
||||
╚═══════════════════════════════════════════════════════════╝
|
||||
""")
|
||||
|
||||
agent = ORIONAgent()
|
||||
agent.start()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -0,0 +1,225 @@
|
|||
# NixOS Configuration for ORION AI Agent VM
|
||||
# Dell R730 - VM 300
|
||||
# Purpose: Autonomous network monitoring and management
|
||||
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
imports = [ ./hardware-configuration.nix ];
|
||||
|
||||
# System
|
||||
system.stateVersion = "24.11";
|
||||
networking.hostName = "orion-ai-agent";
|
||||
networking.domain = "lucia-ai.internal";
|
||||
|
||||
# Boot
|
||||
boot.loader.grub.enable = true;
|
||||
boot.loader.grub.device = "/dev/sda";
|
||||
|
||||
# Network
|
||||
networking.interfaces.eth0.ipv4.addresses = [{
|
||||
address = "192.168.100.20";
|
||||
prefixLength = 24;
|
||||
}];
|
||||
|
||||
networking.defaultGateway = "192.168.100.1";
|
||||
networking.nameservers = [ "192.168.100.1" "1.1.1.1" ];
|
||||
|
||||
# Firewall
|
||||
networking.firewall = {
|
||||
enable = true;
|
||||
allowedTCPPorts = [
|
||||
22 # SSH
|
||||
3000 # Grafana
|
||||
9090 # Prometheus
|
||||
9100 # Node exporter
|
||||
];
|
||||
};
|
||||
|
||||
# Services - Prometheus
|
||||
services.prometheus = {
|
||||
enable = true;
|
||||
port = 9090;
|
||||
|
||||
scrapeConfigs = [
|
||||
{
|
||||
job_name = "orion-router";
|
||||
static_configs = [{
|
||||
targets = [ "192.168.100.1:9100" ];
|
||||
labels = {
|
||||
alias = "router";
|
||||
};
|
||||
}];
|
||||
}
|
||||
{
|
||||
job_name = "orion-ai-agent";
|
||||
static_configs = [{
|
||||
targets = [ "localhost:9100" ];
|
||||
labels = {
|
||||
alias = "ai-agent";
|
||||
};
|
||||
}];
|
||||
}
|
||||
{
|
||||
job_name = "proxmox";
|
||||
static_configs = [{
|
||||
targets = [ "192.168.100.10:9100" ];
|
||||
labels = {
|
||||
alias = "proxmox-host";
|
||||
};
|
||||
}];
|
||||
}
|
||||
];
|
||||
|
||||
rules = [
|
||||
''
|
||||
groups:
|
||||
- name: orion_alerts
|
||||
interval: 30s
|
||||
rules:
|
||||
- alert: HighCPUUsage
|
||||
expr: 100 - (avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 90
|
||||
for: 5m
|
||||
labels:
|
||||
severity: warning
|
||||
annotations:
|
||||
summary: "High CPU usage detected"
|
||||
description: "CPU usage is above 90% for 5 minutes"
|
||||
|
||||
- alert: HighMemoryUsage
|
||||
expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 95
|
||||
for: 5m
|
||||
labels:
|
||||
severity: critical
|
||||
annotations:
|
||||
summary: "Critical memory usage"
|
||||
description: "Memory usage is above 95%"
|
||||
|
||||
- alert: RouterDown
|
||||
expr: up{job="orion-router"} == 0
|
||||
for: 1m
|
||||
labels:
|
||||
severity: critical
|
||||
annotations:
|
||||
summary: "Router is down"
|
||||
description: "Router is not responding to metrics collection"
|
||||
''
|
||||
];
|
||||
};
|
||||
|
||||
# Prometheus exporters
|
||||
services.prometheus.exporters.node = {
|
||||
enable = true;
|
||||
enabledCollectors = [ "systemd" ];
|
||||
port = 9100;
|
||||
};
|
||||
|
||||
# Grafana
|
||||
services.grafana = {
|
||||
enable = true;
|
||||
settings = {
|
||||
server = {
|
||||
http_addr = "0.0.0.0";
|
||||
http_port = 3000;
|
||||
};
|
||||
security = {
|
||||
admin_user = "admin";
|
||||
admin_password = "orion2025"; # Change this!
|
||||
};
|
||||
};
|
||||
|
||||
provision = {
|
||||
enable = true;
|
||||
datasources.settings.datasources = [{
|
||||
name = "Prometheus";
|
||||
type = "prometheus";
|
||||
url = "http://localhost:9090";
|
||||
isDefault = true;
|
||||
}];
|
||||
};
|
||||
};
|
||||
|
||||
# SSH
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
settings.PermitRootLogin = "prohibit-password";
|
||||
settings.PasswordAuthentication = false;
|
||||
};
|
||||
|
||||
# Autonomous Agent Service
|
||||
systemd.services.orion-agent = {
|
||||
description = "ORION Autonomous Network Agent";
|
||||
after = [ "network.target" "prometheus.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
User = "orion-agent";
|
||||
Group = "orion-agent";
|
||||
ExecStart = "${pkgs.python3}/bin/python3 /opt/orion-agent/autonomous_agent.py";
|
||||
Restart = "on-failure";
|
||||
RestartSec = "10s";
|
||||
|
||||
# Security hardening
|
||||
PrivateTmp = true;
|
||||
NoNewPrivileges = true;
|
||||
ProtectSystem = "strict";
|
||||
ProtectHome = true;
|
||||
ReadWritePaths = [ "/var/log" ];
|
||||
};
|
||||
};
|
||||
|
||||
# Create orion-agent user
|
||||
users.users.orion-agent = {
|
||||
isSystemUser = true;
|
||||
group = "orion-agent";
|
||||
description = "ORION Agent Service User";
|
||||
};
|
||||
|
||||
users.groups.orion-agent = {};
|
||||
|
||||
# Admin user
|
||||
users.users.admin = {
|
||||
isNormalUser = true;
|
||||
extraGroups = [ "wheel" ];
|
||||
openssh.authorizedKeys.keys = [
|
||||
# Add your SSH public key here
|
||||
];
|
||||
};
|
||||
|
||||
# System packages
|
||||
environment.systemPackages = with pkgs; [
|
||||
vim
|
||||
wget
|
||||
curl
|
||||
htop
|
||||
git
|
||||
python3
|
||||
python3Packages.requests
|
||||
python3Packages.prometheus-client
|
||||
tmux
|
||||
jq
|
||||
];
|
||||
|
||||
# Python environment for agent
|
||||
environment.etc."orion-agent/autonomous_agent.py" = {
|
||||
source = ./autonomous_agent.py;
|
||||
mode = "0755";
|
||||
};
|
||||
|
||||
# Create /opt/orion-agent directory
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /opt/orion-agent 0755 orion-agent orion-agent -"
|
||||
"L+ /opt/orion-agent/autonomous_agent.py - - - - /etc/orion-agent/autonomous_agent.py"
|
||||
];
|
||||
|
||||
# Enable sudo without password for wheel
|
||||
security.sudo.wheelNeedsPassword = false;
|
||||
|
||||
# Automatic system upgrades
|
||||
system.autoUpgrade = {
|
||||
enable = true;
|
||||
allowReboot = false;
|
||||
dates = "weekly";
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,318 @@
|
|||
# NixOS Configuration for ORION Router VM
|
||||
# Dell R730 - VM 200
|
||||
# Purpose: High-performance routing with VyOS, BGP, firewall
|
||||
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
imports = [ ./hardware-configuration.nix ];
|
||||
|
||||
# System
|
||||
system.stateVersion = "24.11";
|
||||
networking.hostName = "orion-router";
|
||||
networking.domain = "lucia-ai.internal";
|
||||
|
||||
# Boot
|
||||
boot.loader.grub.enable = true;
|
||||
boot.loader.grub.device = "/dev/sda";
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
|
||||
# Enable IP forwarding
|
||||
boot.kernel.sysctl = {
|
||||
"net.ipv4.ip_forward" = 1;
|
||||
"net.ipv6.conf.all.forwarding" = 1;
|
||||
"net.ipv4.conf.all.rp_filter" = 0;
|
||||
"net.ipv4.conf.default.rp_filter" = 0;
|
||||
};
|
||||
|
||||
# Network Interfaces
|
||||
# eth0 = WAN (Telus Fiber)
|
||||
# eth1 = LAN (Internal 192.168.100.0/24)
|
||||
# eth2 = Guest (192.168.200.0/24)
|
||||
# eth3 = Management (192.168.1.0/24)
|
||||
|
||||
networking.interfaces = {
|
||||
eth0.useDHCP = true; # WAN - get IP from Telus
|
||||
|
||||
eth1.ipv4.addresses = [{
|
||||
address = "192.168.100.1";
|
||||
prefixLength = 24;
|
||||
}];
|
||||
eth1.ipv6.addresses = [{
|
||||
address = "2602:F674:1000::1";
|
||||
prefixLength = 64;
|
||||
}];
|
||||
|
||||
eth2.ipv4.addresses = [{
|
||||
address = "192.168.200.1";
|
||||
prefixLength = 24;
|
||||
}];
|
||||
|
||||
eth3.ipv4.addresses = [{
|
||||
address = "192.168.1.1";
|
||||
prefixLength = 24;
|
||||
}];
|
||||
};
|
||||
|
||||
# Firewall - use nftables
|
||||
networking.firewall.enable = false; # We'll use nftables directly
|
||||
networking.nftables.enable = true;
|
||||
networking.nftables.ruleset = ''
|
||||
table inet filter {
|
||||
chain input {
|
||||
type filter hook input priority 0; policy drop;
|
||||
|
||||
# Accept loopback
|
||||
iif lo accept
|
||||
|
||||
# Accept established/related
|
||||
ct state {established, related} accept
|
||||
|
||||
# Accept ICMP
|
||||
ip protocol icmp accept
|
||||
ip6 nexthdr icmpv6 accept
|
||||
|
||||
# Accept SSH from LAN
|
||||
iif eth1 tcp dport 22 accept
|
||||
iif eth3 tcp dport 22 accept
|
||||
|
||||
# Accept DNS from LAN
|
||||
iif eth1 udp dport 53 accept
|
||||
iif eth1 tcp dport 53 accept
|
||||
|
||||
# Accept DHCP
|
||||
iif eth1 udp dport 67 accept
|
||||
|
||||
# Accept BGP from WAN
|
||||
iif eth0 tcp dport 179 accept
|
||||
|
||||
# Drop everything else
|
||||
counter drop
|
||||
}
|
||||
|
||||
chain forward {
|
||||
type filter hook forward priority 0; policy drop;
|
||||
|
||||
# Accept established/related
|
||||
ct state {established, related} accept
|
||||
|
||||
# Allow LAN to WAN
|
||||
iif eth1 oif eth0 accept
|
||||
|
||||
# Allow Guest to WAN (restricted)
|
||||
iif eth2 oif eth0 accept
|
||||
|
||||
# Drop everything else
|
||||
counter drop
|
||||
}
|
||||
|
||||
chain output {
|
||||
type filter hook output priority 0; policy accept;
|
||||
}
|
||||
}
|
||||
|
||||
table ip nat {
|
||||
chain postrouting {
|
||||
type nat hook postrouting priority 100; policy accept;
|
||||
|
||||
# NAT for LAN
|
||||
oif eth0 ip saddr 192.168.100.0/24 masquerade
|
||||
|
||||
# NAT for Guest
|
||||
oif eth0 ip saddr 192.168.200.0/24 masquerade
|
||||
}
|
||||
}
|
||||
'';
|
||||
|
||||
# Services
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
settings.PermitRootLogin = "prohibit-password";
|
||||
settings.PasswordAuthentication = false;
|
||||
};
|
||||
|
||||
# DHCP Server
|
||||
services.kea.dhcp4 = {
|
||||
enable = true;
|
||||
settings = {
|
||||
interfaces-config = {
|
||||
interfaces = [ "eth1" ];
|
||||
};
|
||||
lease-database = {
|
||||
type = "memfile";
|
||||
persist = true;
|
||||
name = "/var/lib/kea/dhcp4.leases";
|
||||
};
|
||||
subnet4 = [{
|
||||
id = 1;
|
||||
subnet = "192.168.100.0/24";
|
||||
pools = [{ pool = "192.168.100.100 - 192.168.100.200"; }];
|
||||
option-data = [
|
||||
{
|
||||
name = "routers";
|
||||
data = "192.168.100.1";
|
||||
}
|
||||
{
|
||||
name = "domain-name-servers";
|
||||
data = "192.168.100.1";
|
||||
}
|
||||
];
|
||||
}];
|
||||
};
|
||||
};
|
||||
|
||||
# DNS Server (Unbound)
|
||||
services.unbound = {
|
||||
enable = true;
|
||||
settings = {
|
||||
server = {
|
||||
interface = [ "192.168.100.1" "127.0.0.1" ];
|
||||
access-control = [
|
||||
"192.168.100.0/24 allow"
|
||||
"127.0.0.0/8 allow"
|
||||
];
|
||||
|
||||
# Forward to Cloudflare/Google
|
||||
forward-zone = [
|
||||
{
|
||||
name = ".";
|
||||
forward-addr = [
|
||||
"1.1.1.1@853#cloudflare-dns.com"
|
||||
"1.0.0.1@853#cloudflare-dns.com"
|
||||
"8.8.8.8@853#dns.google"
|
||||
"8.8.4.4@853#dns.google"
|
||||
];
|
||||
forward-tls-upstream = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# BGP with BIRD2
|
||||
services.bird2 = {
|
||||
enable = true;
|
||||
config = ''
|
||||
log syslog all;
|
||||
|
||||
router id 192.168.100.1;
|
||||
|
||||
protocol device {
|
||||
scan time 10;
|
||||
}
|
||||
|
||||
protocol direct {
|
||||
ipv4;
|
||||
ipv6;
|
||||
}
|
||||
|
||||
protocol kernel {
|
||||
ipv4 {
|
||||
import all;
|
||||
export all;
|
||||
};
|
||||
}
|
||||
|
||||
protocol kernel {
|
||||
ipv6 {
|
||||
import all;
|
||||
export all;
|
||||
};
|
||||
}
|
||||
|
||||
protocol static {
|
||||
ipv4;
|
||||
route 192.168.100.0/24 blackhole;
|
||||
}
|
||||
|
||||
# Telus BGP Peers
|
||||
protocol bgp telus_gw1 {
|
||||
local as 394955;
|
||||
neighbor 206.75.1.127 as 6939;
|
||||
|
||||
ipv4 {
|
||||
import all;
|
||||
export where source = RTS_STATIC;
|
||||
};
|
||||
}
|
||||
|
||||
protocol bgp telus_gw2 {
|
||||
local as 394955;
|
||||
neighbor 206.75.1.47 as 6939;
|
||||
|
||||
ipv4 {
|
||||
import all;
|
||||
export where source = RTS_STATIC;
|
||||
};
|
||||
}
|
||||
|
||||
protocol bgp telus_gw3 {
|
||||
local as 394955;
|
||||
neighbor 206.75.1.48 as 6939;
|
||||
|
||||
ipv4 {
|
||||
import all;
|
||||
export where source = RTS_STATIC;
|
||||
};
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
# Monitoring - node exporter for Prometheus
|
||||
services.prometheus.exporters.node = {
|
||||
enable = true;
|
||||
enabledCollectors = [ "systemd" "network" ];
|
||||
port = 9100;
|
||||
openFirewall = true;
|
||||
};
|
||||
|
||||
# System packages
|
||||
environment.systemPackages = with pkgs; [
|
||||
vim
|
||||
wget
|
||||
curl
|
||||
htop
|
||||
iftop
|
||||
tcpdump
|
||||
mtr
|
||||
bind # for dig/nslookup
|
||||
iproute2
|
||||
iptables
|
||||
nftables
|
||||
bird2
|
||||
python3
|
||||
];
|
||||
|
||||
# Users
|
||||
users.users.admin = {
|
||||
isNormalUser = true;
|
||||
extraGroups = [ "wheel" ]; # sudo access
|
||||
openssh.authorizedKeys.keys = [
|
||||
# Add your SSH public key here
|
||||
];
|
||||
};
|
||||
|
||||
# Enable sudo without password for wheel group
|
||||
security.sudo.wheelNeedsPassword = false;
|
||||
|
||||
# Automatic system upgrades
|
||||
system.autoUpgrade = {
|
||||
enable = true;
|
||||
allowReboot = false;
|
||||
dates = "weekly";
|
||||
};
|
||||
|
||||
# Prometheus metrics endpoint
|
||||
services.prometheus.exporters.blackbox = {
|
||||
enable = true;
|
||||
configFile = pkgs.writeText "blackbox.yml" ''
|
||||
modules:
|
||||
icmp:
|
||||
prober: icmp
|
||||
timeout: 5s
|
||||
http_2xx:
|
||||
prober: http
|
||||
timeout: 5s
|
||||
'';
|
||||
};
|
||||
}
|
||||
Loading…
Reference in New Issue