API Programmability - Part 4: Diagramming

7 minute read

In Part 3, we discussed using the python-ipfabric SDK to interact with IP Fabric's API - did you know that you can also create diagrams using the API? Today we will be using the python-ipfabric-diagrams SDK. Since diagramming is a coding heavy topic, I am also working on a webinar to show live examples and more advanced features such as turning layers off and ungrouping links.

Find a coding example at demo-python-ipfabric-diagrams.

Requirements

  • Python 3.7.1+
  • python-ipfabric-diagrams
    • pip install ipfabric-diagrams
  • IP Fabric version 4.3.0 or greater

Diagram Methods

There are four options for returning data in the IPFDiagram class.

  • diagram_png: Returns PNG image as a bytes string.
  • diagram_svg: Returns SVG image as a bytes string.
  • diagram_json: Returns the raw JSON from IP Fabric.
  • diagram_model: Takes the raw json and converts it into a python object with type hints.

Each of these methods has five input parameters, and only the first one is required:

  • parameters (required): Python object of class Unicast, Multicast, Host2GW, or Network.
  • snapshot_id: A snapshot ID to override the default when the class was initiated.
  • overlay: Overlay object which specifies a comparison snapshot or intent rule overlay.
  • graph_settings: Python object of NetworkSettings (Network parameter) or PathLookupSettings (Unicast, Multicast, or Host2GW parameter).
  • unicast_swap_src_dst: Boolean that if set to True it will swap the Source and Destination IP, Ports, and Regions (only used with the Unicast parameter).

Host to Gateway Path Lookup

This is the most basic diagram as it takes a single IP address. The imports will differ depending on the type of graph.

# 1_host2gateway.py
from ipfabric_diagrams import IPFDiagram, Host2GW

if __name__ == '__main__':
    diagram = IPFDiagram(base_url='https://demo3.ipfabric.io/', token='token', verify=False)

    with open('1_host2gateway.png', 'wb') as f:
        f.write(diagram.diagram_png(Host2GW(startingPoint='10.241.1.108')))

Network Diagram Example

The Network class accepts 3 input parameters. If no parameters are defined, this will create a graph similar to going to the UI and Diagrams > Network.

  • sites: String of a single site name or a List of site names.
  • all_network: If set to True it will show all sites as clouds in the diagram and only expand the sites specified in the above parameter (default False).
  • layouts: List of Layout objects to change the layout of a particular site.
    • Valid layouts: ["circular", "downwardTree", "hierarchical", "radial", "universal", "upwardTree"]
# 2_network.py
from ipfabric_diagrams import IPFDiagram, Network, Layout

if __name__ == '__main__':
    diagram = IPFDiagram(base_url='https://demo3.ipfabric.io/', token='token', verify=False)

    with open('2_1_network.png', 'wb') as f:
        f.write(diagram.diagram_png(Network(sites='MPLS', all_network=True)))

    with open('2_2_network.png', 'wb') as f:
        f.write(diagram.diagram_png(Network(sites=['LAB01', 'HWLAB'], all_network=False)))

    with open('2_3_network.png', 'wb') as f:
        f.write(diagram.diagram_png(
            Network(sites='L71', all_network=False, layouts=[Layout(path='L71', layout='upwardTree')])
        ))

2_1_network.png

2_2_network.png

2_3_network.png

Diagram Overlay

Before moving on to Unicast and Multicast let's take a look at how to overlay a snapshot comparison or specific intent rule onto your graph. You can apply this to any type of graph.

Snapshot Comparison

# 3_network_overlay.py
from ipfabric_diagrams import IPFDiagram, Network, Overlay

if __name__ == '__main__':
    diagram = IPFDiagram(base_url='https://demo3.ipfabric.io/', token='token', verify=False)

    with open('3_1_network_snap_overlay.png', 'wb') as f:
        f.write(diagram.diagram_png(Network(sites='MPLS', all_network=False),
                                    overlay=Overlay(snapshotToCompare='$prev')))

Intent Rule

To overlay an Intent Rule you must first get the ID of the rule to submit. In this example, we are using the ipfabric package to load the intents and get a rule by name. Find more examples of extracting intent rule IDs here.

# 3_network_overlay.py
from ipfabric import IPFClient
from ipfabric_diagrams import IPFDiagram, Network, Overlay

if __name__ == '__main__':
    diagram = IPFDiagram(base_url='https://demo3.ipfabric.io/', token='token', verify=False)

    # Get intent rule ID
    ipf = IPFClient(base_url='https://demo3.ipfabric.io/', token='token', verify=False)
    ipf.intent.load_intent()
    intent_rule_id = ipf.intent.intent_by_name['NTP Reachable Sources'].intent_id

    with open('3_2_network_intent_overlay.png', 'wb') as f:
        f.write(diagram.diagram_png(Network(sites=['L71'], all_network=False),
                                    overlay=Overlay(intentRuleId=intent_rule_id)))

Unicast Path Lookup

The next two examples make it a bit clearer why we first create a python object and then pass it into the diagramming functions. The amount of options required are quite lengthy, and this keeps your code cleaner and provides great type hints (see below). Additionally, it has many built-in checks to ensure you provide the correct data before submitting the payload to IP Fabric and returning an error.

ICMP Example

For all valid ICMP types please refer to icmp.py.

# 5_unicast_path_lookup.py
from ipfabric_diagrams import IPFDiagram, Unicast
from ipfabric_diagrams import icmp

if __name__ == '__main__':
    diagram = IPFDiagram(base_url='https://demo3.ipfabric.io/', token='token', verify=False)

    unicast_icmp = Unicast(
        startingPoint='10.47.117.112',
        destinationPoint='10.66.123.117',
        protocol='icmp',
        icmp=icmp.ECHO_REQUEST,  # Dict is also valid: {'type': 0, 'code': 0}
        ttl=64,
        securedPath=False  # UI Option 'Security Rules'; True == 'Drop'; False == 'Continue'
    )

    with open('5_1_unicast_icmp.png', 'wb') as f:
        f.write(diagram.diagram_png(unicast_icmp))

TCP or UDP Example

TCP and UDP accept srcPorts and dstPorts which can be a single port number, a comma-separated list, a range of ports separated by a -, or any combination of them. The applications, srcRegions, and dstRegions arguments are used for Zone Firewall rule checks and these default to any (.*).

# 5_unicast_path_lookup.py
from ipfabric_diagrams import IPFDiagram, Unicast, OtherOptions, Algorithm, EntryPoint

if __name__ == '__main__':
    diagram = IPFDiagram(base_url='https://demo3.ipfabric.io/', token='token', verify=False)

    unicast_tcp = Unicast(
        startingPoint='10.47.117.112',
        destinationPoint='10.66.123.117',
        protocol='tcp',
        srcPorts='1024,2048-4096',
        dstPorts='80,443',
        otherOptions=OtherOptions(applications='(web|http|https)', tracked=False),
        srcRegions='US',
        dstRegions='CZ',
        ttl=64,
        securedPath=False
    )

    with open(path.join('path_lookup', '5_2_unicast_tcp.png'), 'wb') as f:
        f.write(diagram.diagram_png(unicast_tcp))

    with open(path.join('path_lookup', '5_3_unicast_tcp_swap_src_dst.png'), 'wb') as f:
        f.write(diagram.diagram_png(unicast_tcp, unicast_swap_src_dst=True))

    # Subnet Example
    unicast_subnet = Unicast(
        startingPoint='10.38.115.0/24',
        destinationPoint='10.66.126.0/24',
        protocol='tcp',
        srcPorts='1025',
        dstPorts='22',
        securedPath=False
    )

    with open(path.join('path_lookup', '5_4_unicast_subnet.png'), 'wb') as f:
        f.write(diagram.diagram_png(unicast_subnet))

Subnet Example:

Entry Point Example

This is a new graphing feature in version 4.3 and above that allows you to specify a device and interface a packet enters your network. Perhaps you have a firewall rule to allow a certain IP address or subnet and want to verify that this is functioning correctly. The sn value is the IP Fabric unique serial number, iface is the intName or Interface column (not to be confused with Original Name), and the hostname is also required. The easiest way to collect this information is from the Inventory > Interfaces table. The sn is not a visible column in the UI, but is available from the API.

# Example pulling Interface Inventory table
from ipfabric import IPFClient
ipf = IPFClient(base_url='https://demo3.ipfabric.io/', token='token', verify=False)
interfaces = ipf.inventory.interfaces.all(columns=['sn', 'hostname', 'intName'])
# 5_unicast_path_lookup.py
from ipfabric_diagrams import IPFDiagram, Unicast, Algorithm, EntryPoint

if __name__ == '__main__':
    diagram = IPFDiagram(base_url='https://demo3.ipfabric.io/', token='token', verify=False)

    # User Defined Entry Point Example
    unicast_entry_point = Unicast(
        startingPoint='1.0.0.1',
        destinationPoint='10.66.126.0/24',
        protocol='tcp',
        srcPorts='1025',
        dstPorts='22',
        securedPath=True,
        firstHopAlgorithm=Algorithm(entryPoints=[
            EntryPoint(sn='test', iface='eth0', hostname='test'),
            dict(sn='test', iface='eth0', hostname='test')  # You can also use a dictionary
        ])
    )

Multicast Path Lookup

Multicast is very similar to Unicast except some of the parameter names have changed. You can also specify a receiver IP address but this is optional.

# 7_multicast.py
from ipfabric_diagrams import IPFDiagram, Multicast

if __name__ == '__main__':
    diagram = IPFDiagram(base_url='https://demo3.ipfabric.io/', token='token', verify=False)

    multicast = Multicast(
        source='10.33.230.2',
        group='233.1.1.1',
        receiver='10.33.244.200',  # Optional
        protocol='tcp',
        srcPorts='1024,2048-4096',
        dstPorts='80,443',
    )

    with open('7_multicast.png', 'wb') as f:
        f.write(diagram.diagram_png(multicast))

JSON and Model Outputs

One of the great advantages of using this package is returning a Python object instead of returning the raw JSON. This allows a user to more easily understand the complex textual data returned by IP Fabric that represents how the edges (links) connect to the nodes (devices, clouds, etc.) and the decisions a packet may take. You can accomplish this via the JSON output but returning an object provides type hints along with the ability to export the model as a JSON schema. Please note that the model is not the exact same as the JSON output and some structure has been changed for ease of use. It also dynamically links some internal objects to eliminate the need to do extra lookups and references.

# 6_json_vs_model.py
from ipfabric_diagrams.output_models.graph_result import GraphResult

if __name__ == '__main__':
    print(GraphResult.schema_json(indent=2))
"""
{
  "title": "GraphResult",
  "type": "object",
  "properties": {
    "nodes": {
      "title": "Nodes",
      "type": "object",
      "additionalProperties": {
        "$ref": "#/definitions/Node"
      }
    },
    "edges": {
      "title": "Edges",
      "type": "object",
      "additionalProperties": {
        "anyOf": [
          {
            "$ref": "#/definitions/NetworkEdge"
          },
          {
            "$ref": "#/definitions/PathLookupEdge"
          }
        ]
      }
    },
...
"""

Summary

The ability to create diagrams using the API allows for greater automation and integration into other applications. Many of our customers use this feature to create chatbots to speed up troubleshooting, as shown below. This example is from the Network to Code nautobot-plugin-chatops-ipfabric plugin.

Another useful feature is performing a Path Lookup and parsing the JSON output to ensure traffic is flowing apart of a review process. We have partnered with Itential to demonstrate how using their low-code automation platform can automate ServiceNow requests and ensure that a newly deployed IP has access to correct network services during a Change Control review. Keep an eye out for a video of this exciting demonstration!

If you have any questions, comments, or bug requests please send an email to [email protected] or open an issue request on the GitHub repository.

If you want to see how network assurance can give you control over your network, request a demo with our team.

Get IP Fabric

Request a demo and discover how to increase
your networks visibility & get better time efficiency.
Free Demo | Zero Obligation
Request a Demo
We're Hiring!
Join the Team and be part of the Future of Network Automation
Available Positions
IP Fabric, Inc.
115 BROADWAY, 5th Floor
NEW YORK NY, 10006
United States
This is a block of text. Double-click this text to edit it.
Phone : +1 (914) 752-2991
Email : [email protected]
IP Fabric s.r.o.
Kateřinská 466/40
Praha 2 - Nové Město, 120 00
Czech Republic
This is a block of text. Double-click this text to edit it.
Phone : +420 720 022 997
Email : [email protected]
IP Fabric, Inc. © 2022 All Rights Reserved