>From 07135b5906f97a8c68148a07484e63d6896f410b Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Wed, 15 Mar 2017 08:13:35 +0100
Subject: [PATCH] Added cascading configuration for PKI CLI.

The PKI CLI has been modified to support cascading configuration
files: default, system-wide, and user-specific configuration.

The existing Python-based PKI CLI was moved into pki.cli.main
module. A new shell script was added as a replacement which will
read the configuration files and invoke the Python module.
---
 .../bin/pki => common/python/pki/cli/main.py}      |   0
 base/java-tools/bin/pki                            | 233 ++-------------------
 pylint-build-scan.py                               |  13 +-
 tox.ini                                            |   2 +-
 4 files changed, 20 insertions(+), 228 deletions(-)
 copy base/{java-tools/bin/pki => common/python/pki/cli/main.py} (100%)

diff --git a/base/java-tools/bin/pki b/base/common/python/pki/cli/main.py
similarity index 100%
copy from base/java-tools/bin/pki
copy to base/common/python/pki/cli/main.py
diff --git a/base/java-tools/bin/pki b/base/java-tools/bin/pki
index 53e1b893a7e7a5f80c309039e08507b1ddf9c85e..6060a6e112ea22645a1023e55543cd85dbfda1f8 100644
--- a/base/java-tools/bin/pki
+++ b/base/java-tools/bin/pki
@@ -1,7 +1,6 @@
-#!/usr/bin/python
-# Authors:
-#     Endi S. Dewata <edewata@redhat.com>
+#!/bin/sh
 #
+# --- BEGIN COPYRIGHT BLOCK ---
 # 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.
@@ -15,222 +14,26 @@
 # with this program; if not, write to the Free Software Foundation, Inc.,
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 #
-# Copyright (C) 2014 Red Hat, Inc.
+# Copyright (C) 2017 Red Hat, Inc.
 # All rights reserved.
+# --- END COPYRIGHT BLOCK ---
 #
 
-from __future__ import absolute_import
-from __future__ import print_function
-import shlex
-import subprocess
-import sys
-import traceback
+# default PKI configuration
+. /usr/share/pki/etc/pki.conf
 
-import pki.cli
-import pki.cli.pkcs12
+# system-wide PKI configuration
+if [ -f /etc/pki/pki.conf ]
+then
+    . /etc/pki/pki.conf
+fi
 
+# user-specific PKI configuration
+if [ -f $HOME/.dogtag/pki.conf ]
+then
+    . $HOME/.dogtag/pki.conf
+fi
 
-PYTHON_COMMANDS = ['pkcs12-import']
+python -m pki.cli.main "$@"
 
-
-class PKICLI(pki.cli.CLI):
-
-    def __init__(self):
-        super(PKICLI, self).__init__(
-            'pki', 'PKI command-line interface')
-
-        self.database = None
-        self.password = None
-        self.password_file = None
-        self.token = None
-
-        self.add_module(pki.cli.pkcs12.PKCS12CLI())
-
-    def get_full_module_name(self, module_name):
-        return module_name
-
-    def print_help(self):
-        print('Usage: pki [OPTIONS]')
-        print()
-        print('      --client-type <type>     PKI client type (default: java)')
-        print('   -d <path>                   Client security database location ' +
-              '(default: ~/.dogtag/nssdb)')
-        print('   -c <password>               Client security database password ' +
-              '(mutually exclusive to the -C option)')
-        print('   -C <path>                   Client-side password file ' +
-              '(mutually exclusive to the -c option)')
-        print('      --token <name>           Security token name')
-        print()
-        print('  -v, --verbose                Run in verbose mode.')
-        print('      --debug                  Show debug messages.')
-        print('      --help                   Show help message.')
-        print()
-
-        super(PKICLI, self).print_help()
-
-    def execute_java(self, args, stdout=sys.stdout):
-
-        # read Java home
-        value = subprocess.check_output(
-            '. /usr/share/pki/etc/pki.conf && . /etc/pki/pki.conf && echo $JAVA_HOME',
-            shell=True)
-        java_home = value.decode(sys.getfilesystemencoding()).strip()
-
-        # read PKI library
-        value = subprocess.check_output(
-            '. /usr/share/pki/etc/pki.conf && . /etc/pki/pki.conf && echo $PKI_LIB',
-            shell=True)
-        pki_lib = value.decode(sys.getfilesystemencoding()).strip()
-
-        # read logging configuration path
-        value = subprocess.check_output(
-            '. /usr/share/pki/etc/pki.conf && . /etc/pki/pki.conf && echo $LOGGING_CONFIG',
-            shell=True)
-        logging_config = value.decode(sys.getfilesystemencoding()).strip()
-
-        cmd = [
-            java_home + '/bin/java',
-            '-Djava.ext.dirs=' + pki_lib,
-            '-Djava.util.logging.config.file=' + logging_config,
-            'com.netscape.cmstools.cli.MainCLI'
-        ]
-
-        # restore options for Java commands
-
-        if self.database:
-            cmd.extend(['-d', self.database])
-
-        if self.password:
-            cmd.extend(['-c', self.password])
-
-        if self.password_file:
-            cmd.extend(['-C', self.password_file])
-
-        if self.token and self.token != 'internal':
-            cmd.extend(['--token', self.token])
-
-        if self.verbose:
-            cmd.extend(['--verbose'])
-
-        cmd.extend(args)
-
-        if self.verbose:
-            print('Java command: %s' % ' '.join(cmd))
-
-        subprocess.check_call(cmd, stdout=stdout)
-
-    def execute(self, argv):
-
-        # append global options
-        value = subprocess.check_output(
-            '. /usr/share/pki/etc/pki.conf && . /etc/pki/pki.conf && echo $PKI_CLI_OPTIONS',
-            shell=True)
-        value = value.decode(sys.getfilesystemencoding()).strip()
-        args = shlex.split(value)
-        args.extend(argv[1:])
-
-        client_type = 'java'
-
-        pki_options = []
-        command = None
-        cmd_args = []
-
-        # read pki options before the command
-        # remove options for Python module
-
-        i = 0
-        while i < len(args):
-            # if arg is a command, stop
-            if args[i][0] != '-':
-                command = args[i]
-                break
-
-            # get database path
-            if args[i] == '-d':
-                self.database = args[i + 1]
-                pki_options.append(args[i])
-                pki_options.append(args[i + 1])
-                i = i + 2
-
-            # get database password
-            elif args[i] == '-c':
-                self.password = args[i + 1]
-                pki_options.append(args[i])
-                pki_options.append(args[i + 1])
-                i = i + 2
-
-            # get database password file path
-            elif args[i] == '-C':
-                self.password_file = args[i + 1]
-                pki_options.append(args[i])
-                pki_options.append(args[i + 1])
-                i = i + 2
-
-            # get token name
-            elif args[i] == '--token':
-                self.token = args[i + 1]
-                pki_options.append(args[i])
-                pki_options.append(args[i + 1])
-                i = i + 2
-
-            # check verbose option
-            elif args[i] == '-v' or args[i] == '--verbose':
-                self.set_verbose(True)
-                pki_options.append(args[i])
-                i = i + 1
-
-            # check debug option
-            elif args[i] == '--debug':
-                self.set_verbose(True)
-                self.set_debug(True)
-                pki_options.append(args[i])
-                i = i + 1
-
-            # get client type
-            elif args[i] == '--client-type':
-                client_type = args[i + 1]
-                pki_options.append(args[i])
-                pki_options.append(args[i + 1])
-                i = i + 2
-
-            else:  # otherwise, save the arg for the next module
-                cmd_args.append(args[i])
-                i = i + 1
-
-        # save the rest of the args
-        while i < len(args):
-            cmd_args.append(args[i])
-            i = i + 1
-
-        if self.verbose:
-            print('PKI options: %s' % ' '.join(pki_options))
-            print('PKI command: %s %s' % (command, ' '.join(cmd_args)))
-
-        if client_type == 'python' or command in PYTHON_COMMANDS:
-            (module, module_args) = self.parse_args(cmd_args)
-            module.execute(module_args)
-
-        elif client_type == 'java':
-            self.execute_java(cmd_args)
-
-        else:
-            raise Exception('Unsupported client type: ' + client_type)
-
-
-if __name__ == '__main__':
-
-    cli = PKICLI()
-
-    try:
-        cli.execute(sys.argv)
-
-    except subprocess.CalledProcessError as e:
-        if cli.verbose:
-            print('ERROR: %s' % e)
-        elif cli.debug:
-            traceback.print_exc()
-        sys.exit(e.returncode)
-
-    except KeyboardInterrupt:
-        print()
-        sys.exit(-1)
+exit $?
diff --git a/pylint-build-scan.py b/pylint-build-scan.py
index d4156e87bdcd67d7aaac4b7053c77109d5b6e59c..3a7b4732137c4f1e20b1b7be21a49a8ea11f2013 100755
--- a/pylint-build-scan.py
+++ b/pylint-build-scan.py
@@ -38,7 +38,6 @@ PYLINTRC = os.path.join(SCRIPTPATH, 'dogtag.pylintrc')
 FILENAMES = [
     os.path.abspath(__file__),
     '{sitepackages}/pki',
-    '{bin}/pki-cmd',  # see HACK
     '{sbin}/pkispawn',
     '{sbin}/pkidestroy',
     '{sbin}/pki-upgrade',
@@ -130,17 +129,7 @@ def main():
     if args.verbose:
         pprint.pprint(pylint)
 
-    # HACK:
-    # pylint confuses the pki command with the pki package. We create a
-    # symlink from bin/pki to bin/pki-cmd and test bin/pki-cmd instead.
-    pki_bin = '{bin}/pki'.format(**env)
-    pki_cmd = '{bin}/pki-cmd'.format(**env)
-    os.symlink(pki_bin, pki_cmd)
-
-    try:
-        return subprocess.call(pylint, cwd=env['sitepackages'])
-    finally:
-        os.unlink(pki_cmd)
+    return subprocess.call(pylint, cwd=env['sitepackages'])
 
 if __name__ == '__main__':
     sys.exit(main())
diff --git a/tox.ini b/tox.ini
index 2430a95ee3ac13d1a4035081a4b2c1c08fc52d0d..f73818d9cd531db3b04014a3f07a4040c2c61370 100644
--- a/tox.ini
+++ b/tox.ini
@@ -92,7 +92,7 @@ python_files = tests/python/*.py
 [flake8]
 ignore = N802,N806,N812
 exclude = .tox,*.egg,dist,build,conf.py,tests/dogtag/*,.git
-filename = *.py,pki,pkidestroy,pki-upgrade,pki-server,pki-server-upgrade,pkispawn,[0-9][0-9]-*
+filename = *.py,pkidestroy,pki-upgrade,pki-server,pki-server-upgrade,pkispawn,[0-9][0-9]-*
 show-source = true
 max-line-length = 99
 # application-import-names = pki
-- 
2.9.3

