pynipap - a Python NIPAP client library¶
pynipap is a Python client library for the NIPAP IP address planning
system. It is structured as a simple ORM.
To make it easy to maintain it’s quite “thin”, passing many arguments
straight through to the backend. Thus, also the pynipap-specific
documentation is quite thin. For in-depth information please look at the
main NIPAP API documentation
.
There are four ORM-classes:
Each of these maps to the NIPAP objects with the same name. See the main
NIPAP API documentation
for an overview of the
different object types and what they are used for.
There are also a few supporting classes:
AuthOptions
- Authentication options.
And a bunch of exceptions:
NipapError
NipapNonExistentError
NipapInputError
NipapMissingInputError
NipapExtraneousInputError
NipapNoSuchOperatorError
NipapValueError
NipapDuplicateError
NipapAuthError
NipapAuthenticationError
NipapAuthorizationError
General usage¶
pynipap has been designed to be simple to use.
Preparations¶
Make sure that pynipap is accessible in your sys.path, you can test it by starting a python shell and running:
import pynipap
If that works, you are good to go!
To simplify your code slightly, you can import the individual classes into your main namespace:
import pynipap
from pynipap import VRF, Pool, Prefix
Before you can access NIPAP you need to specify the URL to the NIPAP XML-RPC service and the authentication options to use for your connection. NIPAP has a authentication system which is somewhat involved, see the main NIPAP documentation.
The URL, including the user credentials, is set in the pynipap module variable xmlrpc_uri as so:
pynipap.xmlrpc_uri = "http://user:pass@127.0.0.1:1337/XMLRPC"
If you want to access the API externally, from another host, update the corresponding lines in the nipap.conf file. Here you can also change the port.
listen = 0.0.0.0 ; IP address to listen on.
port = 1337 ; XML-RPC listen port (change requires restart)
The minimum authentication options which we need to set is the
authoritative_source option, which specifies what system is accessing
NIPAP. This is logged for each query which alters the NIPAP database and
attached to each prefix which is created or edited. Well-behaved clients
are required to honor this and verify that the user really want to alter
the prefix, when trying to edit a prefix which last was edited by another
system. The AuthOptions
class is a class with a shared state,
similar to a singleton class; that is, when a first instance is created
each consecutive instances will be copies of the first one. In this way the
authentication options can be accessed from all of the pynipap classes.
a = AuthOptions({
'authoritative_source': 'my_fancy_nipap_client'
})
After this, we are good to go!
Accessing data¶
To fetch data from NIPAP, a set of static methods (@classmethod) has been defined in each of the ORM classes. They are:
get()
- Get a single object from its ID.list()
- List objects matching a simple criteria.search()
- Perform a full-blown search.smart_search()
- Perform a magic search from a string.
Each of these functions return either an instance of the requested class
(VRF
, Pool
, Prefix
) or a list of
instances. The search()
and smart_search()
functions also
embeds the lists in dicts which contain search meta data.
The easiest way to get data out of NIPAP is to use the get()
-method,
given that you know the ID of the object you want to fetch:
# Fetch VRF with ID 1 and print its name
vrf = VRF.get(1)
print(vrf.name)
To list all objects each object has a list()
-function.
# list all pools
pools = Pool.list()
# print the name of the pools
for p in pools:
print(p.name)
Each of the list functions can also take a spec-dict as a second argument. With the spec you can perform a simple search operation by specifying object attribute values.
# List pools with a default type of 'assignment'
pools = Pool.list({ 'default_type': 'assignment' })
Performing searches¶
Searches are easiest when using the object’s smart_search()
-method:
#Returns a dict which includes search metadata and
#a 'result' : [array, of, prefix, objects]
search_result = Prefix.smart_search('127.0.0.0/8')
prefix_objects = search_result['result']
prefix_objects[0].description
prefix_objects[0].prefix
You can also send query filters.
#Find the prefix for Vlan 901
vlan = 901
vlan_query = { 'val1': 'vlan', 'operator': 'equals', 'val2': vlan }
vlan_901 = Prefix.smart_search('', { }, vlan_query)['result'][0]
vlan_901.vlan
The following operators can be used.
* 'and'
* 'or'
* 'equals_any'
* '='
* 'equals'
* '<'
* 'less'
* '<='
* 'less_or_equal'
* '>'
* 'greater'
* '>='
* 'greater_or_equal'
* 'is'
* 'is_not'
* '!='
* 'not_equals'
* 'like': '
* 'regex_match'
* 'regex_not_match'
* '>>':
* 'contains'
* '>>='
* 'contains_equals'
* '<<'
* 'contained_within'
* '<<='
* 'contained_within_equals'
Saving changes¶
Changes made to objects are not automatically saved. To save the changes,
simply run the object’s save()
-method:
vrf.name = "Spam spam spam"
vrf.save()
Error handling¶
As is customary in Python applications, an error results in an exception
being thrown. All pynipap exceptions extend the main exception
NipapError
. A goal with the pynipap library has been to make the
XML-RPC-channel to the backend as transparent as possible, so the XML-RPC
Faults which the NIPAP server returns in case of errors are converted and
re-thrown as new exceptions which also they extend NipapError
,
for example the NipapDuplicateError which is thrown when a duplicate key
error occurs in NIPAP.
Classes¶
-
class
pynipap.
AuthOptions
(options=None)¶ A global-ish authentication option container.
Note that this essentially is a global variable. If you handle multiple queries from different users, you need to make sure that the AuthOptions-instances are set to the current user’s.
-
exception
pynipap.
NipapAuthError
¶ General NIPAP AAA error
-
exception
pynipap.
NipapAuthenticationError
¶ Authentication failed.
-
exception
pynipap.
NipapAuthorizationError
¶ Authorization failed.
-
exception
pynipap.
NipapDuplicateError
¶ A duplicate entry was encountered
-
exception
pynipap.
NipapError
¶ A generic NIPAP model exception.
All errors thrown from the NIPAP model extends this exception.
-
exception
pynipap.
NipapExtraneousInputError
¶ Extraneous input
Most input is passed in dicts, this could mean an unknown key in a dict.
-
exception
pynipap.
NipapInputError
¶ Something wrong with the input we received
A general case.
-
exception
pynipap.
NipapMissingInputError
¶ Missing input
Most input is passed in dicts, this could mean a missing key in a dict.
-
exception
pynipap.
NipapNoSuchOperatorError
¶ A non existent operator was specified.
-
exception
pynipap.
NipapNonExistentError
¶ Thrown when something can not be found.
For example when a given ID can not be found in the NIPAP database.
-
exception
pynipap.
NipapValueError
¶ Something wrong with a value we have
For example, trying to send an integer when an IP address is expected.
-
class
pynipap.
Pool
¶ An address pool.
-
classmethod
from_dict
(parm, pool=None)¶ Create new Pool-object from dict.
Suitable for creating objects from XML-RPC data. All available keys must exist.
-
classmethod
get
(id)¶ Get the pool with id ‘id’.
-
classmethod
list
(spec=None)¶ List pools.
Maps to the function
nipap.backend.Nipap.list_pool()
in the backend. Please see the documentation for the backend function for information regarding input arguments and return values.
-
remove
()¶ Remove pool.
Maps to the function
nipap.backend.Nipap.remove_pool()
in the backend. Please see the documentation for the backend function for information regarding input arguments and return values.
-
save
()¶ Save changes made to pool to NIPAP.
If the object represents a new pool unknown to NIPAP (attribute id is None) this function maps to the function
nipap.backend.Nipap.add_pool()
in the backend, used to create a new pool. Otherwise it maps to the functionnipap.backend.Nipap.edit_pool()
in the backend, used to modify the pool. Please see the documentation for the backend functions for information regarding input arguments and return values.
-
classmethod
search
(query, search_opts=None)¶ Search pools.
Maps to the function
nipap.backend.Nipap.search_pool()
in the backend. Please see the documentation for the backend function for information regarding input arguments and return values.
-
classmethod
smart_search
(query_string, search_options=None, extra_query=None)¶ Perform a smart pool search.
Maps to the function
nipap.backend.Nipap.smart_search_pool()
in the backend. Please see the documentation for the backend function for information regarding input arguments and return values.
-
classmethod
-
class
pynipap.
Prefix
¶ A prefix.
-
classmethod
find_free
(vrf, args)¶ Finds a free prefix.
Maps to the function
nipap.backend.Nipap.find_free_prefix()
in the backend. Please see the documentation for the backend function for information regarding input arguments and return values.
-
classmethod
from_dict
(pref, prefix=None)¶ Create a Prefix object from a dict.
Suitable for creating Prefix objects from XML-RPC input.
-
classmethod
get
(id)¶ Get the prefix with id ‘id’.
-
classmethod
list
(spec=None)¶ List prefixes.
Maps to the function
nipap.backend.Nipap.list_prefix()
in the backend. Please see the documentation for the backend function for information regarding input arguments and return values.
-
remove
(recursive=False)¶ Remove the prefix.
Maps to the function
nipap.backend.Nipap.remove_prefix()
in the backend. Please see the documentation for the backend function for information regarding input arguments and return values.
-
save
(args=None)¶ Save prefix to NIPAP.
If the object represents a new prefix unknown to NIPAP (attribute id is None) this function maps to the function
nipap.backend.Nipap.add_prefix()
in the backend, used to create a new prefix. Otherwise it maps to the functionnipap.backend.Nipap.edit_prefix()
in the backend, used to modify the VRF. Please see the documentation for the backend functions for information regarding input arguments and return values.
-
classmethod
search
(query, search_opts=None)¶ Search for prefixes.
Maps to the function
nipap.backend.Nipap.search_prefix()
in the backend. Please see the documentation for the backend function for information regarding input arguments and return values.
-
classmethod
smart_search
(query_string, search_options=None, extra_query=None)¶ Perform a smart prefix search.
Maps to the function
nipap.backend.Nipap.smart_search_prefix()
in the backend. Please see the documentation for the backend function for information regarding input arguments and return values.
-
classmethod
-
class
pynipap.
Pynipap
(id=None)¶ A base class for the pynipap model classes.
All Pynipap classes which maps to data in NIPAP (
VRF
,Pool
,Prefix
) extends this class.-
id
= None¶ Internal database ID of object.
-
-
class
pynipap.
Tag
(id=None)¶ A Tag.
-
classmethod
from_dict
(tag=None)¶ Create new Tag-object from dict.
Suitable for creating objects from XML-RPC data. All available keys must exist.
-
name
= None¶ The Tag name
-
classmethod
search
(query, search_opts=None)¶ Search tags.
For more information, see the backend function
nipap.backend.Nipap.search_tag()
.
-
classmethod
-
class
pynipap.
VRF
¶ A VRF.
-
description
= None¶ VRF description, as a string.
-
free_addresses_v4
= None¶ Number of free IPv4 addresses in this VRF
-
free_addresses_v6
= None¶ Number of free IPv6 addresses in this VRF
-
classmethod
from_dict
(parm, vrf=None)¶ Create new VRF-object from dict.
Suitable for creating objects from XML-RPC data. All available keys must exist.
-
classmethod
get
(id)¶ Get the VRF with id ‘id’.
-
classmethod
list
(vrf=None)¶ List VRFs.
Maps to the function
nipap.backend.Nipap.list_vrf()
in the backend. Please see the documentation for the backend function for information regarding input arguments and return values.
-
name
= None¶ The name of the VRF, as a string.
-
num_prefixes_v4
= None¶ Number of IPv4 prefixes in this VRF
-
num_prefixes_v6
= None¶ Number of IPv6 prefixes in this VRF
-
remove
()¶ Remove VRF.
Maps to the function
nipap.backend.Nipap.remove_vrf()
in the backend. Please see the documentation for the backend function for information regarding input arguments and return values.
-
rt
= None¶ The VRF RT, as a string (x:y or x.x.x.x:y).
-
save
()¶ Save changes made to object to NIPAP.
If the object represents a new VRF unknown to NIPAP (attribute id is None) this function maps to the function
nipap.backend.Nipap.add_vrf()
in the backend, used to create a new VRF. Otherwise it maps to the functionnipap.backend.Nipap.edit_vrf()
in the backend, used to modify the VRF. Please see the documentation for the backend functions for information regarding input arguments and return values.
-
classmethod
search
(query, search_opts=None)¶ Search VRFs.
Maps to the function
nipap.backend.Nipap.search_vrf()
in the backend. Please see the documentation for the backend function for information regarding input arguments and return values.
-
classmethod
smart_search
(query_string, search_options=None, extra_query=None)¶ Perform a smart VRF search.
Maps to the function
nipap.backend.Nipap.smart_search_vrf()
in the backend. Please see the documentation for the backend function for information regarding input arguments and return values.
-
total_addresses_v4
= None¶ Total number of IPv4 addresses in this VRF
-
total_addresses_v6
= None¶ Total number of IPv6 addresses in this VRF
-
used_addresses_v4
= None¶ Number of used IPv4 addresses in this VRF
-
used_addresses_v6
= None¶ Number of used IPv6 addresses in this VRF
-
-
class
pynipap.
XMLRPCConnection
¶ Handles a shared XML-RPC connection.
-
pynipap.
nipap_db_version
()¶ Get schema version of database we’re connected to.
Maps to the function
nipap.backend.Nipap._get_db_version()
in the backend. Please see the documentation for the backend function for information regarding the return value.
-
pynipap.
nipapd_version
()¶ Get version of nipapd we’re connected to.
Maps to the function
nipap.xmlrpc.NipapXMLRPC.version()
in the XML-RPC API. Please see the documentation for the XML-RPC function for information regarding the return value.