>From da192c7710c075269827bf4a8b32de83137b1771 Mon Sep 17 00:00:00 2001
From: Ade Lee <alee@redhat.com>
Date: Mon, 27 Apr 2015 15:29:26 -0400
Subject: [PATCH 250/251] Add ability to pki-server to enable/disable nuxwdog
 for an instance

This adds the ability to either enable or disable an instance using
the pki-server utility.  Additional documentation and additions to the
man pages will be added in a separate patch.
---
 base/server/python/pki/server/cli/instance.py | 117 ++++++++-
 base/server/python/pki/server/cli/nuxwdog.py  | 329 ++++++++++++++++++++++++++
 base/server/sbin/pki-server                   |   3 +
 3 files changed, 447 insertions(+), 2 deletions(-)
 create mode 100644 base/server/python/pki/server/cli/nuxwdog.py

diff --git a/base/server/python/pki/server/cli/instance.py b/base/server/python/pki/server/cli/instance.py
index b4a9ec05a803673adcf4d56441faf39cd23941f2..37db0398800b28412e85013e6fe0cda692abeb68 100644
--- a/base/server/python/pki/server/cli/instance.py
+++ b/base/server/python/pki/server/cli/instance.py
@@ -25,18 +25,22 @@ import sys
 
 import pki.cli
 import pki.server
+import pki.server.cli.nuxwdog
 
 
 class InstanceCLI(pki.cli.CLI):
 
     def __init__(self):
-        super(InstanceCLI, self).__init__('instance', 'Instance management commands')
+        super(InstanceCLI, self).__init__('instance',
+                                          'Instance management commands')
 
         self.add_module(InstanceFindCLI())
         self.add_module(InstanceShowCLI())
         self.add_module(InstanceStartCLI())
         self.add_module(InstanceStopCLI())
         self.add_module(InstanceMigrateCLI())
+        self.add_module(InstanceNuxwdogEnableCLI())
+        self.add_module(InstanceNuxwdogDisableCLI())
 
     @staticmethod
     def print_instance(instance):
@@ -252,6 +256,7 @@ class InstanceStopCLI(pki.cli.CLI):
 
         self.print_message('%s instance stopped' % instance_name)
 
+
 class InstanceMigrateCLI(pki.cli.CLI):
 
     def __init__(self):
@@ -317,6 +322,114 @@ class InstanceMigrateCLI(pki.cli.CLI):
         instance = pki.server.PKIInstance(instance_name)
         instance.load()
 
-        module.migrate(instance, tomcat_version) # pylint: disable=no-member,maybe-no-member
+        module.migrate(instance, tomcat_version)  # pylint: disable=no-member,maybe-no-member
 
         self.print_message('%s instance migrated' % instance_name)
+
+
+class InstanceNuxwdogEnableCLI(pki.cli.CLI):
+
+    def __init__(self):
+        super(InstanceNuxwdogEnableCLI, self).__init__(
+            'nuxwdog-enable',
+            'Instance enable nuxwdog')
+
+    def print_help(self):
+        print 'Usage: pki-server instance-nuxwdog-enable [OPTIONS] <instance ID>'
+        print
+        print '  -v, --verbose                Run in verbose mode.'
+        print '      --help                   Show help message.'
+        print
+
+    def execute(self, argv):
+        try:
+            opts, args = getopt.getopt(argv, 'i:v', [
+                'verbose', 'help'])
+
+        except getopt.GetoptError as e:
+            print 'ERROR: ' + str(e)
+            self.print_help()
+            sys.exit(1)
+
+        if len(args) != 1:
+            print 'ERROR: missing instance ID'
+            self.print_help()
+            sys.exit(1)
+
+        instance_name = args[0]
+
+        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 ' + o
+                self.print_help()
+                sys.exit(1)
+
+        #module = self.top.find_module('nuxwdog-enable')
+        module = pki.server.cli.nuxwdog.NuxwdogEnableCLI()
+        module.set_verbose(self.verbose)
+
+        instance = pki.server.PKIInstance(instance_name)
+        instance.load()
+
+        module.enable_nuxwdog(instance)  # pylint: disable=no-member,maybe-no-member
+
+        self.print_message('nuxwdog enabled for instance %s' % instance_name)
+
+
+class InstanceNuxwdogDisableCLI(pki.cli.CLI):
+
+    def __init__(self):
+        super(InstanceNuxwdogDisableCLI, self).__init__(
+            'nuxwdog-disable',
+            'Instance disable nuxwdog')
+
+    def print_help(self):
+        print 'Usage: pki-server instance-nuxwdog-disable [OPTIONS] <instance ID>'
+        print
+        print '  -v, --verbose                Run in verbose mode.'
+        print '      --help                   Show help message.'
+        print
+
+    def execute(self, argv):
+        try:
+            opts, args = getopt.getopt(argv, 'i:v', [
+                'verbose', 'help'])
+
+        except getopt.GetoptError as e:
+            print 'ERROR: ' + str(e)
+            self.print_help()
+            sys.exit(1)
+
+        if len(args) != 1:
+            print 'ERROR: missing instance ID'
+            self.print_help()
+            sys.exit(1)
+
+        instance_name = args[0]
+
+        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 ' + o
+                self.print_help()
+                sys.exit(1)
+
+        # module = self.top.find_module('nuxwdog-disable')
+        module = pki.server.cli.nuxwdog.NuxwdogDisableCLI()
+        module.set_verbose(self.verbose)
+
+        instance = pki.server.PKIInstance(instance_name)
+        instance.load()
+
+        module.disable_nuxwdog(instance)  # pylint: disable=no-member,maybe-no-member
+
+        self.print_message('nuxwdog disabled for instance %s' % instance_name)
diff --git a/base/server/python/pki/server/cli/nuxwdog.py b/base/server/python/pki/server/cli/nuxwdog.py
new file mode 100644
index 0000000000000000000000000000000000000000..d439dd7dbb2608269600507b2267c38a322b91bf
--- /dev/null
+++ b/base/server/python/pki/server/cli/nuxwdog.py
@@ -0,0 +1,329 @@
+#!/usr/bin/python
+# Authors:
+#     Ade Lee <alee@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 getopt
+import fileinput
+import os
+import re
+import struct
+import subprocess
+import sys
+
+from lxml import etree
+
+import pki.cli
+import pki.server
+
+
+class NuxwdogCLI(pki.cli.CLI):
+
+    def __init__(self):
+        super(NuxwdogCLI, self).__init__(
+            'nuxwdog',
+            'Nuxwdog related commands')
+        self.add_module(NuxwdogEnableCLI())
+        self.add_module(NuxwdogDisableCLI())
+
+
+class NuxwdogEnableCLI(pki.cli.CLI):
+
+    def __init__(self):
+        self.parser = etree.XMLParser(remove_blank_text=True)
+        self.nuxwdog_listener_class = (
+            'com.netscape.cms.tomcat.NuxwdogPasswordStoreInitializer'
+        )
+        self.nuxwdog_pwstore_class = (
+            'com.netscape.cms.tomcat.NuxwdogPasswordStore'
+        )
+        super(NuxwdogEnableCLI, self).__init__(
+            'enable',
+            'Enable nuxwdog')
+
+    def print_help(self):
+        print 'Usage: pki-server nuxwdog-enable [OPTIONS]'
+        print
+        print '  -v, --verbose                Run in verbose mode.'
+        print '      --help                   Show help message.'
+        print
+
+    def execute(self, argv):
+        try:
+            opts, _ = getopt.getopt(argv, 'i:v', [
+                'verbose', 'help'])
+
+        except getopt.GetoptError as e:
+            print 'ERROR: ' + str(e)
+            self.print_help()
+            sys.exit(1)
+
+        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 ' + o
+                self.print_help()
+                sys.exit(1)
+
+        instances = pki.server.PKIServer.instances()
+
+        for instance in instances:
+            self.enable_nuxwdog(instance)
+
+        self.print_message('Nuxwdog enabled for system.')
+
+    def enable_nuxwdog(self, instance):
+        # add nuxwdog link
+        self.add_nuxwdog_link(instance)
+
+        # modify sysconfig file
+        self.enable_nuxwdog_sysconfig_file(instance)
+
+        # create nuxwdog conf file
+        subprocess.call(['pki-server-nuxwdog', instance.name])
+
+        # modify server.xml
+        server_xml = os.path.join(instance.conf_dir, 'server.xml')
+        self.enable_nuxwdog_server_xml(server_xml, instance)
+
+    def add_nuxwdog_link(self, instance):
+        nuxwdog_jar_path = '/usr/lib/java/nuxwdog.jar'
+        if not os.path.exists(nuxwdog_jar_path):
+            print (
+                "Error: nuxwdog jar file does not exist.  "
+                "Is nuxwdog installed?"
+            )
+            sys.exit(1)
+        instance_jar_path = os.path.join(
+            instance.base_dir,
+            'common',
+            'lib',
+            'nuxwdog.jar')
+
+        if os.path.exists(instance_jar_path):
+            os.remove(instance_jar_path)
+
+        os.symlink(nuxwdog_jar_path, instance_jar_path)
+
+    def enable_nuxwdog_sysconfig_file(self, instance):
+        sysconfig_file = os.path.join('/etc/sysconfig', instance.name)
+
+        arch = struct.calcsize("P") * 8
+        if arch == 64:
+            jni_str = "-Djava.library.path=/usr/lib64/nuxwdog-jni"
+        else:
+            jni_str = "-Djava.library.path=/usr/lib/nuxwdog-jni"
+
+        got_use_nuxwdog = False
+
+        for line in fileinput.input(sysconfig_file, inplace=1):
+            match = re.search("^JAVA_OPTS=\"(.*)\"", line)
+            if match:
+                opts = match.group(1)
+                if jni_str not in opts:
+                    line = "JAVA_OPTS=\"" + opts + " " + jni_str + "\"\n"
+
+            match = re.search("^USE_NUXWDOG=.*", line)
+            if match:
+                line = "USE_NUXWDOG=\"true\"\n"
+                got_use_nuxwdog = True
+
+            sys.stdout.write(line)
+
+        if not got_use_nuxwdog:
+            with open(sysconfig_file, 'a') as f:
+                f.write("USE_NUXWDOG=\"true\"\n")
+
+    def get_conf_file(self, instance):
+        if not instance.subsystems:
+            print "Error: Instance has no subsystems."
+            sys.exit(1)
+
+        # return the path to the first instance
+        subsystem = instance.subsystems[0]
+        return os.path.join(subsystem.conf_dir, 'CS.cfg')
+
+    def enable_nuxwdog_server_xml(self, filename, instance):
+        if self.verbose:
+            print 'Enabling nuxwdog in %s' % filename
+
+        conf_file = self.get_conf_file(instance)
+
+        document = etree.parse(filename, self.parser)
+
+        server = document.getroot()
+
+        global_naming_resources = None
+
+        nuxwdog_listener = etree.Element('Listener')
+        nuxwdog_listener.set('className', self.nuxwdog_listener_class)
+
+        children = list(server)
+        for child in children:
+
+            if child.tag == 'Listener':
+                class_name = child.get('className')
+                if class_name == self.nuxwdog_listener_class:
+                    nuxwdog_listener = None
+            elif child.tag == 'GlobalNamingResources':
+                global_naming_resources = child
+
+        # add before GlobalResourcesLifecycleListener if exists
+        if global_naming_resources is not None:
+            index = list(server).index(global_naming_resources)
+        else:
+            index = 0
+
+        if nuxwdog_listener is not None:
+            server.insert(index, nuxwdog_listener)
+
+        connectors = server.findall('Service/Connector')
+        for connector in connectors:
+            if connector.get('secure') == 'true':
+                connector.set('passwordClass', self.nuxwdog_pwstore_class)
+                connector.set('passwordFile', conf_file)
+
+        with open(filename, 'w') as f:
+            f.write(etree.tostring(document, pretty_print=True))
+
+
+class NuxwdogDisableCLI(pki.cli.CLI):
+
+    def __init__(self):
+        self.parser = etree.XMLParser(remove_blank_text=True)
+        self.nuxwdog_listener_class = (
+            'com.netscape.cms.tomcat.NuxwdogPasswordStoreInitializer'
+        )
+        self.plain_pwstore_class = (
+            'org.apache.tomcat.util.net.jss.PlainPasswordFile'
+        )
+        super(NuxwdogDisableCLI, self).__init__(
+            'disable',
+            'Disable nuxwdog')
+
+    def print_help(self):
+        print 'Usage: pki-server nuxwdog-disable [OPTIONS]'
+        print
+        print '  -v, --verbose                Run in verbose mode.'
+        print '      --help                   Show help message.'
+        print
+
+    def execute(self, argv):
+        try:
+            opts, _ = getopt.getopt(argv, 'i:v', [
+                'verbose', 'help'])
+
+        except getopt.GetoptError as e:
+            print 'ERROR: ' + str(e)
+            self.print_help()
+            sys.exit(1)
+
+        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 ' + o
+                self.print_help()
+                sys.exit(1)
+
+        instances = pki.server.PKIServer.instances()
+
+        for instance in instances:
+            self.disable_nuxwdog(instance)
+
+        self.print_message('Nuxwdog disabled for system.')
+
+    def disable_nuxwdog(self, instance):
+        self.disable_nuxwdog_sysconfig_file(instance)
+        self.remove_nuxwdog_link(instance)
+
+        nuxwdog_conf = os.path.join(instance.conf_dir, 'nuxwdog.conf')
+        if os.path.exists(nuxwdog_conf):
+            os.remove(nuxwdog_conf)
+
+        server_xml = os.path.join(instance.conf_dir, 'server.xml')
+        self.disable_nuxwdog_server_xml(server_xml, instance)
+
+    def disable_nuxwdog_sysconfig_file(self, instance):
+        sysconfig_file = os.path.join('/etc/sysconfig', instance.name)
+
+        arch = struct.calcsize("P") * 8
+        if arch == 64:
+            jni_str = "-Djava.library.path=/usr/lib64/nuxwdog-jni"
+        else:
+            jni_str = "-Djava.library.path=/usr/lib/nuxwdog-jni"
+
+        for line in fileinput.input(sysconfig_file, inplace=1):
+            match = re.search("^JAVA_OPTS=\"(.*)\"", line)
+            if match:
+                opts = match.group(1)
+                line = "JAVA_OPTS=\"" + opts.replace(jni_str, '') + "\"\n"
+
+            match = re.search("^USE_NUXWDOG=.*", line)
+            if match:
+                line = "USE_NUXWDOG=\"false\"\n"
+
+            sys.stdout.write(line)
+
+    def remove_nuxwdog_link(self, instance):
+        instance_jar_path = os.path.join(
+            instance.base_dir,
+            'common',
+            'lib',
+            'nuxwdog.jar')
+
+        if os.path.exists(instance_jar_path):
+            os.remove(instance_jar_path)
+
+    def disable_nuxwdog_server_xml(self, filename, instance):
+        if self.verbose:
+            print 'Disabling nuxwdog in %s' % filename
+
+        pw_conf = os.path.join(instance.conf_dir, 'password.conf')
+
+        document = etree.parse(filename, self.parser)
+
+        server = document.getroot()
+
+        children = list(server)
+        for child in children:
+            if child.tag == 'Listener':
+                class_name = child.get('className')
+                if class_name == self.nuxwdog_listener_class:
+                    server.remove(child)
+
+        connectors = server.findall('Service/Connector')
+        for connector in connectors:
+            if connector.get('secure') == 'true':
+                connector.set('passwordClass', self.plain_pwstore_class)
+                connector.set('passwordFile', pw_conf)
+
+        with open(filename, 'w') as f:
+            f.write(etree.tostring(document, pretty_print=True))
diff --git a/base/server/sbin/pki-server b/base/server/sbin/pki-server
index 2fb41bd146eebdd1ee9b81854e731f01e3adcd67..627a4765ece87d9c98a973aef00fb5fea69f361f 100644
--- a/base/server/sbin/pki-server
+++ b/base/server/sbin/pki-server
@@ -26,6 +26,8 @@ import pki.cli
 import pki.server.cli.instance
 import pki.server.cli.subsystem
 import pki.server.cli.migrate
+import pki.server.cli.nuxwdog
+
 
 class PKIServerCLI(pki.cli.CLI):
 
@@ -36,6 +38,7 @@ class PKIServerCLI(pki.cli.CLI):
         self.add_module(pki.server.cli.instance.InstanceCLI())
         self.add_module(pki.server.cli.subsystem.SubsystemCLI())
         self.add_module(pki.server.cli.migrate.MigrateCLI())
+        self.add_module(pki.server.cli.nuxwdog.NuxwdogCLI())
 
     def get_full_module_name(self, module_name):
         return module_name
-- 
1.9.3

