.. toctree::
:maxdepth: 3
===========================
Cableplan Application
===========================
The Cable Plan module allows the programmer to easily import existing
cable plans from XML files, import the currently running cable plan
from an APIC controller, export previously imported cable plans to a
file, and compare cable plans.
More advanced users can use the Cable Plan to easily build a cable plan XML
file, query a cable plan, and modify a cable plan.
.. _tut-using:
****************************
Using the Cable Plan
****************************
.. _tut-invoking:
Invoking
========================
The Cable Plan module is imported from :file:`cableplan.py` which can
be found in the ``acitoolkit/applications/cableplan`` directory.
::
>>>from cableplan import CABLEPLAN
When you want to create a cable plan from the current running topology
of an ACI fabric, simply do the following::
>>>cp = CABLEPLAN.get(session)
Where ``session`` is an ACI session object generated using the
``acitoolkit``. ``cp`` will be the cable plan object.
You can export that cable plan by opening a file and calling the
``export()`` method as follows::
>>>cpFile = open('cableplan1.xml','w')
>>>cp.export(cpFile)
>>>cpFile.close()
The cable plan will be written to the :file:`cableplan1.xml` file.
Reading an existing cable plan xml file is equally easy.::
>>>fileName = 'cableplan2.xml'
>>>cp2 = CABLEPLAN.get(fileName)
Note that you don't have to explicitly open or close the file. The
``get(fileName)`` method will take care of that for you.
Comparing cable plans is one of the more interesting cabablilities of
the Cable Plan module and is very easy to do using the "difference"
methods. When generating the difference between two cable plans, the
module will return those items that exist in the first cable plan, but
not in the second.
For example, assume that in the above example, the second cable plan
read from the :file:`cableplan2.xml` file does not have switch "Spine3"
and the first cable plan does have it. The following example will
print all of the switches in the first cable plan and not in the
second.::
>>>missing_switches = cp1.difference_switch(cp2)
>>>for switch in missing_switches :
>>> print switch.get_name()
Spine3
Similiarly, the following example will print all of the missing
links::
>>>missing_links = cp1.difference_link(cp2)
>>>for link in missing_links :
>>> print link.get_name()
To understand all of the differences between two cable plans it is
necessary to compare them in both directions ::
>>>missing_links = cp1.difference_link(cp2)
>>>extra_links = cp2.difference_link(cp1)
>>>print 'The following links are missing from the second cable plan'
>>>for link in missing_links :
>>> print link.get_name()
>>>print 'The following links are extra links in the second cable plan'
>>>for link in extra_links:
>>> print link.get_name()
If multiple ports are specified in the link object with minPorts and
maxPorts attributes (see Cable Plan XML Syntax below), it is possible
that a link object in the first cable plan is only partially met by
the link objects in the second cable plan. The ``remainingNeed()``
method of the CP_LINK object.::
>>>missing_links = cp1.difference_link(cp2)
>>>for link in missing_links :
>>> print 'Link',link.get_name(), 'still needs',link.remainingNeed(),'links to satisfy its mimimum requirement'
There is a similar method, ``remainingAvail()`` that returns the
number of physical links the link object could match.
The ``remainingNeed()`` and ``remainingAvail()`` values are reset when
the ``difference_link()`` method is invoked.
It might be necessary to compare cable plans when the names of the
switches are different, but the topologies are the same. This can
easily done by simply changing the names of the switches that are
different and then doing the comparisons.::
>>>switch = cp1.get_switch('Spine1')
>>>switch.set_name('Spine1_new_name')
This will automatically also fix-up all of the link names that are
connected to the switch whose name is being changed. Note that this
is also an easy way to change the name of a switch in a cable plan
file. Simply read it in, change the switch name, and export it out.
The following example will read in :file:`cable_plan2.xml`, change the
name of 'Leaf1' to 'Leaf35', and then export to the same file the
modified cable plan::
>>>fileName = 'cable_plan2.xml'
>>>cp2 = CABLEPLAN.get(fileName)
>>>switch = cp2.get_switch('Leaf1')
>>>switch.set_name('Leaf35')
>>>f = open(fileName,'w')
>>>cp2.export(f)
>>>f.close()
***************************
Cable Plan XML Syntax
***************************
The cable plan XML looks like the following ::
The CHASSIS_INFO tag normally identifies the spine switches and the
leaf switches are contained in the LINK_INFO. When the XML is read
in, both leaf and spine switch objects will be created and the
``get_switch()`` and ``get_link()`` methods can be used to access
them.
The LINK_INFO syntax also allows more flexible and loose
specifications of the links. If the ``sourcePort`` or ``destPort``
attributes are left out, then any port on that corresponding switch
can be used. The ``sourcePort`` and ``destPort`` attributes can also
take port ranges, and lists as shown here::
In addition, you can add ``minPorts`` and ``maxPorts`` attributes to
specify the minimum number of ports or maximum number of ports when
multiple are defined.::
If minPorts is omitted, the default will be 1. If maxPorts is
omitted, the default will be unlimited.
When comparing two cable plans using the ``difference_link()`` method,
if the minimum number of links in the first cable plan can be met with
second cable plan, then the difference will show no difference. Note
that it is possible that requirements of several links specified in
one cable plan may be met by one or more links in the other.
Basically, the difference is calculated such that the minimum
requirements of the first cable plan are met without exceeding the
maximum capacity of the second cable plan.
***************************
Cable Plan API Reference
***************************
.. automodule:: cableplan
:members:
:undoc-members:
:show-inheritance: