# SuzieQ Integration - Multi-Vendor Drift Detection ## Overview SuzieQ is an open-source network observability framework that provides multi-vendor state collection, topology discovery, and historical analysis. Overgrowth integrates SuzieQ for **continuous drift detection** - comparing actual network state against intended state (NetBox SoT) and automatically generating remediation plans. ### What is Configuration Drift? Configuration drift occurs when the actual network state diverges from the intended state defined in your source of truth (SoT). Common causes: - Manual changes made directly on devices - Failed automation runs leaving partial configs - Hardware failures requiring emergency workarounds - Shadow IT adding unauthorized VLANs/subnets - Config erosion over time ### Why SuzieQ? | Feature | SuzieQ | Traditional Monitoring | |---------|--------|----------------------| | **Multi-vendor** | ✅ Arista, Cisco, Juniper, Cumulus, etc. | ❌ Vendor-specific | | **Agentless** | ✅ SSH-based collection | ❌ Requires agents | | **Historical data** | ✅ Parquet files for time-travel | ❌ Limited retention | | **Topology discovery** | ✅ LLDP/CDP-based | ❌ Manual mapping | | **Open source** | ✅ Apache 2.0 | ❌ Commercial | ## Architecture ``` ┌─────────────────────────────────────────────────────────────┐ │ Overgrowth Pipeline │ │ ┌─────────────┐ ┌──────────────┐ ┌──────────────────┐ │ │ │ NetBox │→ │ SuzieQ │→ │ Drift Detection │ │ │ │ (SoT) │ │ Collector │ │ & Remediation │ │ │ └─────────────┘ └──────────────┘ └──────────────────┘ │ └─────────────────────────────────────────────────────────────┘ ↓ ↓ ↓ Intended State Actual State Drift Analysis ┌────────────────────────────────────────────────────────────┐ │ Stage 7: Observability - Collect actual network state │ │ Stage 7b: Drift Detection - Compare actual vs intended │ │ Stage 8: Validation - Auto-remediate approved changes │ └────────────────────────────────────────────────────────────┘ ``` ## What SuzieQ Detects ### 1. Configuration Mismatches - Device hostname changes - Management IP changes - Unexpected device roles (leaf acting as spine) ### 2. VLAN Drift - **Missing VLANs**: Intended in SoT but not on device - **Extra VLANs**: Present on device but not in SoT - VLAN name mismatches ### 3. IP Address Conflicts - Duplicate IPs across devices - IP mismatches vs NetBox IPAM - Gateway conflicts ### 4. Interface State Drift - Interfaces expected UP but actually DOWN - Interfaces expected DOWN but actually UP - Description mismatches ### 5. Routing Issues - BGP neighbor states - OSPF adjacency problems - Route count anomalies ## Usage Examples ### Basic Drift Detection ```python from agent.pipeline_engine import OvergrowthPipeline from agent.network_model import NetworkModel # Create pipeline with SuzieQ enabled pipeline = OvergrowthPipeline() # Your network model (from NetBox or YAML) model = NetworkModel(...) # Stage 7: Collect actual state obs_results = pipeline.stage7_observability(model) print(f"Collected state from {obs_results['collection']['devices_polled']} devices") # Stage 7b: Detect drift drift_results = pipeline.stage7b_drift_detection(model) if drift_results['drift_detected']: print(f"⚠️ Drift detected! Score: {drift_results['drift_score']:.2f}") print(f"Issues found:") print(f" - Config mismatches: {drift_results['summary']['config_mismatches']}") print(f" - Missing VLANs: {drift_results['summary']['missing_vlans']}") print(f" - Interface issues: {drift_results['summary']['interfaces_down']}") else: print("✓ No drift - network matches SoT") ``` ### Auto-Remediation ```python # Stage 8: Validate and auto-remediate validation = pipeline.stage8_validation(model) compliance = validation['compliance_report'] print(f"Compliance Status: {compliance['status']}") print(f"Drift Score: {compliance['drift_score']:.2f}") if 'remediation' in validation: print(f"Applied {validation['remediation']['applied']} automatic fixes") print(f"Skipped {validation['remediation']['skipped']} (require manual approval)") ``` ### Direct SuzieQ Client Usage ```python from agent.suzieq_client import SuzieQClient # Initialize client suzieq = SuzieQClient(use_suzieq=True) # Collect state from devices devices = [ {'name': 'leaf-01', 'ip': '10.0.0.11', 'username': 'admin', 'password': 'admin'}, {'name': 'spine-01', 'ip': '10.0.0.1', 'username': 'admin', 'password': 'admin'} ] collection = suzieq.collect_network_state(devices) print(f"Collected from {collection['devices_polled']} devices") # Get topology topology = suzieq.get_topology() print(f"Discovered {len(topology['nodes'])} nodes") print(f"Found {len(topology['edges'])} LLDP/CDP connections") # Get VLAN summary vlans = suzieq.get_vlan_summary() for device, vlan_list in vlans.items(): print(f"{device}: {vlan_list}") # Detect drift intended_state = { 'devices': [...], 'vlans': [...], 'subnets': [...] } drift = suzieq.detect_drift(intended_state) if drift.has_drift: print(f"Drift Score: {drift.drift_score:.2f}") print(f"Missing VLANs: {len(drift.missing_vlans)}") print(f"Extra VLANs: {len(drift.extra_vlans)}") # Generate remediation plan plan = suzieq.generate_remediation_plan(drift) for action in plan: status = "AUTO-FIX" if action['auto_fix'] else "MANUAL" print(f"[{status}] {action['action']} on {action['device']}") print(f" Commands: {action['commands']}") # Apply auto-approved fixes results = suzieq.apply_remediation(plan, auto_approve=True) print(f"Applied: {results['applied']}, Skipped: {results['skipped']}") ``` ## Remediation Safety ### Auto-Fix vs Manual Approval SuzieQ classifies remediation actions by safety: | Action | Auto-Fix | Reason | |--------|----------|--------| | **Add missing VLAN** | ✅ Yes | Safe - doesn't disrupt traffic | | **Remove extra VLAN** | ❌ No | Dangerous - could break connectivity | | **Enable interface** | ❌ No | Dangerous - interface may be down intentionally | | **Fix IP mismatch** | ✅ Yes | Safe - corrects IPAM drift | | **Update descriptions** | ✅ Yes | Safe - cosmetic change | ### Approval Workflow ```python # Get remediation plan plan = suzieq.generate_remediation_plan(drift) # Filter by auto-fix status auto_fixes = [a for a in plan if a['auto_fix']] manual_review = [a for a in plan if not a['auto_fix']] print(f"Auto-fix ready: {len(auto_fixes)}") print(f"Require approval: {len(manual_review)}") # Apply only auto-approved suzieq.apply_remediation(plan, auto_approve=True) # For manual items, integrate with ticketing system for action in manual_review: # Create Jira ticket, ServiceNow change request, etc. create_change_request( title=f"Fix {action['action']} on {action['device']}", commands=action['commands'], reason=action['reason'] ) ``` ## Installation ### Option 1: Mock Mode (Default) No installation required! Overgrowth includes mock SuzieQ for testing: ```python suzieq = SuzieQClient(use_suzieq=True) # Automatically uses mock mode if suzieq not installed ``` Mock mode simulates: - State collection from devices - Topology discovery - Drift detection with heuristic rules - Remediation plan generation ### Option 2: Real SuzieQ Install SuzieQ for production use: ```bash # Install SuzieQ pip install suzieq # Verify installation suzieq-cli --help # Create SuzieQ directory mkdir -p ~/.suzieq/parquet ``` Configure SuzieQ inventory (`~/.suzieq/inventory.yml`): ```yaml sources: - name: overgrowth hosts: - url: ssh://admin@10.0.0.11 devtype: eos - url: ssh://admin@10.0.0.1 devtype: eos ``` Start SuzieQ poller: ```bash suzieq-poller -I ~/.suzieq/inventory.yml -d ~/.suzieq/parquet ``` ## Configuration ### SuzieQ Client Options ```python from pathlib import Path # Custom data directory suzieq = SuzieQClient( suzieq_dir=Path("/opt/suzieq/data"), use_suzieq=True ) # Collect with custom namespace suzieq.collect_network_state( devices=[...], namespace="production" # vs "staging", "lab", etc. ) # Query specific namespace topology = suzieq.get_topology(namespace="production") ``` ### Drift Tolerance Adjust drift score threshold in `stage8_validation()`: ```python # Default: 20% drift allowed results['validation_passed'] = drift_score < 0.2 # Stricter: 10% drift results['validation_passed'] = drift_score < 0.1 # Looser: 30% drift results['validation_passed'] = drift_score < 0.3 ``` Drift score calculation: ``` drift_score = total_drift_items / (devices_checked * expected_resources) Examples: - 0.0 = Perfect match - 0.15 = Minor drift (2-3 VLANs missing) - 0.5 = Moderate drift (half of config missing) - 1.0 = Complete drift (nothing matches) ``` ## Integration with Pipeline ### Stage 7: Observability Collects actual network state via SuzieQ: - Device inventory - Interface states - VLAN configurations - IP addressing - Routing protocol status - Topology via LLDP/CDP ```python obs_result = pipeline.stage7_observability(model) # Returns: collection stats, topology, VLAN summary ``` ### Stage 7b: Drift Detection Compares actual vs intended (NetBox SoT): - Config mismatches - Missing/extra VLANs - IP conflicts - Interface state drift - Routing issues ```python drift_result = pipeline.stage7b_drift_detection(model) # Returns: drift score, detailed findings, remediation plan ``` ### Stage 8: Validation & Remediation Validates network compliance and auto-remediates: - Generates compliance report - Applies auto-approved fixes - Queues manual approval items - Re-checks drift after remediation ```python val_result = pipeline.stage8_validation(model) # Returns: validation status, compliance report, remediation results ``` ## Drift Detection Examples ### Example 1: Missing VLAN **Intended (NetBox):** ```yaml vlans: - id: 10 name: Users - id: 20 name: Servers - id: 99 name: Management ``` **Actual (Device):** ``` show vlan brief VLAN Name Status Ports ---- -------------------------------- --------- ------ 1 default active 10 Users active Et1-10 99 Management active Et48 ``` **Drift Detected:** ```json { "missing_vlans": [{ "device": "leaf-01", "vlan_id": 20, "vlan_name": "Servers", "severity": "ERROR" }] } ``` **Remediation:** ``` ! Auto-fix: Add missing VLAN vlan 20 name Servers exit ``` ### Example 2: Extra VLAN (Shadow IT) **Intended:** VLANs 10, 20, 99 **Actual:** VLANs 10, 20, 99, **666** (unauthorized) **Drift Detected:** ```json { "extra_vlans": [{ "device": "leaf-01", "vlan_id": 666, "severity": "WARNING" }] } ``` **Remediation:** ``` ! Manual approval required - could disrupt traffic no vlan 666 ``` ### Example 3: Interface Down **Intended:** All uplinks should be UP **Actual:** Ethernet48 is DOWN **Drift Detected:** ```json { "interface_down": [{ "device": "leaf-01", "interface": "Ethernet48", "expected_state": "up", "actual_state": "down", "severity": "WARNING" }] } ``` **Remediation:** ``` ! Manual approval - verify interface should be up interface Ethernet48 no shutdown exit ``` ## Troubleshooting ### Mock Mode vs Real Mode Check if SuzieQ is installed: ```python suzieq = SuzieQClient(use_suzieq=True) print(f"Mock mode: {suzieq.mock_mode}") # Expected output: # WARNING: suzieq not installed - using mock mode # Mock mode: True ``` ### SuzieQ Not Collecting Data 1. **Check SSH connectivity:** ```bash ssh admin@10.0.0.11 ``` 2. **Verify inventory:** ```bash cat ~/.suzieq/inventory.yml ``` 3. **Check poller logs:** ```bash tail -f ~/.suzieq/suzieq-poller.log ``` 4. **Test with CLI:** ```bash suzieq-cli device show ``` ### Drift Detection Returns Empty **Cause:** SuzieQ hasn't collected data yet **Solution:** Run initial collection ```bash # Start poller for 1 minute suzieq-poller -I ~/.suzieq/inventory.yml -d ~/.suzieq/parquet --run-once ``` ### Auto-Fix Not Working **Cause:** `auto_approve=False` (default) **Solution:** ```python # Enable auto-approval results = suzieq.apply_remediation(plan, auto_approve=True) # Or apply manually via Netmiko for action in plan: if action['auto_fix']: device = ConnectHandler( device_type='cisco_ios', host=action['device'], username='admin', password='admin' ) device.send_config_set(action['commands']) ``` ## Performance ### Collection Frequency SuzieQ poller intervals: - **Lab:** Every 1 minute (rapid testing) - **Staging:** Every 5 minutes (drift detection) - **Production:** Every 15 minutes (capacity planning) ### Data Retention SuzieQ stores data in Parquet files: ```bash # Check storage usage du -sh ~/.suzieq/parquet # Cleanup old data (>30 days) find ~/.suzieq/parquet -mtime +30 -delete ``` ### Drift Detection Performance | Network Size | Devices | Drift Check Time | |--------------|---------|------------------| | Small | 1-10 | < 1 second | | Medium | 10-100 | 1-5 seconds | | Large | 100-500 | 5-15 seconds | | Enterprise | 500+ | 15-60 seconds | ## Best Practices ### 1. Use Namespaces Separate environments: ```python # Production namespace suzieq.collect_network_state(devices, namespace="production") # Staging namespace suzieq.collect_network_state(devices, namespace="staging") ``` ### 2. Schedule Regular Drift Checks ```python # Cron job: Check drift every hour #!/bin/bash cd /opt/overgrowth source venv/bin/activate python -c " from agent.pipeline_engine import OvergrowthPipeline pipeline = OvergrowthPipeline() model = NetworkModel.from_yaml('network.yaml') drift = pipeline.stage7b_drift_detection(model) if drift['drift_detected']: print(f'ALERT: Drift score {drift[\"drift_score\"]:.2f}') # Send alert to Slack/PagerDuty " ``` ### 3. Auto-Fix Low-Risk Changes ```python # Safe changes: Add VLANs, update descriptions auto_fix_actions = ['add_vlan', 'update_description', 'fix_ip_mismatch'] # Apply only safe actions safe_plan = [a for a in plan if a['action'] in auto_fix_actions] suzieq.apply_remediation(safe_plan, auto_approve=True) # Manual review for everything else manual_plan = [a for a in plan if a['action'] not in auto_fix_actions] notify_team(manual_plan) ``` ### 4. Track Drift Over Time ```python from datetime import datetime # Log drift history drift_log = { 'timestamp': datetime.now().isoformat(), 'drift_score': drift.drift_score, 'devices_checked': drift.devices_checked, 'issues': { 'config_mismatches': len(drift.config_mismatches), 'missing_vlans': len(drift.missing_vlans), 'extra_vlans': len(drift.extra_vlans) } } # Store in database or CSV append_to_history(drift_log) # Alert if drift increasing if drift_score > previous_score * 1.5: alert("Drift increasing rapidly!") ``` ## Future Enhancements ### Planned Features - **StackStorm Integration:** Event-driven auto-remediation when drift detected - **RAG-based Learning:** Learn from past drift incidents to prevent recurrence - **Change Correlation:** Link drift events to recent changes (Git, tickets) - **Predictive Drift:** ML model to predict drift before it happens - **Multi-Region Sync:** Ensure consistency across global deployments ### Community Contributions See `CONTRIBUTING.md` for how to add: - New drift detection rules - Additional remediation actions - Custom compliance policies - Integration with other observability tools ## References - **SuzieQ Documentation:** https://suzieq.readthedocs.io/ - **SuzieQ GitHub:** https://github.com/netenglabs/suzieq - **Overgrowth Repo:** https://huggingface.co/spaces/MCP-1st-Birthday/overgrowth - **NetBox Integration:** See `NETBOX_INTEGRATION.md` - **Batfish Digital Twin:** See `BATFISH_INTEGRATION.md` ## Support Questions? Issues? Contributions? - Open an issue on HuggingFace Spaces - Join our Discord: [link] - Email: overgrowth@example.com