merged cleanup branch with master

This commit is contained in:
Rod A Santiago 2017-06-19 18:09:28 -07:00
parent 0a91fe7a3e
commit 55a6e2dcef
81 changed files with 11596 additions and 15021 deletions

View file

@ -6,29 +6,31 @@
#
# author: Jeff Ahrenholz <jeffrey.m.ahrenholz@boeing.com>
#
'''
"""
core-manage: Helper tool to add, remove, or check for services, models, and
node types in a CORE installation.
'''
"""
import os
import sys
import ast
import optparse
import os
import re
import sys
from core import pycore
from core import services
from core.constants import CORE_CONF_DIR
class FileUpdater(object):
''' Helper class for changing configuration files.
'''
"""
Helper class for changing configuration files.
"""
actions = ("add", "remove", "check")
targets = ("service", "model", "nodetype")
def __init__(self, action, target, data, options):
'''
'''
"""
"""
self.action = action
self.target = target
self.data = data
@ -37,13 +39,13 @@ class FileUpdater(object):
self.search, self.filename = self.get_filename(target)
def process(self):
''' Invoke update_file() using a helper method depending on target.
'''
""" Invoke update_file() using a helper method depending on target.
"""
if self.verbose:
txt = "Updating"
if self.action == "check":
txt = "Checking"
sys.stdout.write("%s file: '%s'\n" % (txt, self.filename))
sys.stdout.write("%s file: %s\n" % (txt, self.filename))
if self.target == "service":
r = self.update_file(fn=self.update_services)
@ -64,41 +66,40 @@ class FileUpdater(object):
return r
def update_services(self, line):
''' Modify the __init__.py file having this format:
""" Modify the __init__.py file having this format:
__all__ = ["quagga", "nrl", "xorp", "bird", ]
Returns True or False when "check" is the action, a modified line
otherwise.
'''
line = line.strip('\n')
key, valstr = line.split('= ')
"""
line = line.strip("\n")
key, valstr = line.split("= ")
vals = ast.literal_eval(valstr)
r = self.update_keyvals(key, vals)
if self.action == "check":
return r
valstr = '%s' % r
return '= '.join([key, valstr]) + '\n'
valstr = "%s" % r
return "= ".join([key, valstr]) + "\n"
def update_emane_models(self, line):
''' Modify the core.conf file having this format:
""" Modify the core.conf file having this format:
emane_models = RfPipe, Ieee80211abg, CommEffect, Bypass
Returns True or False when "check" is the action, a modified line
otherwise.
'''
line = line.strip('\n')
key, valstr = line.split('= ')
vals = valstr.split(', ')
"""
line = line.strip("\n")
key, valstr = line.split("= ")
vals = valstr.split(", ")
r = self.update_keyvals(key, vals)
if self.action == "check":
return r
valstr = ', '.join(r)
return '= '.join([key, valstr]) + '\n'
valstr = ", ".join(r)
return "= ".join([key, valstr]) + "\n"
def update_keyvals(self, key, vals):
''' Perform self.action on (key, vals).
""" Perform self.action on (key, vals).
Returns True or False when "check" is the action, a modified line
otherwise.
'''
"""
if self.action == "check":
if self.data in vals:
return True
@ -115,11 +116,10 @@ class FileUpdater(object):
return vals
def get_filename(self, target):
''' Return search string and filename based on target.
'''
""" Return search string and filename based on target.
"""
if target == "service":
pypath = os.path.dirname(pycore.__file__)
filename = os.path.join(pypath, "services", "__init__.py")
filename = os.path.abspath(services.__file__)
search = "__all__ ="
elif target == "model":
filename = os.path.join(CORE_CONF_DIR, "core.conf")
@ -132,21 +132,21 @@ class FileUpdater(object):
else:
raise ValueError, "unknown target"
if not os.path.exists(filename):
raise ValueError, "file '%s' does not exist" % filename
raise ValueError, "file %s does not exist" % filename
return search, filename
def update_file(self, fn=None):
''' Open a file and search for self.search, invoking the supplied
""" Open a file and search for self.search, invoking the supplied
function on the matching line. Write file changes if necessary.
Returns True if the file has changed (or action is "check" and the
search string is found), False otherwise.
'''
"""
changed = False
output = "" # this accumulates output, assumes input is small
output = "" # this accumulates output, assumes input is small
with open(self.filename, "r") as f:
for line in f:
if line[:len(self.search)] == self.search:
r = fn(line) # line may be modified by fn() here
r = fn(line) # line may be modified by fn() here
if self.action == "check":
return r
else:
@ -157,17 +157,17 @@ class FileUpdater(object):
if changed:
with open(self.filename, "w") as f:
f.write(output)
return changed
def update_nodes_conf(self):
''' Add/remove/check entries from nodes.conf. This file
""" Add/remove/check entries from nodes.conf. This file
contains a Tcl-formatted array of node types. The array index must be
properly set for new entries. Uses self.{action, filename, search,
data} variables as input and returns the same value as update_file().
'''
"""
changed = False
output = "" # this accumulates output, assumes input is small
output = "" # this accumulates output, assumes input is small
with open(self.filename, "r") as f:
for line in f:
# make sure data is not added twice
@ -181,14 +181,15 @@ class FileUpdater(object):
continue
else:
output += line
if self.action == "add":
index = int(re.match('^\d+', line).group(0))
output += str(index + 1) + ' ' + self.data + '\n'
index = int(re.match("^\d+", line).group(0))
output += str(index + 1) + " " + self.data + "\n"
changed = True
if changed:
with open(self.filename, "w") as f:
f.write(output)
return changed
@ -200,21 +201,21 @@ def main():
usagestr += "\n %prog -v check model RfPipe"
usagestr += "\n %prog --userpath=\"$HOME/.core\" add nodetype \"{ftp ftp.gif ftp.gif {DefaultRoute FTP} netns {FTP server} }\" \n"
usagestr += "\nArguments:\n <action> should be one of: %s" % \
', '.join(FileUpdater.actions)
", ".join(FileUpdater.actions)
usagestr += "\n <target> should be one of: %s" % \
', '.join(FileUpdater.targets)
", ".join(FileUpdater.targets)
usagestr += "\n <string> is the text to %s" % \
', '.join(FileUpdater.actions)
parser = optparse.OptionParser(usage = usagestr)
parser.set_defaults(userpath = None, verbose = False,)
", ".join(FileUpdater.actions)
parser = optparse.OptionParser(usage=usagestr)
parser.set_defaults(userpath=None, verbose=False, )
parser.add_option("--userpath", dest = "userpath", type = "string",
help = "use the specified user path (e.g. \"$HOME/.core" \
"\") to access nodes.conf")
parser.add_option("-v", "--verbose", dest = "verbose", action="store_true",
help = "be verbose when performing action")
parser.add_option("--userpath", dest="userpath", type="string",
help="use the specified user path (e.g. \"$HOME/.core" \
"\") to access nodes.conf")
parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
help="be verbose when performing action")
def usage(msg = None, err = 0):
def usage(msg=None, err=0):
sys.stdout.write("\n")
if msg:
sys.stdout.write(msg + "\n\n")
@ -228,11 +229,11 @@ def main():
action = args[0]
if action not in FileUpdater.actions:
usage("invalid action '%s'" % action, 1)
usage("invalid action %s" % action, 1)
target = args[1]
if target not in FileUpdater.targets:
usage("invalid target '%s'" % target, 1)
usage("invalid target %s" % target, 1)
if target == "nodetype" and not options.userpath:
usage("user path option required for this target (%s)" % target)
@ -249,5 +250,6 @@ def main():
sys.exit(1)
sys.exit(0)
if __name__ == "__main__":
main()