quagga-reload.py should be importable

Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by:   Don Slice <dslice@cumulusnetworks.com>

Ticket: CM-12686
This commit is contained in:
Daniel Walton 2016-08-31 12:58:46 +00:00
parent 337299a936
commit a782e613dd

View File

@ -23,6 +23,9 @@ from ipaddr import IPv6Address
from pprint import pformat from pprint import pformat
log = logging.getLogger(__name__)
class Context(object): class Context(object):
""" """
@ -80,12 +83,12 @@ class Config(object):
The internal representation has been marked appropriately by passing it The internal representation has been marked appropriately by passing it
through vtysh with the -m parameter through vtysh with the -m parameter
""" """
logger.info('Loading Config object from file %s', filename) log.info('Loading Config object from file %s', filename)
try: try:
file_output = subprocess.check_output(['/usr/bin/vtysh', '-m', '-f', filename]) file_output = subprocess.check_output(['/usr/bin/vtysh', '-m', '-f', filename])
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
logger.error('vtysh marking of config file %s failed with error %s:', filename, str(e)) log.error('vtysh marking of config file %s failed with error %s:', filename, str(e))
print "vtysh marking of file %s failed with error: %s" % (filename, str(e)) print "vtysh marking of file %s failed with error: %s" % (filename, str(e))
sys.exit(1) sys.exit(1)
@ -105,14 +108,14 @@ class Config(object):
The internal representation has been marked appropriately by passing it The internal representation has been marked appropriately by passing it
through vtysh with the -m parameter through vtysh with the -m parameter
""" """
logger.info('Loading Config object from vtysh show running') log.info('Loading Config object from vtysh show running')
try: try:
config_text = subprocess.check_output( config_text = subprocess.check_output(
"/usr/bin/vtysh -c 'show run' | /usr/bin/tail -n +4 | /usr/bin/vtysh -m -f -", "/usr/bin/vtysh -c 'show run' | /usr/bin/tail -n +4 | /usr/bin/vtysh -m -f -",
shell=True) shell=True)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
logger.error('vtysh marking of running config failed with error %s:', str(e)) log.error('vtysh marking of running config failed with error %s:', str(e))
print "vtysh marking of running config failed with error %s:" % (str(e)) print "vtysh marking of running config failed with error %s:" % (str(e))
sys.exit(1) sys.exit(1)
@ -259,13 +262,13 @@ end
ctx_keys = [line, ] ctx_keys = [line, ]
current_context_lines = [] current_context_lines = []
logger.debug('LINE %-50s: entering new context, %-50s', line, ctx_keys) log.debug('LINE %-50s: entering new context, %-50s', line, ctx_keys)
self.save_contexts(ctx_keys, current_context_lines) self.save_contexts(ctx_keys, current_context_lines)
new_ctx = True new_ctx = True
elif line == "end": elif line == "end":
self.save_contexts(ctx_keys, current_context_lines) self.save_contexts(ctx_keys, current_context_lines)
logger.debug('LINE %-50s: exiting old context, %-50s', line, ctx_keys) log.debug('LINE %-50s: exiting old context, %-50s', line, ctx_keys)
# Start a new context # Start a new context
new_ctx = True new_ctx = True
@ -281,7 +284,7 @@ end
# Start a new context # Start a new context
ctx_keys = copy.deepcopy(main_ctx_key) ctx_keys = copy.deepcopy(main_ctx_key)
current_context_lines = [] current_context_lines = []
logger.debug('LINE %-50s: popping from subcontext to ctx%-50s', line, ctx_keys) log.debug('LINE %-50s: popping from subcontext to ctx%-50s', line, ctx_keys)
elif new_ctx is True: elif new_ctx is True:
if not main_ctx_key: if not main_ctx_key:
@ -292,7 +295,7 @@ end
current_context_lines = [] current_context_lines = []
new_ctx = False new_ctx = False
logger.debug('LINE %-50s: entering new context, %-50s', line, ctx_keys) log.debug('LINE %-50s: entering new context, %-50s', line, ctx_keys)
elif "address-family " in line: elif "address-family " in line:
main_ctx_key = [] main_ctx_key = []
@ -301,7 +304,7 @@ end
self.save_contexts(ctx_keys, current_context_lines) self.save_contexts(ctx_keys, current_context_lines)
current_context_lines = [] current_context_lines = []
main_ctx_key = copy.deepcopy(ctx_keys) main_ctx_key = copy.deepcopy(ctx_keys)
logger.debug('LINE %-50s: entering sub-context, append to ctx_keys', line) log.debug('LINE %-50s: entering sub-context, append to ctx_keys', line)
if line == "address-family ipv6": if line == "address-family ipv6":
ctx_keys.append("address-family ipv6 unicast") ctx_keys.append("address-family ipv6 unicast")
@ -313,7 +316,7 @@ end
else: else:
# Continuing in an existing context, add non-commented lines to it # Continuing in an existing context, add non-commented lines to it
current_context_lines.append(line) current_context_lines.append(line)
logger.debug('LINE %-50s: append to current_context_lines, %-50s', line, ctx_keys) log.debug('LINE %-50s: append to current_context_lines, %-50s', line, ctx_keys)
# Save the context of the last one # Save the context of the last one
self.save_contexts(ctx_keys, current_context_lines) self.save_contexts(ctx_keys, current_context_lines)
@ -699,7 +702,7 @@ if __name__ == '__main__':
# argparse should prevent this from happening but just to be safe... # argparse should prevent this from happening but just to be safe...
else: else:
raise Exception('Must specify --reload or --test') raise Exception('Must specify --reload or --test')
logger = logging.getLogger(__name__) log = logging.getLogger(__name__)
# Verify the new config file is valid # Verify the new config file is valid
if not os.path.isfile(args.filename): if not os.path.isfile(args.filename):
@ -728,9 +731,9 @@ if __name__ == '__main__':
sys.exit(1) sys.exit(1)
if args.debug: if args.debug:
logger.setLevel(logging.DEBUG) log.setLevel(logging.DEBUG)
logger.info('Called via "%s"', str(args)) log.info('Called via "%s"', str(args))
# Create a Config object from the config generated by newconf # Create a Config object from the config generated by newconf
newconf = Config() newconf = Config()
@ -777,7 +780,7 @@ if __name__ == '__main__':
elif args.reload: elif args.reload:
logger.debug('New Quagga Config\n%s', newconf.get_lines()) log.debug('New Quagga Config\n%s', newconf.get_lines())
# This looks a little odd but we have to do this twice...here is why # This looks a little odd but we have to do this twice...here is why
# If the user had this running bgp config: # If the user had this running bgp config:
@ -804,7 +807,7 @@ if __name__ == '__main__':
for x in range(2): for x in range(2):
running = Config() running = Config()
running.load_from_show_running() running.load_from_show_running()
logger.debug('Running Quagga Config (Pass #%d)\n%s', x, running.get_lines()) log.debug('Running Quagga Config (Pass #%d)\n%s', x, running.get_lines())
(lines_to_add, lines_to_del) = compare_context_objects(newconf, running) (lines_to_add, lines_to_del) = compare_context_objects(newconf, running)
@ -844,17 +847,17 @@ if __name__ == '__main__':
# 'no ip ospf authentication message-digest 1.1.1.1' in # 'no ip ospf authentication message-digest 1.1.1.1' in
# our example above # our example above
# - Split that last entry by whitespace and drop the last word # - Split that last entry by whitespace and drop the last word
logger.warning('Failed to execute %s', ' '.join(cmd)) log.warning('Failed to execute %s', ' '.join(cmd))
last_arg = cmd[-1].split(' ') last_arg = cmd[-1].split(' ')
if len(last_arg) <= 2: if len(last_arg) <= 2:
logger.error('"%s" we failed to remove this command', original_cmd) log.error('"%s" we failed to remove this command', original_cmd)
break break
new_last_arg = last_arg[0:-1] new_last_arg = last_arg[0:-1]
cmd[-1] = ' '.join(new_last_arg) cmd[-1] = ' '.join(new_last_arg)
else: else:
logger.info('Executed "%s"', ' '.join(cmd)) log.info('Executed "%s"', ' '.join(cmd))
break break
if lines_to_add: if lines_to_add:
@ -874,7 +877,7 @@ if __name__ == '__main__':
string.digits) for _ in range(6)) string.digits) for _ in range(6))
filename = "/var/run/quagga/reload-%s.txt" % random_string filename = "/var/run/quagga/reload-%s.txt" % random_string
logger.info("%s content\n%s" % (filename, pformat(lines_to_configure))) log.info("%s content\n%s" % (filename, pformat(lines_to_configure)))
with open(filename, 'w') as fh: with open(filename, 'w') as fh:
for line in lines_to_configure: for line in lines_to_configure: