Automating DrawIO network topology using Python

Intro

In this blog , we are going to show how to use the draw_network_plot python library to generate a DrawIO Network topology easily instead of manually drawing them yourself .

DrawIO is widely used as a free alternative to Microsoft’s Visio to draw network topologies.

I will be using Netmiko and CDP to acquire the data needed for the plot for the devices themselves , but this part won’t be the focus of the article .

Focus of the article is how to use the “drawio_network_plot” library” to generate the DrawIO file .

Library setup

Make sure to have Python 3.7 and above , then install the library using :
$ pip install drawio_network_plot

Lab setup

Lab is done on EVE-NG using Cisco’s 7200VXR image to create the topology , the whole topology is L3 with Loopback so the Python CentOS server would be able to ssh to each device .

EVE-NG Topology Diagram (Non-generated):

Configuration and Script

You can find both the below script and all the EVE-NG Cisco devices configuration in the following Github Link :
drawio_network_plot/examples/cisco_gather_cdp_and_plot

<span>from</span> <span>netmiko</span> <span>import</span> <span>ConnectHandler</span>
<span>import</span> <span>re</span>
<span>from</span> <span>drawio_network_plot.drawio_network_plot</span> <span>import</span> <span>NetPlot</span>
<span># ----------------- Getting live CDP Neigbors to gather links endpoints --------------------------- </span><span>def</span> <span>retieve_lldp_neigbor_hostname</span><span>(</span><span>devices_list</span><span>):</span>
<span>list_of_cdp_neighborship</span> <span>=</span> <span>[]</span>
<span>for</span> <span>device</span> <span>in</span> <span>devices_list</span><span>:</span>
<span>device_dictionary</span> <span>=</span> <span>{</span>
<span>'</span><span>device_type</span><span>'</span><span>:</span> <span>'</span><span>cisco_ios</span><span>'</span><span>,</span>
<span>'</span><span>host</span><span>'</span><span>:</span> <span>device</span><span>[</span><span>'</span><span>ip_address</span><span>'</span><span>],</span>
<span>'</span><span>username</span><span>'</span><span>:</span> <span>'</span><span>automation</span><span>'</span><span>,</span>
<span>'</span><span>password</span><span>'</span> <span>:</span> <span>'</span><span>1234567</span><span>'</span><span>,</span>
<span>}</span>
<span>net_connect</span> <span>=</span> <span>ConnectHandler</span><span>(</span><span>**</span><span>device_dictionary</span><span>)</span>
<span>output</span> <span>=</span> <span>net_connect</span><span>.</span><span>send_command</span><span>(</span><span>"</span><span>show cdp neighbor</span><span>"</span><span>)</span>
<span>lines_list</span> <span>=</span> <span>output</span><span>.</span><span>splitlines</span><span>()</span>
<span>for</span> <span>line</span> <span>in</span> <span>lines_list</span><span>:</span>
<span>try</span><span>:</span>
<span># regex to search the name of the device before the domain ID ".default" , then removing the word ".default" from the string </span> <span>link</span> <span>=</span> <span>{</span>
<span>'</span><span>sourceNodeID</span><span>'</span> <span>:</span> <span>device</span><span>[</span><span>'</span><span>nodeName</span><span>'</span><span>],</span>
<span>'</span><span>destinationNodeID</span><span>'</span> <span>:</span> <span>re</span><span>.</span><span>search</span><span>(</span><span>'</span><span>\S+\.default</span><span>'</span><span>,</span><span>line</span><span>).</span><span>group</span><span>().</span><span>replace</span><span>(</span><span>'</span><span>.default</span><span>'</span><span>,</span><span>''</span><span>)</span>
<span>}</span>
<span># checking for duplication before adding new link : </span> <span>if</span> <span>{</span><span>'</span><span>sourceNodeID</span><span>'</span><span>:</span><span>link</span><span>[</span><span>'</span><span>destinationNodeID</span><span>'</span><span>],</span><span>'</span><span>destinationNodeID</span><span>'</span><span>:</span><span>link</span><span>[</span><span>'</span><span>sourceNodeID</span><span>'</span><span>]}</span> <span>not</span> <span>in</span> <span>list_of_cdp_neighborship</span><span>:</span>
<span>list_of_cdp_neighborship</span><span>.</span><span>append</span><span>(</span><span>link</span><span>)</span>
<span>except</span><span>:</span>
<span>continue</span>
<span>net_connect</span><span>.</span><span>disconnect</span><span>()</span>
<span>return</span> <span>list_of_cdp_neighborship</span>
<span>def</span> <span>main</span><span>():</span>
<span># Lab Devices , must have the device type for the plotting library to work </span> <span>devices</span> <span>=</span> <span>[</span>
<span>{</span><span>'</span><span>nodeName</span><span>'</span><span>:</span><span>'</span><span>Router_1</span><span>'</span><span>,</span><span>'</span><span>ip_address</span><span>'</span><span>:</span><span>'</span><span>100.0.1.1</span><span>'</span><span>,</span><span>'</span><span>nodeType</span><span>'</span><span>:</span><span>'</span><span>router</span><span>'</span><span>,</span><span>'</span><span>nodeDescription</span><span>'</span><span>:</span><span>'</span><span>NA</span><span>'</span><span>},</span>
<span>{</span><span>'</span><span>nodeName</span><span>'</span><span>:</span><span>'</span><span>Router_2</span><span>'</span><span>,</span><span>'</span><span>ip_address</span><span>'</span><span>:</span><span>'</span><span>100.0.1.2</span><span>'</span><span>,</span><span>'</span><span>nodeType</span><span>'</span><span>:</span><span>'</span><span>router</span><span>'</span><span>,</span><span>'</span><span>nodeDescription</span><span>'</span><span>:</span><span>'</span><span>NA</span><span>'</span><span>},</span>
<span>{</span><span>'</span><span>nodeName</span><span>'</span><span>:</span><span>'</span><span>Spine_1</span><span>'</span><span>,</span><span>'</span><span>ip_address</span><span>'</span><span>:</span><span>'</span><span>100.0.2.1</span><span>'</span><span>,</span><span>'</span><span>nodeType</span><span>'</span><span>:</span><span>'</span><span>l3_switch</span><span>'</span><span>,</span><span>'</span><span>nodeDescription</span><span>'</span><span>:</span><span>'</span><span>NA</span><span>'</span><span>},</span>
<span>{</span><span>'</span><span>nodeName</span><span>'</span><span>:</span><span>'</span><span>Spine_2</span><span>'</span><span>,</span><span>'</span><span>ip_address</span><span>'</span><span>:</span><span>'</span><span>100.0.2.2</span><span>'</span><span>,</span><span>'</span><span>nodeType</span><span>'</span><span>:</span><span>'</span><span>l3_switch</span><span>'</span><span>,</span><span>'</span><span>nodeDescription</span><span>'</span><span>:</span><span>'</span><span>NA</span><span>'</span><span>},</span>
<span>{</span><span>'</span><span>nodeName</span><span>'</span><span>:</span><span>'</span><span>Leaf_1</span><span>'</span><span>,</span><span>'</span><span>ip_address</span><span>'</span><span>:</span><span>'</span><span>100.0.3.1</span><span>'</span><span>,</span><span>'</span><span>nodeType</span><span>'</span><span>:</span><span>'</span><span>l2_switch</span><span>'</span><span>,</span><span>'</span><span>nodeDescription</span><span>'</span><span>:</span><span>'</span><span>NA</span><span>'</span><span>},</span>
<span>{</span><span>'</span><span>nodeName</span><span>'</span><span>:</span><span>'</span><span>Leaf_2</span><span>'</span><span>,</span><span>'</span><span>ip_address</span><span>'</span><span>:</span><span>'</span><span>100.0.3.2</span><span>'</span><span>,</span><span>'</span><span>nodeType</span><span>'</span><span>:</span><span>'</span><span>l2_switch</span><span>'</span><span>,</span><span>'</span><span>nodeDescription</span><span>'</span><span>:</span><span>'</span><span>NA</span><span>'</span><span>},</span>
<span>{</span><span>'</span><span>nodeName</span><span>'</span><span>:</span><span>'</span><span>Leaf_3</span><span>'</span><span>,</span><span>'</span><span>ip_address</span><span>'</span><span>:</span><span>'</span><span>100.0.3.3</span><span>'</span><span>,</span><span>'</span><span>nodeType</span><span>'</span><span>:</span><span>'</span><span>l2_switch</span><span>'</span><span>,</span><span>'</span><span>nodeDescription</span><span>'</span><span>:</span><span>'</span><span>NA</span><span>'</span><span>}</span>
<span>]</span>
<span># Getting list of links for each device </span> <span>list_of_cdp_neighborship</span> <span>=</span> <span>retieve_lldp_neigbor_hostname</span><span>(</span><span>devices</span><span>)</span>
<span>for</span> <span>peering</span> <span>in</span> <span>list_of_cdp_neighborship</span><span>:</span>
<span>print</span><span>(</span><span>peering</span><span>)</span>
<span># ------------------------------------------------------------------------------------------------------ </span> <span># ------------------------------------------------------------------------------------------------------ </span> <span># ----------------- Main Part : using library to generate XML DrawIIO format --------------------------- </span> <span># Using the Plot library </span> <span>x</span> <span>=</span> <span>NetPlot</span><span>()</span>
<span>x</span><span>.</span><span>addNodeList</span><span>(</span><span>devices</span><span>)</span>
<span>x</span><span>.</span><span>addLinkList</span><span>(</span><span>list_of_cdp_neighborship</span><span>)</span>
<span>print</span><span>(</span><span>x</span><span>.</span><span>display_xml</span><span>())</span>
<span># ------------------------------------------------------------------------------------------------------ </span> <span># ------------------------------------------------------------------------------------------------------ </span> <span># ------------------------------------------------------------------------------------------------------ </span>
<span>if</span> <span>__name__</span> <span>==</span> <span>"</span><span>__main__</span><span>"</span><span>:</span>
<span>main</span><span>()</span>
<span>from</span> <span>netmiko</span> <span>import</span> <span>ConnectHandler</span>
<span>import</span> <span>re</span> 
<span>from</span> <span>drawio_network_plot.drawio_network_plot</span> <span>import</span> <span>NetPlot</span>

<span># ----------------- Getting live CDP Neigbors to gather links endpoints --------------------------- </span><span>def</span> <span>retieve_lldp_neigbor_hostname</span><span>(</span><span>devices_list</span><span>):</span>
    <span>list_of_cdp_neighborship</span> <span>=</span> <span>[]</span>
    <span>for</span> <span>device</span> <span>in</span> <span>devices_list</span><span>:</span>
        <span>device_dictionary</span> <span>=</span> <span>{</span>
                            <span>'</span><span>device_type</span><span>'</span><span>:</span> <span>'</span><span>cisco_ios</span><span>'</span><span>,</span>  
                            <span>'</span><span>host</span><span>'</span><span>:</span> <span>device</span><span>[</span><span>'</span><span>ip_address</span><span>'</span><span>],</span>
                            <span>'</span><span>username</span><span>'</span><span>:</span> <span>'</span><span>automation</span><span>'</span><span>,</span>
                            <span>'</span><span>password</span><span>'</span> <span>:</span> <span>'</span><span>1234567</span><span>'</span><span>,</span>
                        <span>}</span>
        <span>net_connect</span> <span>=</span> <span>ConnectHandler</span><span>(</span><span>**</span><span>device_dictionary</span><span>)</span>
        <span>output</span> <span>=</span> <span>net_connect</span><span>.</span><span>send_command</span><span>(</span><span>"</span><span>show cdp neighbor</span><span>"</span><span>)</span>
        <span>lines_list</span> <span>=</span> <span>output</span><span>.</span><span>splitlines</span><span>()</span>
        <span>for</span> <span>line</span> <span>in</span> <span>lines_list</span><span>:</span>
            <span>try</span><span>:</span>
                <span># regex to search the name of the device before the domain ID ".default" , then removing the word ".default" from the string </span>                <span>link</span> <span>=</span> <span>{</span>
                            <span>'</span><span>sourceNodeID</span><span>'</span> <span>:</span> <span>device</span><span>[</span><span>'</span><span>nodeName</span><span>'</span><span>],</span>
                            <span>'</span><span>destinationNodeID</span><span>'</span> <span>:</span> <span>re</span><span>.</span><span>search</span><span>(</span><span>'</span><span>\S+\.default</span><span>'</span><span>,</span><span>line</span><span>).</span><span>group</span><span>().</span><span>replace</span><span>(</span><span>'</span><span>.default</span><span>'</span><span>,</span><span>''</span><span>)</span> 
                            <span>}</span>
                <span># checking for duplication before adding new link : </span>                <span>if</span> <span>{</span><span>'</span><span>sourceNodeID</span><span>'</span><span>:</span><span>link</span><span>[</span><span>'</span><span>destinationNodeID</span><span>'</span><span>],</span><span>'</span><span>destinationNodeID</span><span>'</span><span>:</span><span>link</span><span>[</span><span>'</span><span>sourceNodeID</span><span>'</span><span>]}</span> <span>not</span> <span>in</span> <span>list_of_cdp_neighborship</span><span>:</span>
                    <span>list_of_cdp_neighborship</span><span>.</span><span>append</span><span>(</span><span>link</span><span>)</span>
            <span>except</span><span>:</span>
                <span>continue</span>
        <span>net_connect</span><span>.</span><span>disconnect</span><span>()</span>
    <span>return</span> <span>list_of_cdp_neighborship</span>

<span>def</span> <span>main</span><span>():</span>
    <span># Lab Devices , must have the device type for the plotting library to work </span>    <span>devices</span> <span>=</span> <span>[</span>
            <span>{</span><span>'</span><span>nodeName</span><span>'</span><span>:</span><span>'</span><span>Router_1</span><span>'</span><span>,</span><span>'</span><span>ip_address</span><span>'</span><span>:</span><span>'</span><span>100.0.1.1</span><span>'</span><span>,</span><span>'</span><span>nodeType</span><span>'</span><span>:</span><span>'</span><span>router</span><span>'</span><span>,</span><span>'</span><span>nodeDescription</span><span>'</span><span>:</span><span>'</span><span>NA</span><span>'</span><span>},</span>
            <span>{</span><span>'</span><span>nodeName</span><span>'</span><span>:</span><span>'</span><span>Router_2</span><span>'</span><span>,</span><span>'</span><span>ip_address</span><span>'</span><span>:</span><span>'</span><span>100.0.1.2</span><span>'</span><span>,</span><span>'</span><span>nodeType</span><span>'</span><span>:</span><span>'</span><span>router</span><span>'</span><span>,</span><span>'</span><span>nodeDescription</span><span>'</span><span>:</span><span>'</span><span>NA</span><span>'</span><span>},</span>
            <span>{</span><span>'</span><span>nodeName</span><span>'</span><span>:</span><span>'</span><span>Spine_1</span><span>'</span><span>,</span><span>'</span><span>ip_address</span><span>'</span><span>:</span><span>'</span><span>100.0.2.1</span><span>'</span><span>,</span><span>'</span><span>nodeType</span><span>'</span><span>:</span><span>'</span><span>l3_switch</span><span>'</span><span>,</span><span>'</span><span>nodeDescription</span><span>'</span><span>:</span><span>'</span><span>NA</span><span>'</span><span>},</span>
            <span>{</span><span>'</span><span>nodeName</span><span>'</span><span>:</span><span>'</span><span>Spine_2</span><span>'</span><span>,</span><span>'</span><span>ip_address</span><span>'</span><span>:</span><span>'</span><span>100.0.2.2</span><span>'</span><span>,</span><span>'</span><span>nodeType</span><span>'</span><span>:</span><span>'</span><span>l3_switch</span><span>'</span><span>,</span><span>'</span><span>nodeDescription</span><span>'</span><span>:</span><span>'</span><span>NA</span><span>'</span><span>},</span>
            <span>{</span><span>'</span><span>nodeName</span><span>'</span><span>:</span><span>'</span><span>Leaf_1</span><span>'</span><span>,</span><span>'</span><span>ip_address</span><span>'</span><span>:</span><span>'</span><span>100.0.3.1</span><span>'</span><span>,</span><span>'</span><span>nodeType</span><span>'</span><span>:</span><span>'</span><span>l2_switch</span><span>'</span><span>,</span><span>'</span><span>nodeDescription</span><span>'</span><span>:</span><span>'</span><span>NA</span><span>'</span><span>},</span>
            <span>{</span><span>'</span><span>nodeName</span><span>'</span><span>:</span><span>'</span><span>Leaf_2</span><span>'</span><span>,</span><span>'</span><span>ip_address</span><span>'</span><span>:</span><span>'</span><span>100.0.3.2</span><span>'</span><span>,</span><span>'</span><span>nodeType</span><span>'</span><span>:</span><span>'</span><span>l2_switch</span><span>'</span><span>,</span><span>'</span><span>nodeDescription</span><span>'</span><span>:</span><span>'</span><span>NA</span><span>'</span><span>},</span>
            <span>{</span><span>'</span><span>nodeName</span><span>'</span><span>:</span><span>'</span><span>Leaf_3</span><span>'</span><span>,</span><span>'</span><span>ip_address</span><span>'</span><span>:</span><span>'</span><span>100.0.3.3</span><span>'</span><span>,</span><span>'</span><span>nodeType</span><span>'</span><span>:</span><span>'</span><span>l2_switch</span><span>'</span><span>,</span><span>'</span><span>nodeDescription</span><span>'</span><span>:</span><span>'</span><span>NA</span><span>'</span><span>}</span>
            <span>]</span>
    <span># Getting list of links for each device </span>    <span>list_of_cdp_neighborship</span> <span>=</span> <span>retieve_lldp_neigbor_hostname</span><span>(</span><span>devices</span><span>)</span>
    <span>for</span> <span>peering</span> <span>in</span> <span>list_of_cdp_neighborship</span><span>:</span>
        <span>print</span><span>(</span><span>peering</span><span>)</span>

    <span># ------------------------------------------------------------------------------------------------------ </span>    <span># ------------------------------------------------------------------------------------------------------ </span>    <span># ----------------- Main Part : using library to generate XML DrawIIO format --------------------------- </span>    <span># Using the Plot library </span>    <span>x</span> <span>=</span> <span>NetPlot</span><span>()</span>
    <span>x</span><span>.</span><span>addNodeList</span><span>(</span><span>devices</span><span>)</span>
    <span>x</span><span>.</span><span>addLinkList</span><span>(</span><span>list_of_cdp_neighborship</span><span>)</span>
    <span>print</span><span>(</span><span>x</span><span>.</span><span>display_xml</span><span>())</span>
    <span># ------------------------------------------------------------------------------------------------------ </span>    <span># ------------------------------------------------------------------------------------------------------ </span>    <span># ------------------------------------------------------------------------------------------------------ </span>
<span>if</span> <span>__name__</span> <span>==</span> <span>"</span><span>__main__</span><span>"</span><span>:</span>
    <span>main</span><span>()</span>
from netmiko import ConnectHandler import re from drawio_network_plot.drawio_network_plot import NetPlot # ----------------- Getting live CDP Neigbors to gather links endpoints --------------------------- def retieve_lldp_neigbor_hostname(devices_list): list_of_cdp_neighborship = [] for device in devices_list: device_dictionary = { 'device_type': 'cisco_ios', 'host': device['ip_address'], 'username': 'automation', 'password' : '1234567', } net_connect = ConnectHandler(**device_dictionary) output = net_connect.send_command("show cdp neighbor") lines_list = output.splitlines() for line in lines_list: try: # regex to search the name of the device before the domain ID ".default" , then removing the word ".default" from the string link = { 'sourceNodeID' : device['nodeName'], 'destinationNodeID' : re.search('\S+\.default',line).group().replace('.default','') } # checking for duplication before adding new link : if {'sourceNodeID':link['destinationNodeID'],'destinationNodeID':link['sourceNodeID']} not in list_of_cdp_neighborship: list_of_cdp_neighborship.append(link) except: continue net_connect.disconnect() return list_of_cdp_neighborship def main(): # Lab Devices , must have the device type for the plotting library to work devices = [ {'nodeName':'Router_1','ip_address':'100.0.1.1','nodeType':'router','nodeDescription':'NA'}, {'nodeName':'Router_2','ip_address':'100.0.1.2','nodeType':'router','nodeDescription':'NA'}, {'nodeName':'Spine_1','ip_address':'100.0.2.1','nodeType':'l3_switch','nodeDescription':'NA'}, {'nodeName':'Spine_2','ip_address':'100.0.2.2','nodeType':'l3_switch','nodeDescription':'NA'}, {'nodeName':'Leaf_1','ip_address':'100.0.3.1','nodeType':'l2_switch','nodeDescription':'NA'}, {'nodeName':'Leaf_2','ip_address':'100.0.3.2','nodeType':'l2_switch','nodeDescription':'NA'}, {'nodeName':'Leaf_3','ip_address':'100.0.3.3','nodeType':'l2_switch','nodeDescription':'NA'} ] # Getting list of links for each device list_of_cdp_neighborship = retieve_lldp_neigbor_hostname(devices) for peering in list_of_cdp_neighborship: print(peering) # ------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------ # ----------------- Main Part : using library to generate XML DrawIIO format --------------------------- # Using the Plot library x = NetPlot() x.addNodeList(devices) x.addLinkList(list_of_cdp_neighborship) print(x.display_xml()) # ------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------ if __name__ == "__main__": main()

Enter fullscreen mode Exit fullscreen mode

Library Options

Remember , you can gather the data however you like , this was just a simple demonstration of what you can do , main code to remember is the plotting part :

<span># please adhere to the naming scheme in the variables </span><span>device_list</span> <span>=</span> <span>[{</span><span>'</span><span>nodeName</span><span>'</span> <span>:</span> <span>'</span><span>TOR_1</span><span>'</span><span>,</span><span>'</span><span>nodeType</span><span>'</span> <span>:</span> <span>'</span><span>l2_switch</span><span>'</span><span>,</span><span>'</span><span>nodeDescription</span><span>'</span> <span>:</span> <span>'</span><span>Leaf Switch 01</span><span>'</span><span>}]</span>
<span>x</span> <span>=</span> <span>NetPlot</span><span>()</span>
<span># **IMPORTANT NOTE :**---> Make sure that the sourceNode in the connection is the higher level device and that connections are not replicated , this way when you use the DrawIO automatic layout , it would create the diagram hierarchy the correct way </span><span>connections_list</span> <span>=</span> <span>[{</span><span>'</span><span>sourceNodeID</span><span>'</span> <span>:</span> <span>'</span><span>Router_1</span><span>'</span><span>,</span><span>'</span><span>destinationNodeID</span><span>'</span> <span>:</span> <span>'</span><span>Core_switch_1</span><span>'</span><span>}]</span>
<span># Adding using list all at once </span> <span>x</span><span>.</span><span>addNodeList</span><span>(</span><span>device_list</span><span>)</span>
<span>x</span><span>.</span><span>addLinkList</span><span>(</span><span>connections_list</span><span>)</span>
<span># Adding node by node and link by link </span> <span>x</span><span>.</span><span>addNode</span><span>(</span><span>nodeName</span><span>=</span><span>'</span><span>Router_18</span><span>'</span><span>,</span><span>nodeType</span><span>=</span><span>'</span><span>router</span><span>'</span><span>)</span>
<span>x</span><span>.</span><span>addLink</span><span>(</span><span>'</span><span>Router_17</span><span>'</span><span>,</span><span>'</span><span>Router_18</span><span>'</span><span>)</span>
<span># --- Output --- </span> <span># You can print the XML to the Stdout </span> <span>print</span><span>(</span><span>x</span><span>.</span><span>display_xml</span><span>())</span>
<span># Or You can also directly generate an XML file using the built in function : </span> <span># x.exportXML('examples/output.xml') </span>
<span># please adhere to the naming scheme in the variables </span><span>device_list</span> <span>=</span> <span>[{</span><span>'</span><span>nodeName</span><span>'</span> <span>:</span> <span>'</span><span>TOR_1</span><span>'</span><span>,</span><span>'</span><span>nodeType</span><span>'</span> <span>:</span> <span>'</span><span>l2_switch</span><span>'</span><span>,</span><span>'</span><span>nodeDescription</span><span>'</span> <span>:</span> <span>'</span><span>Leaf Switch 01</span><span>'</span><span>}]</span>
<span>x</span> <span>=</span> <span>NetPlot</span><span>()</span>
<span># **IMPORTANT NOTE :**---> Make sure that the sourceNode in the connection is the higher level device and that connections are not replicated , this way when you use the DrawIO automatic layout , it would create the diagram hierarchy the correct way </span><span>connections_list</span> <span>=</span> <span>[{</span><span>'</span><span>sourceNodeID</span><span>'</span> <span>:</span> <span>'</span><span>Router_1</span><span>'</span><span>,</span><span>'</span><span>destinationNodeID</span><span>'</span> <span>:</span> <span>'</span><span>Core_switch_1</span><span>'</span><span>}]</span>
    <span># Adding using list all at once </span>    <span>x</span><span>.</span><span>addNodeList</span><span>(</span><span>device_list</span><span>)</span>
    <span>x</span><span>.</span><span>addLinkList</span><span>(</span><span>connections_list</span><span>)</span>
    <span># Adding node by node and link by link </span>    <span>x</span><span>.</span><span>addNode</span><span>(</span><span>nodeName</span><span>=</span><span>'</span><span>Router_18</span><span>'</span><span>,</span><span>nodeType</span><span>=</span><span>'</span><span>router</span><span>'</span><span>)</span>
    <span>x</span><span>.</span><span>addLink</span><span>(</span><span>'</span><span>Router_17</span><span>'</span><span>,</span><span>'</span><span>Router_18</span><span>'</span><span>)</span>

    <span># --- Output --- </span>    <span># You can print the XML to the Stdout </span>    <span>print</span><span>(</span><span>x</span><span>.</span><span>display_xml</span><span>())</span>
    <span># Or You can also directly generate an XML file using the built in function : </span>    <span># x.exportXML('examples/output.xml') </span>
# please adhere to the naming scheme in the variables device_list = [{'nodeName' : 'TOR_1','nodeType' : 'l2_switch','nodeDescription' : 'Leaf Switch 01'}] x = NetPlot() # **IMPORTANT NOTE :**---> Make sure that the sourceNode in the connection is the higher level device and that connections are not replicated , this way when you use the DrawIO automatic layout , it would create the diagram hierarchy the correct way connections_list = [{'sourceNodeID' : 'Router_1','destinationNodeID' : 'Core_switch_1'}] # Adding using list all at once x.addNodeList(device_list) x.addLinkList(connections_list) # Adding node by node and link by link x.addNode(nodeName='Router_18',nodeType='router') x.addLink('Router_17','Router_18') # --- Output --- # You can print the XML to the Stdout print(x.display_xml()) # Or You can also directly generate an XML file using the built in function : # x.exportXML('examples/output.xml')

Enter fullscreen mode Exit fullscreen mode

Generated output will be collapsed in one point , you will have to choose the Layout you would like in DrawIO after opening the file like showed as follows :

Generated Topology

1- Open generated XML file in DrawIO

2- go to Arrange/Layout/Vertical Tree

3- Final Result

For any comment on the pip package , feature addition or any comment , please share your suggestions as this is my 1st PIP library , and divinely its not perfect .

Thanks …

原文链接:Automating DrawIO network topology using Python

© 版权声明
THE END
喜欢就支持一下吧
点赞12 分享
The God only arranges a happy ending. If it is not happy, it means that it is not the final result.
上天只会安排的快乐的结局。如果不快乐,说明还不是最后结局
评论 抢沙发

请登录后发表评论

    暂无评论内容