Commits

Erik Romijn committed 7d2c40a

better community syntax, bugfix

Comments (0)

Files changed (5)

+Metadata-Version: 1.1
+Name: pybird
+Version: 1.0.6
+Author: Erik Romijn
+Author-email: eromijn at solidlinks nl
+Summary: BIRD interface handler for Python
+Description: .. -*- restructuredtext -*-
+	
+	==========================================
+	pybird - BIRD interface handler for Python
+	==========================================
+	
+	PyBird is a Python interface to the BIRD Internet Routing Daemon's UNIX control
+	socket, handling the socket connections and parsing the output.
+	
+	In it's current state, you can use it to query the status of specific or all
+	BGP peers, to query the routes received, accepted and rejected from a peer,
+	or the general status of BIRD (router ID, last config change)
+	
+	
+	Usage example
+	=============
+	
+	    >>> from pybird import PyBird
+	    >>> pybird = PyBird(socket_file='/var/run/bird.ctl')
+	    >>> peer_state = pybird.get_peer_status('KPN')
+	    >>> peer_state['up']
+	    True
+	    >>> peer_state['import_updates_received']
+	    4214
+	    >>> peer_state['last_change']
+	    datetime.datetime(2011, 6, 19, 19, 57, 0, 0)
+	
+	    >>> rejected = pybird.get_peer_prefixes_rejected('KPN')
+	    >>> rejected[0]['as_path']
+	    '23456 65592'
+	    
+	    >>> status = pybird.get_status()
+	    >>> status['last_reconfiguration_time']
+	    datetime.datetime(2012, 1, 3, 12, 46, 40)
+	    >>> status['router_id']
+	    "192.168.0.1"
+	
+	You can also call ``get_peer_status()`` without a peer name, to get an array
+	with all the BGP peers.
+	
+	Full field list for peers
+	=========================
+	
+	All fields that are decoded, if present:
+	
+	- ``name``: Name as configured in BIRD
+	- ``protocol``: Currently always "BGP"
+	- ``last_change``: Last state change as a ``datetime.datetime`` object
+	- ``state``: String of the peer status, e.g. "Established" or "Passive"
+	- ``up``: Boolean, True if session is Established
+	- ``routes_imported``: Number of imported routes
+	- ``routes_exported``: Number of exported routes
+	- ``router_id``: BGP router id
+	
+	And all combinations of:
+	``[import,export]_[updates,withdraws]_[received,rejected,filtered,ignored,accepted]``
+	which BIRD supports.
+	
+	
+	Full field list for routes
+	==========================
+	
+	All fields that are decoded, if present:
+	
+	- ``origin``: BGP origin, e.g. "IGP"
+	- ``as_path``: AS path as string
+	- ``next_hop``: BGP next hop
+	- ``local_pref``: Local pref, e.g. '100'
+	- ``community``: Communities in string format, e.g. '8954:220 8954:620'
+	
+	And any other BGP attribute fields BIRD has found.
+	
+	
+	Full field list for BIRD status
+	===============================
+	
+	- ``router_id``: BGP Router ID as string
+	- ``last_reboot``: Last BIRD restart time as datetime
+	- ``last_reconfiguration``: Last BIRD config change as datetime
+	
+	
+	Test suite
+	==========
+	
+	There is a series of tests in ``tests.py``. This includes a ``MockBird``: a
+	mocked BIRD instance, with fixed but real responses, that listens on a real
+	UNIX socket. This means the tests do not only test parsing, but also socket
+	interaction.
+Keywords: bird bgp
+Classifier: Development Status :: 4 - Beta
 - ``as_path``: AS path as string
 - ``next_hop``: BGP next hop
 - ``local_pref``: Local pref, e.g. '100'
-- ``community``: Communities in BIRD string format, e.g. '(8954,620)'
+- ``community``: Communities in string format, e.g. '8954:220 8954:620'
 
 And any other BGP attribute fields BIRD has found.
 
      	for line in lines:
      	    line = line.strip()
      	    # remove 'BGP.'
-     	    line = line[4:]
+     	    line = line[4:]     	    
+     	    (key, value) = line.split(": ")
      	    
-     	    (key, value) = line.split(": ")
+     	    if key == 'community':
+     	        # convert (8954,220) (8954,620) to 8954:220 8954:620
+     	        value = value.replace(",", ":").replace("(", "").replace(")", "")
+     	    
      	    attributes[key] = value
      	    
      	return attributes
 from distutils.core import setup
 
 setup(name='pybird',
-      version='1.0.5',
+      version='1.0.6',
       description='BIRD interface handler for Python',
       author='Erik Romijn',
       author_email='eromijn@solidlinks.nl',
         # The test data says 14:20, so that could be today or yesterday
         now = datetime.now()
         expected_date = datetime(now.year, now.month, now.day, 14, 20)
-        if now.hour <= 14 and now.hour < 20:
+        if now.hour < 14 or now.hour == 14 and now.minute < 20:
             expected_date = expected_date - timedelta(days=1)
         self.assertEquals(ps2_status['last_change'], expected_date)
         
         ps1_status = self.pybird.get_peer_status("PS1")
         self.assertFalse(ps1_status['up'])
 
-        self.assertEquals(ps1_status['last_change'], datetime(2011, 6, 14))
+        self.assertEquals(ps1_status['last_change'], datetime(2012, 6, 13))
 
         self.assertEquals(ps1_status['state'], "Passive")
 
 
         self.assertEquals(accepted_prefixes[0]['origin'], 'IGP')
         self.assertEquals(accepted_prefixes[0]['as_path'], '8954 8283')
+        self.assertEquals(accepted_prefixes[0]['community'], '8954:220 8954:620')
         
 
     def test_specific_peer_prefixes_rejected(self):
  	BGP.as_path: 8954 8283
  	BGP.next_hop: 2001:7f8:1::a500:8954:1 fe80::21f:caff:fe16:e02
  	BGP.local_pref: 100
- 	BGP.community: (8954,620)
+ 	BGP.community: (8954,220) (8954,620)
 0000
 """,
         'show route all protocol ps99\n': """
  	BGP.as_path: 8954 8283
  	BGP.next_hop: 2001:7f8:1::a500:8954:1 fe80::21f:caff:fe16:e02
  	BGP.local_pref: 100
- 	BGP.community: (8954,620)
+ 	BGP.community: (8954,220) (8954,620)
 1007-2001:500:3::/48    via 2001:7f8:1::a500:8954:1 on eth1 [PS2 13:14] * (100) [AS20144i]
 1008-	Type: BGP unicast univ
 1012-	BGP.origin: IGP