File size: 5,455 Bytes
5fb828f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
"""
Generate network topology diagrams from GNS3 topology data
"""

from typing import Dict, List, Optional
import json


def generate_ascii_diagram(topology: Dict) -> str:
    """
    Generate a simple ASCII diagram from topology data
    
    Args:
        topology: Topology dict with nodes and links
        
    Returns:
        ASCII art string representing the network
    """
    nodes = topology.get('nodes', [])
    links = topology.get('links', [])
    
    if not nodes:
        return "No nodes in topology"
    
    # Simple representation
    lines = []
    lines.append(f"{'='*60}")
    lines.append(f"Network Topology: {topology.get('project', 'Unknown')}")
    lines.append(f"Status: {topology.get('status', 'unknown')}")
    lines.append(f"{'='*60}")
    lines.append("")
    
    # Group nodes by type
    by_type = {}
    for node in nodes:
        node_type = node.get('node_type', 'unknown')
        if node_type not in by_type:
            by_type[node_type] = []
        by_type[node_type].append(node)
    
    # Display nodes by type
    for node_type, type_nodes in by_type.items():
        lines.append(f"\n{node_type.upper()} Devices ({len(type_nodes)}):")
        lines.append("-" * 60)
        for node in type_nodes:
            status = node.get('status', 'unknown')
            console = node.get('console', 'N/A')
            status_icon = "🟢" if status == "started" else "🔴" if status == "stopped" else "⚪"
            lines.append(f"  {status_icon} {node['name']:<30} Console: {console}")
    
    # Display link count
    lines.append(f"\n\nTotal Links: {len(links)}")
    
    return "\n".join(lines)


def generate_mermaid_diagram(topology: Dict) -> str:
    """
    Generate a Mermaid diagram from topology data
    
    Args:
        topology: Topology dict with nodes and links
        
    Returns:
        Mermaid diagram code
    """
    nodes = topology.get('nodes', [])
    links = topology.get('links', [])
    
    if not nodes:
        return "graph TD\n  A[No Topology Data]"
    
    lines = []
    lines.append("graph TD")
    
    # Create node definitions with icons based on type
    node_map = {}
    for i, node in enumerate(nodes):
        node_id = f"N{i}"
        node_map[node['name']] = node_id
        node_type = node.get('node_type', 'unknown')
        
        # Choose icon based on type
        if node_type == 'qemu' or 'SW' in node['name']:
            icon = "🔀"  # Switch
        elif node_type == 'vpcs' or 'PC' in node['name'] or 'POS' in node['name']:
            icon = "💻"  # PC
        elif node_type == 'cloud':
            icon = "☁️"  # Cloud
        else:
            icon = "📦"
        
        status = node.get('status', 'unknown')
        if status == "started":
            lines.append(f'  {node_id}["{icon} {node["name"]}<br/>🟢 Running"]')
        elif status == "stopped":
            lines.append(f'  {node_id}["{icon} {node["name"]}<br/>🔴 Stopped"]')
        else:
            lines.append(f'  {node_id}["{icon} {node["name"]}"]')
    
    # Add links (simplified - just show connections exist)
    # Note: GNS3 link format is complex, this is a simplified version
    if links:
        lines.append("\n  %% Network Links")
        # For now, just note that links exist
        lines.append(f"  %% {len(links)} links configured")
    
    return "\n".join(lines)


def generate_topology_summary(topology: Dict) -> str:
    """
    Generate a text summary of the topology
    
    Args:
        topology: Topology dict with nodes and links
        
    Returns:
        Markdown-formatted summary
    """
    nodes = topology.get('nodes', [])
    links = topology.get('links', [])
    project = topology.get('project', 'Unknown')
    status = topology.get('status', 'unknown')
    
    # Count nodes by type and status
    by_type = {}
    by_status = {'started': 0, 'stopped': 0, 'unknown': 0}
    
    for node in nodes:
        node_type = node.get('node_type', 'unknown')
        by_type[node_type] = by_type.get(node_type, 0) + 1
        
        node_status = node.get('status', 'unknown')
        by_status[node_status] = by_status.get(node_status, 0) + 1
    
    summary = []
    summary.append(f"## Network Topology: {project}")
    summary.append(f"**Project Status:** {status}")
    summary.append("")
    summary.append(f"### Devices ({len(nodes)} total)")
    
    for node_type, count in sorted(by_type.items()):
        summary.append(f"- **{node_type}**: {count} device(s)")
    
    summary.append("")
    summary.append(f"### Device Status")
    summary.append(f"- 🟢 Running: {by_status.get('started', 0)}")
    summary.append(f"- 🔴 Stopped: {by_status.get('stopped', 0)}")
    summary.append(f"- ⚪ Unknown: {by_status.get('unknown', 0)}")
    
    summary.append("")
    summary.append(f"### Connectivity")
    summary.append(f"- **Links**: {len(links)} connection(s)")
    
    # List console ports for access
    summary.append("")
    summary.append("### Device Access")
    console_devices = [n for n in nodes if n.get('console')]
    if console_devices:
        summary.append("Devices with console access:")
        for node in console_devices[:10]:  # Limit to first 10
            console = node.get('console')
            console_type = node.get('console_type', 'telnet')
            summary.append(f"- **{node['name']}**: {console_type}://localhost:{console}")
    
    return "\n".join(summary)