class Command(object): """ Command class representing a katello cli command @ivar name: command's name @ivar parser: optparse.OptionParser instance @ivar username: username credential @ivar password: password credential @ivar cert_file: certificate file credential @ivar key_file: private key file credential """ def __init__(self): """ @type actions: None or tuple/list of str's @param actoins: list of actions to expose, uses _default_actions if None """ self.cli = None self.name = None self._actions = {} self._action_order = [] @property def usage(self): """ Return a string showing the command's usage """ lines = ["Usage: %s <options> %s <action> <options>" % (self.cli.name, self.name), "Supported Actions:"] for name in self._action_order: action = self._actions[name] lines += self.__build_action_usage_lines(action) return "\n".join(lines) def __build_action_usage_lines(self, action): lines = [] desc_lines = action.description.split("\n") lines.append("\t%-14s %s" % (action.name, desc_lines.pop(0))) for l in desc_lines: lines.append("\t%-14s %s" % (" ", l)) return lines @property def description(self): """ Return a string showing the command's description """ return _("no description available") def add_action(self, name, action): """ Add an action to this command @note: actions are displayed in the order they are added @type name: str @param name: name to associate with the action @type action: L{Action} instance @param action: action to add """ action.cmd = self action.name = name self._action_order.append(name) self._actions[name] = action def action_names(self): return self._actions.keys() def get_action(self, name): return self._actions.get(name, None) def create_parser(self): self.parser = OptionParser(option_class=KatelloOption) self.parser.disable_interspersed_args() self.parser.set_usage(self.usage) return self.parser def process_options(self, parser, args): if not args: parser.error(_("no action given: please see --help")) parser.parse_args(args) def extract_action(self, args): action = self._actions.get(args[0], None) if action is None: self.parser.error(_("invalid action: please see --help")) return action def main(self, args): """ Main execution of a katello cli command This method parses options sent to the command itself, looks up the corresponding action, and calls that action's main() @warning: this method should only be overridden with care @type args: list of str's @param args: command line arguments to parse """ if type(args) == str: args = parse_tokens(args) try: parser = self.create_parser() self.process_options(parser, args) action = self.extract_action(args) return action.main(args[1:]) except OptionParserExitError, opee: return opee.args[0]
class KatelloCLI(object): """ Katello command line tool class. """ def __init__(self): self.name = os.path.basename(sys.argv[0]) self.opts = None self._server = None self._commands = {} self.usage_line = 'Usage: %s <options> <command>' % self.name self._username = None self._password = None self._certfile = None self._keyfile = None @property def usage(self): """ Usage string. @rtype: str @return: command's usage string """ lines = [self.usage_line, 'Supported Commands:'] for name, command in sorted(self._commands.items()): lines += self.__build_command_usage_lines(command) return '\n'.join(lines) def __build_command_usage_lines(self, command): lines = [] desc_lines = command.description.split("\n") lines.append('\t%-14s %s' % (command.name, desc_lines.pop(0)) ) for l in desc_lines: lines.append('\t%-14s %s' % (" ", l) ) return lines def add_command(self, name, command): """ Add a command to this command line tool @type name: str @param name: name to associate with the command @type command: L{katello.client.core.base.Command} instance @param command: command to add """ command.cli = self command.name = name self._commands[name] = command def remove_command(self, name): del self._commands[name] def setup_parser(self): """ Add options to the command line parser. @note: this method may be overridden to define new options """ self.parser = OptionParser() self.parser.disable_interspersed_args() self.parser.set_usage(self.usage) credentials = OptionGroup(self.parser, _('Katello User Account Credentials')) credentials.add_option('-u', '--username', dest='username', default=None, help=_('account username')) credentials.add_option('-p', '--password', dest='password', default=None, help=_('account password')) credentials.add_option('--cert-file', dest='certfile', default=None, help=SUPPRESS_HELP) credentials.add_option('--key-file', dest='keyfile', default=None, help=SUPPRESS_HELP) self.parser.add_option_group(credentials) server = OptionGroup(self.parser, _('Katello Server Information')) host = Config.parser.get('server', 'host') or 'localhost.localdomain' server.add_option('--host', dest='host', default=host, help=_('katello server host name (default: %s)') % host) port = Config.parser.get('server', 'port') or '443' server.add_option('--port', dest='port', default=port, help=SUPPRESS_HELP) scheme = Config.parser.get('server', 'scheme') or 'https' server.add_option('--scheme', dest='scheme', default=scheme, help=SUPPRESS_HELP) path = Config.parser.get('server', 'path') or '/katello/api' server.add_option('--path', dest='path', default=path, help=SUPPRESS_HELP) self.parser.add_option_group(server) def setup_server(self): """ Setup the active server connection. """ host = self.opts.host port = self.opts.port scheme = self.opts.scheme path = self.opts.path #print >> sys.stderr, 'server information: %s, %s, %s, %s' % \ # (host, port, scheme, path) self._server = server.KatelloServer(host, int(port), scheme, path) server.set_active_server(self._server) def setup_credentials(self): """ Setup up request credentials with the active server. """ try: self._username = self._username or self.opts.username self._password = self._password or self.opts.password self._certfile = self._certfile or self.opts.certfile self._keyfile = self._keyfile or self.opts.keyfile if None not in (self._username, self._password): self._server.set_basic_auth_credentials(self._username, self._password) elif None not in (self.opts.certfile, self.opts.keyfile): self._server.set_ssl_credentials(self.opts.certfile, self.opts.keyfile) else: self._server.set_kerberos_auth() except GSSError, e: raise KatelloError("Missing credentials and unable to authenticate using Kerberos", e) except Exception, e: raise KatelloError("Invalid credentials or unable to authenticate", e)