summaryrefslogtreecommitdiffstats
path: root/base/common/python/pki/cli/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'base/common/python/pki/cli/__init__.py')
-rw-r--r--base/common/python/pki/cli/__init__.py198
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)