Skip to content

Commit

Permalink
Changed parsing structure into separated files
Browse files Browse the repository at this point in the history
  • Loading branch information
nepJIywa committed Sep 3, 2018
1 parent c8f1fd6 commit 20cc264
Show file tree
Hide file tree
Showing 8 changed files with 320 additions and 288 deletions.
381 changes: 95 additions & 286 deletions parsing.py

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion parsing_checks/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__all__ = ["ip_iface","port_security","storm_control","stp_global","vtp"]
__all__ = ["ip_iface","port_security","storm_control","stp_global","vtp","username","aaa","ssh","http","lines"]
38 changes: 38 additions & 0 deletions parsing_checks/aaa.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Parse AAA options
# Input:
# line with AAA options, type of AAA, login count
# login default group radius local, authentication, 1
# Output:
# AAA option dictionary
# {'login1': {'list': 'default', 'methods': ['radius', 'local']}}
from pyparsing import Word,Suppress,printables,restOfLine,OneOrMore,MatchFirst,Optional


def _globalParse___aaa_attributes(line, type, count_aaa):
aaa_dict = {}

parse_authentication_options = Suppress('login') + Word(printables) + OneOrMore(Optional(Suppress('group')) + Word(printables))
parse_authorization_options = MatchFirst(['exec', 'login']) + Word(printables) + OneOrMore(Optional(Suppress('group')) + Word(printables))
parse_accounting_options = MatchFirst(['exec', 'network']) + Word(printables) +\
MatchFirst(['start-stop', 'stop-only', 'stop']) + OneOrMore(Optional(Suppress('group')) + Word(printables))

if type == 'authentication':
result = parse_authentication_options.parseString(line)
aaa_dict.update({'login' + str(count_aaa): {}})
aaa_dict['login' + str(count_aaa)]['list'] = result.pop(0)
aaa_dict['login' + str(count_aaa)]['methods'] = result.asList()
elif type == 'authorization':
result = parse_authorization_options.parseString(line)
aaa_dict.update({'login' + str(count_aaa): {}})
aaa_dict['login' + str(count_aaa)]['login'] = result.pop(0)
aaa_dict['login' + str(count_aaa)]['list'] = result.pop(0)
aaa_dict['login' + str(count_aaa)]['methods'] = result.asList()
elif type == 'accounting':
result = parse_accounting_options.parseString(line)
aaa_dict.update({'login' + str(count_aaa): {}})
aaa_dict['login' + str(count_aaa)]['login'] = result.pop(0)
aaa_dict['login' + str(count_aaa)]['list'] = result.pop(0)
aaa_dict['login' + str(count_aaa)]['record'] = result.pop(0)
aaa_dict['login' + str(count_aaa)]['methods'] = result.asList()

return aaa_dict
20 changes: 20 additions & 0 deletions parsing_checks/http.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Parse HTTP options
# Input:
# line with http option
# ip http secure-server
# Output:
# http option dictionary
# {'type': 'HTTPS'}
def _globalParse___http_attributes(line):
http_dict = {}

if line == 'server':
http_dict['type'] = 'http'
elif line == 'secure-server':
http_dict['type'] = 'https'
elif line.split()[0] == 'max-connections':
http_dict['max_connections'] = line.split()[-1]
elif line.split()[0] == 'port':
http_dict['port'] = line.split()[-1]

return http_dict
80 changes: 80 additions & 0 deletions parsing_checks/lines.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Parse console and vty line options
# Input:
# line with console or vty line name
# vty 0 4
# Output:
# console or line options dictionary, next line (otherwise program will skip next line due to cursor placement)
# {'log_syng': 'no', 'access-class': {'name': 'ssh-in', 'type': 'in'}, 'privilege': '15'}, 'line vty 5 15'
import util
from pyparsing import Word,alphas,MatchFirst,restOfLine,Suppress,Optional,ParseException


def _globalParse___line_attributes(config):
line_list, next_line = util.get_attributes(config)
line_dict = {'log_syng': 'no', 'no_exec': 'no', 'access-class': {}}

parse_login_type = Suppress('login ' + Optional('authentication ')) + restOfLine
parse_exec_timeout = Suppress('exec-timeout ') + restOfLine
parse_pass_type = Suppress('password ') + restOfLine
parse_privilege = Suppress('privilege level ') + restOfLine
parse_transp_in = Suppress('transport input ') + restOfLine
parse_transp_out = Suppress('transport output ') + restOfLine
parse_rotary = Suppress('rotary ') + restOfLine
parse_access_class = Suppress('access-class') + Word(alphas + '-') + MatchFirst(['in', 'out']) + Suppress(Optional(restOfLine))

for option in line_list:
if option == 'logging synchronous':
line_dict['log_syng'] = 'yes'
continue
if option == 'no exec':
line_dict['no_exec'] = 'yes'
continue
try:
item = parse_exec_timeout.parseString(option).asList()[-1]
item = item.split()
if len(item) == 2:
line_dict['exec_timeout'] = int(item[0]) + int(item[1]) / 60
else:
line_dict['exec_timeout'] = int(item[0])
continue
except ParseException:
pass
try:
line_dict['login_type'] = parse_login_type.parseString(option).asList()[-1]
continue
except ParseException:
pass
try:
line_dict['pass_type'] = parse_pass_type .parseString(option).asList()[-1]
continue
except ParseException:
pass
try:
line_dict['privilege'] = parse_privilege .parseString(option).asList()[-1]
continue
except ParseException:
pass
try:
line_dict['transp_in'] = parse_transp_in .parseString(option).asList()[-1]
continue
except ParseException:
pass
try:
line_dict['transp_out'] = parse_transp_out.parseString(option).asList()[-1]
continue
except ParseException:
pass
try:
line_dict['rotary'] = parse_rotary .parseString(option).asList()[-1]
continue
except ParseException:
pass
try:
item = parse_access_class.parseString(option).asList()
line_dict['access-class']['name'] = item[0]
line_dict['access-class']['type'] = item[-1]
continue
except ParseException:
pass

return line_dict, next_line
32 changes: 32 additions & 0 deletions parsing_checks/ssh.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Parse SSH options
# Input:
# line with ssh option
# ip ssh time-out 30
# Output:
# ssh option dictionary
# {'time-out': '30'}
from pyparsing import Word,alphas,White,restOfLine


def _globalParse___ssh_attributes(line):
ssh_dict = {}

ssh_option = (Word(alphas + '-'))('option')
ssh_value = (restOfLine) ('value')

result = (ssh_option + White() + ssh_value).parseString(line)

if result.option == 'logging':
ssh_dict['logging-events'] = 'yes'
elif result.option == 'authentication-retries':
ssh_dict['authentication_retries'] = result.value.split()[0]
elif result.option == 'port':
ssh_dict['port_rotary'] = result.value.split()[0]
elif result.option == 'maxstartups':
ssh_dict['maxstartups'] = result.value.split()[0]
elif result.option == 'time-out':
ssh_dict['time-out'] = result.value.split()[0]
elif result.option == 'version':
ssh_dict['version'] = result.value.split()[0]

return ssh_dict
30 changes: 30 additions & 0 deletions parsing_checks/username.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Parse username options
# Input:
# line with user options
# vasya privilege 15 secret 5 $1$0k5Q$3h/ZPjj8T0iHu9DL/Ejt30
# Output:
# user's options dictionary
# {'vasya': {'password_type': '5', 'privilege': '15'}}
from pyparsing import Word,Suppress,printables,restOfLine,nums,MatchFirst,Optional


def _globalParse___username_attributes(line):
username_dict = {}

username = (Word(printables)) ('user')
privilege = (Suppress('privilege') + Word(nums)) ('priv_num')
password_type = (Suppress(MatchFirst(['secret', 'password'])) + Word(nums))('pass_type')

parse_username = username + Optional(privilege) + password_type + Suppress(restOfLine)

result = parse_username.parseString(line)

username_dict[result.user] = {}
username_dict[result.user]['password_type'] = result.pass_type.asList()[0]

try:
username_dict[result.user]['privilege'] = result.priv_num.asList()[0]
except AttributeError:
pass

return username_dict
25 changes: 24 additions & 1 deletion util.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# library with different useful functions to use them within various modules
from pyparsing import White,restOfLine,Suppress,Optional

# converts string list of numbers to list of ints with those numbers
# ['1','2','3'] -> [1,2,3]
Expand All @@ -14,4 +15,26 @@ def int_dict_parse(parse_meth,featur_str,name,featur_dict):

value = parse_meth.parseString(featur_str).asList()
featur_dict[name] = value
return featur_dict
return featur_dict


# Parse any attributes with whitespace as first symbol into list
# Input:
# line with futher options (starts with whitespaces)
# interface Loopback1
# Output:
# further options list, next line (otherwise program may skip next line due to cursor placement)
# ['description -= MGMT - core.nnn048.nnn =-', 'ip address 172.21.24.140 255.255.255.255'], '!'
def get_attributes(config):
options_list = []
option = White(exact=1) + Suppress(Optional(White())) + restOfLine
next_line = config.readline()
try:
option_parse = option.parseString(next_line)
while option_parse[0] == ' ':
options_list.append(option_parse[-1])
next_line = config.readline()
option_parse = option.parseString(next_line)
except:
pass
return options_list, next_line

0 comments on commit 20cc264

Please sign in to comment.