Skip to content

Commit

Permalink
Merge pull request #50 from arista-eosplus/feature_routemap-update
Browse files Browse the repository at this point in the history
Feature routemap update
  • Loading branch information
phil-dileo committed Oct 21, 2015
2 parents 64f7a46 + dd5312a commit 2033504
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 33 deletions.
2 changes: 1 addition & 1 deletion pyeapi/api/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def getall(self):
for name in interfaces_re.findall(self.config):
interface = self.get(name)
if interface:
response['name'] = interface
response[name] = interface
return response

def __getattr__(self, name):
Expand Down
71 changes: 43 additions & 28 deletions pyeapi/api/routemaps.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,46 +55,61 @@

import re

from pyeapi.api import Entity
from pyeapi.api import Entity, EntityCollection


class Routemaps(Entity):
class Routemaps(EntityCollection):
"""The Routemaps class provides management of the routemaps configuration
The Routemaps class is derived from Entity and provides an API for working
with the nodes routemaps configuraiton.
"""

def get(self, name, action, seqno):
return self._get_instance(name, action, seqno)
def get(self, name):
if not self.get_block(r'route-map\s%s\s\w+\s\d+' % name):
return None

return self._parse_entries(name)

def getall(self):
resources = dict()
routemaps_re = re.compile(r'^route-map\s(\w+)\s(\w+)\s(\d+)$', re.M)
for entry in routemaps_re.findall(self.config):
name = entry[0]
action = entry[1]
seqno = int(entry[2])

routemap = self.get(name, action, seqno)
routemaps_re = re.compile(r'^route-map\s(\w+)\s\w+\s\d+$', re.M)
for name in routemaps_re.findall(self.config):
routemap = self.get(name)
if routemap:
key = (name, action, seqno)
resources[key] = routemap
resources[name] = routemap
return resources

def _get_instance(self, name, action, seqno):
routemap_re = r'route-map\s%s\s%s\s%s' % (name, action, seqno)
routemap = self.get_block(routemap_re)

if not routemap:
return None

resource = dict(name=name, action=action, seqno=int(seqno))
resource.update(self._parse_match_statements(routemap))
resource.update(self._parse_set_statements(routemap))
resource.update(self._parse_continue_statement(routemap))
resource.update(self._parse_description(routemap))
return resource
def _parse_entries(self, name):

routemap_re = re.compile(r'^route-map\s%s\s(\w+)\s(\d+)$'
% name, re.M)
entries = list()
for entry in routemap_re.findall(self.config):
resource = dict()
action, seqno = entry
routemap = self.get_block(r'route-map\s%s\s%s\s%s'
% (name, action, seqno))

resource = dict(name=name, action=action, seqno=seqno, attr=dict())
resource['attr'].update(self._parse_match_statements(routemap))
resource['attr'].update(self._parse_set_statements(routemap))
resource['attr'].update(self._parse_continue_statement(routemap))
resource['attr'].update(self._parse_description(routemap))
entries.append(resource)

return self._merge_entries(entries)

def _merge_entries(self, entries):
response = dict()
for e in entries:
action = e['action']
seqno = int(e['seqno'])
if not response.get(action):
response[action] = dict()
response[action][seqno] = e['attr']

return response

def _parse_match_statements(self, config):
match_re = re.compile(r'^\s+match\s(.+)$', re.M)
Expand Down Expand Up @@ -196,7 +211,7 @@ def set_match_statements(self, name, action, seqno, statements):
True if the operation succeeds otherwise False
"""
try:
current_statements = self._get_instance(name, action, seqno)['match']
current_statements = self.get(name)[action][seqno]['match']
except:
current_statements = []

Expand Down Expand Up @@ -232,7 +247,7 @@ def set_set_statements(self, name, action, seqno, statements):
True if the operation succeeds otherwise False
"""
try:
current_statements = self._get_instance(name, action, seqno)['set']
current_statements = self.get(name)[action][seqno]['set']
except:
current_statements = []

Expand Down
24 changes: 24 additions & 0 deletions test/fixtures/running_config.routemaps
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,27 @@ route-map TEST permit 20
match interface Ethernet2
continue 200
!
route-map TEST deny 30
match as 2000
match source-protocol ospf
match interface Ethernet2
continue 200
!
route-map FOO deny 20
match as 2000
match source-protocol ospf
match interface Ethernet2
continue 200
!
route-map FOOBAR permit 20
match as 2000
match source-protocol ospf
match interface Ethernet2
continue 200
!
route-map FOOBAR permit 20
match as 2000
match source-protocol ospf
match interface Ethernet2
continue 200
!
33 changes: 29 additions & 4 deletions test/unit/test_api_routemaps.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,12 @@ def test_instance(self):
self.assertIsInstance(result, pyeapi.api.routemaps.Routemaps)

def test_get(self):
result = self.instance.get('TEST', 'permit', 10)
keys = ['name', 'action', 'seqno', 'set', 'match', 'continue',
'description']
result = self.instance.get('TEST')
keys = ['deny', 'permit']
self.assertEqual(sorted(keys), sorted(result.keys()))

def test_get_not_configured(self):
self.assertIsNone(self.instance.get('blah', 'blah', 1))
self.assertIsNone(self.instance.get('blah'))

def test_getall(self):
result = self.instance.getall()
Expand Down Expand Up @@ -110,12 +109,38 @@ def test_set_continue(self):
func = function('set_continue', 'TEST', 'permit', 10, 100)
self.eapi_positive_config_test(func, cmds)

def test_set_continue_with_invalid_integer(self):
with self.assertRaises(ValueError):
self.instance.set_continue('TEST', 'permit', 10, -1)

def test_set_continue_to_default(self):
cmds = ['route-map TEST permit 10', 'default continue']
func = function('set_continue', 'TEST', 'permit', 10, default=True)
self.eapi_positive_config_test(func, cmds)

def test_negate_continue(self):
cmds = ['route-map TEST permit 10', 'no continue']
func = function('set_continue', 'TEST', 'permit', 10)
self.eapi_positive_config_test(func, cmds)

def test_set_description_with_value(self):
value = random_string()
cmds = ['route-map TEST permit 10', 'no description',
'description %s' % value]
func = function('set_description', 'TEST', 'permit', 10, value)
self.eapi_positive_config_test(func, cmds)

def test_negate_description(self):
value = random_string()
cmds = ['route-map TEST permit 10', 'no description']
func = function('set_description', 'TEST', 'permit', 10)
self.eapi_positive_config_test(func, cmds)

def test_set_description_with_default(self):
value = random_string()
cmds = ['route-map TEST permit 10', 'default description']
func = function('set_description', 'TEST', 'permit', 10, default=True)
self.eapi_positive_config_test(func, cmds)

if __name__ == '__main__':
unittest.main()

0 comments on commit 2033504

Please sign in to comment.