diff options
Diffstat (limited to 'base/common/python/pki/cli/__init__.py')
-rw-r--r-- | base/common/python/pki/cli/__init__.py | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/base/common/python/pki/cli/__init__.py b/base/common/python/pki/cli/__init__.py new file mode 100644 index 000000000..2c51056f8 --- /dev/null +++ b/base/common/python/pki/cli/__init__.py @@ -0,0 +1,198 @@ +#!/usr/bin/python +# Authors: +# Endi S. Dewata <edewata@redhat.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Copyright (C) 2015 Red Hat, Inc. +# All rights reserved. +# + +import collections +import getopt +import sys + + +class CLI(object): + + def __init__(self, name, description): + + self.name = name + self.description = description + self.parent = None + + self.verbose = False + self.debug = False + + self.modules = collections.OrderedDict() + + def set_verbose(self, verbose): + self.verbose = verbose + if self.parent: + self.parent.set_verbose(verbose) + + def set_debug(self, debug): + self.debug = debug + if self.parent: + self.parent.set_debug(debug) + + def get_full_name(self): + if self.parent: + return self.parent.get_full_module_name(self.name) + return self.name + + def get_full_module_name(self, module_name): + return self.get_full_name() + '-' + module_name + + def add_module(self, module): + self.modules[module.name] = module + module.parent = self + + def get_module(self, name): + return self.modules.get(name) + + def get_top_module(self): + if self.parent: + return self.parent.get_top_module() + return self + + def print_message(self, message): + print '-' * len(message) + print message + print '-' * len(message) + + def print_help(self): + + print 'Commands:' + + for module in self.modules.itervalues(): + full_name = module.get_full_name() + print ' {:30}{:30}'.format(full_name, module.description) + + def find_module(self, command): + + module = self + + while True: + (module, command) = module.parse_command(command) + + if not module or not command: + return module + + def parse_command(self, command): + + # A command consists of parts joined by dashes: <part 1>-<part 2>-...-<part N>. + # For example: cert-request-find + + # The command will be split into module name and sub command, for example: + # - module name: cert + # - sub command: request-find + module_name = None + sub_command = None + + # Search the module by incrementally adding parts into module name. + # Repeat until it finds the module or until there is no more parts to add. + module = None + position = 0 + + while True: + + # Find the next dash. + i = command.find('-', position) + if i >= 0: + # Dash found. Split command into module name and sub command. + module_name = command[0:i] + sub_command = command[i+1:] + else: + # Dash not found. Use the whole command. + module_name = command + sub_command = None + + if self.debug: + print 'Module: %s' % module_name + + m = self.get_module(module_name) + if m: + # Module found. Check sub command. + if not sub_command: + # No sub command. Use this module. + module = m + break + + # There is a sub command. It must be processed by module's children. + if len(m.modules) > 0: + # Module has children. Use this module. + module = m + break + + # Module doesn't have children. Keep looking. + + # If there's no more dashes, stop. + if i < 0: + break + + position = i + 1 + + return (module, sub_command) + + def parse_args(self, args): + + command = args[0] + (module, sub_command) = self.parse_command(command) + + if not module: + raise Exception('Invalid module "%s".' % command) + + # Prepare module arguments. + if sub_command: + # If module command exists, include it as arguments: <module command> <args>... + module_args = [sub_command] + args[1:] + + else: + # Otherwise, pass the original arguments: <args>... + module_args = args[1:] + + return (module, module_args) + + def execute(self, argv): + + try: + opts, args = getopt.getopt(argv, 'v', [ + 'verbose', 'help']) + + except getopt.GetoptError as e: + print 'ERROR: ' + str(e) + self.print_help() + sys.exit(1) + + if len(args) == 0: + self.print_help() + sys.exit() + + for o, _ in opts: + if o in ('-v', '--verbose'): + self.set_verbose(True) + + elif o == '--help': + self.print_help() + sys.exit() + + else: + print 'ERROR: unknown option %s' % o + self.print_help() + sys.exit(1) + + (module, module_args) = self.parse_args(argv) + + module.execute(module_args) |