Project Details
| Readme | Download |
Introduction
Tangle is a tool to help you document networks.
It takes a text file that lists:
- Endpoint devices (eg, servers, workstations)
- Switches, routers, firewalls
- Management devices (eg, console/KVM servers, managed PDUs)
- Network cables
- Power cables
- Serial/KVM/USB/parallel cables
- Telephone cables (for analogue phones that don't go over UTP)
- Telephones
- VLANs
- IPv4 subnets
- External networks (ISP networks, the phone network, etc)
- Organisations (that own equipment)
...and how they interconnect.
It can then convert that file into a heavily cross-referenced HTML document listing all the components of your network. Every device will list every cable that connects to it (specifying the VLAN(s), IPv4 addresses and so on), and clicking on a cable will lead to a list of all devices and VLANs on that cable; clicking on a VLAN will lead to a list of all devices and IPv4 subnets on the cable; and clicking on an IPv4 address or subnet will go to a list of all the IPv4 addresses on that subnet, and so on.
It also outputs several "dot" files for GraphViz. The default makefile produces three diagrams: one for physical network cabling, one for logical network connectivity (showing what devices are on which VLANs), and one showing management cabling (power, serial, and KVM).
It is written in Python, and consists of two layers: a network parser library which reads the network description file, checks it for errors (duplicate IP addresses, etc), and produces an in-memory cross-referenced object graph; and then a set of scripts that use that library to generate the HTML and "dot" output formats. You can write your own scripts that do other things with the data (such as generating reverse DNS zonefiles).
Using it
A simple (all too simple) driver shell script is supplied, called
document-network.sh, that runs parts of Tangle to make a veritable
soup of network documentation.
Try it out on the supplied examples. From this directory, run:
./document-network.sh examples/home-lan.tangle
./document-network.sh examples/office-lan.tangle
...then look at the HTML and PNG files that appear in the examples directory.
The tangle file format
The network consists of cables, vlans, devices, and ip4 subnets.
Cables
Each cable starts with a line of the form:
{utp|serial|fibre|power|kvm|virtual|usb|telephone|parallel|other|unused} <name> {
Cables all need unique names. Ideally, they should be numbered, with
the number written on the cable (http://www.partex.com/ sell nice
clip-on cable numbers). If you have a multi-location system you can
reuse cable numbers within a location, and write the cable names in
your Tangle file as "
Virtual cables are used for internal management interfaces in switches; they don't exist in the real world, but exist to show that a virtual port inside a device is connected to something, somehow.
Unused cables are special virtual cables used to group unused ports on
devices together. Each unused declaration creates a pool of unused
ports, which is connected with device statements to unused ports on
devices. Within the system an unused port pool is really just a cable,
but the display of the cable is modified slightly - it's not
considered to actually link any ports together, and unused port pools
are listed separately to cables in the table of contents. You don't
have to declare your unused ports, but doing so makes it easy to see
what ports you have spare.
A cable declaration is ended with a closing brace:
}
Within are lines defining the details of the cable:
device <name>/<port>
Declares that this cable goes to the given device on the given
port. Since this is a cabling document, the device names should be in
terms of people looking at the outside of the device - how the
physical socket is labelled, or some other obvious designation; a
server may refer to eth0 internally, but unless you stick a label
saying eth0 on the outside of your server (which is a good idea!), a
name like left might be more useful to the people who go to the
datacenter to re-cable your server.
If you don't know what port it's plugged into, as you have incomplete
information, just use ? as the port name. This will suppress errors
about multiple cables going into the same port, as many cables will
probably go to the ? port on a device.
Device names can be of the form <owner>:<device>. If so, the owning
organisation can be declared with an organisation block, to attach
metadata, as described below.
vlan <vlan>
For Ethernet cables, the untagged VLAN carried on this cable. VLAN
names must be unique; if you reuse VLAN names or numbers in different
contexts, name them <location>.<id>. It is suggested that you use
the actual VLAN ID as the ID (eg, the number you configure into the
switch), but you can use any alphanumeric string as the ID.
tagged vlans <vlan>,<vlan>,...
For Ethernet cables, the list of tagged VLANs carried on this cable.
note "<text>"
General notes to sysadmins. There can be more than one.
Devices
We can also optionally provide extra data about devices with a device declaration:
device <name> {
...
}
If a cable refers to a device with no device declaration, that's fine - we just don't know anything about the device other than what cables plug into it. It's a black box.
Within a device declaration, we allow note declarations, and these
specialist declarations:
type {server|switch|router|manager|power|external|virtual|workstation|printer|telephone|firewall|other}
This declares the type of device, which affects how it is displayed in diagrams, and how it is categorised in the HTML output.
ip4 <port> [<vlan>] <ip> [shared|stub]
This declares that a given port of the device, optionally specifying a
vlan for tagged ports, has a given IPv4 address. There can be more
than one ip4 declaration for a given vlan on a given port, and more
than one vlan on a port, as you would expect. An IP address that
appears on more than one port (eg, HSRP / CARP) should be marked
shared to suppress warnings about the duplication. An IP address
that does not need to match a subnet (eg, a /32 address set up on a
Cisco router's loopback interface) can be declared 'stub' to suppress
warnings about that, too.
mac <port> [<vlan>] <mac> [shared]
This declares that a given port of the device (again, optionally
specifying a vlan for tagged ports), has a given MAC address. The
address should be in xx:xx:xx:xx:xx:xx form, but omitting the colons
or using other characters (spaces, hypens) is also
acceptable. Re-using the same MAC will cause warnings, unless shared
is specified.
Some devices are virtual - VMs, for example. We can express this fact by declaring that the physical server hosts the virtual server like so:
hosts <device>
Note that the system makes no real distinction between physical and virtual devices. They can nest arbitrarily; you can have VMs within VMs.
VM host servers should declare a virtual cable that carries appropriate vlans to ports on virtual machines, and which plugs into an internal virtual port in the VM server, to explain how the VMs get network connectivity.
VLANs
Likewise, we can provide extra information about a VLAN with a vlan declaration:
vlan <name> {
...
}
Again, we can use note declarations within a VLAN.
title "<title>"
This gives the VLAN a meaningful title, since VLAN 'names' are usually just the VLAN numbers.
ip4 subnet <ip>/<prefixlen> "<title>" [multiple]
This declares that a given IPv4 subnet exists on the VLAN. There can
be more than one. The same ip range can exist on different VLANs, too,
but this will cause a warning unless the multiple flag is given, as
this state of affairs is sometimes legitimate (eg, when doing BGP
anycast routing, or an IPv4 subnet appears on different VLANs in
different locations)
ip4 reserved <ip1>-<ip2> "<description>"
This declares that a range of ip4 addresses are reserved for something. This allocates the IP4s as being in use, as if a port on the vlan were assigned an IP, but without a port being required. It's perfect for IP ranges set aside for future use, or for DHCP / VPN / dialup address pools.
Organisations
Finally, we can declare information about organisations.
organisation <code> {
The code of the organisation is the short name used before the colon in the name of a device.
Within an organisation, we can specify a longer name using a title declaration:
title "<name>"
And general notes:
note "<text>"
And details of authorised and emergency contacts:
contact [authorised|emergency] "<text>"
History
Version 0.3
Added MAC address support
Version 0.2
Added the office-lan example, and improved the rendering logic
Version 0.1
Initial public release
TODOs
Generalise VLANs
Having multiple virtual circuits over one cable can be useful for:
- Polyphase power cables
- Serial/KVM "splitter" cables
- ...and maybe other uses in future.
We can currently create VLANs on non-Ethernet cables, just it looks odd; they should be renamed from "VLANs" to "virtual circuits" or some shorter phrasing.
Suggestion: s/vlan/circuit/ but keep "vlan" as a parser-level synonym.
And add a "type" declaration within a circuit declaration, with values matching the same types allowed for cables.
Generalise device/cable types
The core engine has a fixed list of device and cable types (and vlan types?), even though it doesn't really care what they are. Front-end scripts tend to care more, as they often invoke special rendering for particular types of object.
Adding to this list involves extending the parser regexps, extending the documentation, and then extending the various rendering scripts.
It might be nice to have a configuration file that lists all the types of typable things, and then listing key=value properties for them. The parser can generate its regexps from the lists, and then frontends can look up keys to find styling information for specific types.
Make better use of more node shapes:
http://www.graphviz.org/doc/info/shapes.html
Also, make use of colour to better distinguish node and link types in the graphviz outputs.
Minor issues
Make ip4 reserved ranges appear as a single row in the IP4 displays in the HTML.
Make it a proper installable Python thing where you do
python setup.py install

