Blob Blame History Raw
From bbdb82268026821cd6a00edae09cc30079effd30 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Tue, 8 Mar 2022 15:19:09 -0600
Subject: [PATCH] Fix pki-server migrate CLI

The pki-server migrate CLI has been modified to configure the
AJP connectors with either secret or requiredSecret parameter
(mutually exclusive) depending on the Tomcat version.

https://bugzilla.redhat.com/show_bug.cgi?id=2061458
---
 base/server/python/pki/server/cli/migrate.py |  60 ----------
 base/server/python/pki/server/instance.py    | 118 +++++++++++++++++++
 2 files changed, 118 insertions(+), 60 deletions(-)

diff --git a/base/server/python/pki/server/cli/migrate.py b/base/server/python/pki/server/cli/migrate.py
index 2005004c4e..6e0ed6c2a7 100644
--- a/base/server/python/pki/server/cli/migrate.py
+++ b/base/server/python/pki/server/cli/migrate.py
@@ -23,7 +23,6 @@ from __future__ import print_function
 
 import getopt
 import logging
-import re
 import sys
 
 from lxml import etree
@@ -104,62 +103,3 @@ class MigrateCLI(pki.cli.CLI):
 
             for instance in instances:
                 instance.init()
-
-        # update AJP connectors for Tomcat 9.0.31 or later
-
-        tomcat_version = pki.server.Tomcat.get_version()
-        if tomcat_version >= pki.util.Version('9.0.31'):
-
-            for instance in instances:
-                self.update_ajp_connectors(instance)
-
-    def update_ajp_connectors(self, instance):
-
-        logger.info('Updating AJP connectors in %s', instance.server_xml)
-
-        document = etree.parse(instance.server_xml, self.parser)
-        server = document.getroot()
-
-        # replace 'requiredSecret' with 'secret' in comments
-
-        services = server.findall('Service')
-        for service in services:
-
-            children = list(service)
-            for child in children:
-
-                if not isinstance(child, etree._Comment):  # pylint: disable=protected-access
-                    # not a comment -> skip
-                    continue
-
-                if 'protocol="AJP/1.3"' not in child.text:
-                    # not an AJP connector -> skip
-                    continue
-
-                child.text = re.sub(r'requiredSecret=',
-                                    r'secret=',
-                                    child.text,
-                                    flags=re.MULTILINE)
-
-        # replace 'requiredSecret' with 'secret' in Connectors
-
-        connectors = server.findall('Service/Connector')
-        for connector in connectors:
-
-            if connector.get('protocol') != 'AJP/1.3':
-                # not an AJP connector -> skip
-                continue
-
-            if connector.get('secret'):
-                # already has a 'secret' -> skip
-                continue
-
-            if connector.get('requiredSecret') is None:
-                # does not have a 'requiredSecret' -> skip
-                continue
-
-            value = connector.attrib.pop('requiredSecret')
-            connector.set('secret', value)
-
-        with open(instance.server_xml, 'wb') as f:
-            document.write(f, pretty_print=True, encoding='utf-8')
diff --git a/base/server/python/pki/server/instance.py b/base/server/python/pki/server/instance.py
index ad938b841d..ff43dae8ec 100644
--- a/base/server/python/pki/server/instance.py
+++ b/base/server/python/pki/server/instance.py
@@ -836,9 +836,127 @@ class PKIInstance(pki.server.PKIServer):
             nssdb.close()
             shutil.rmtree(tmpdir)
 
+    def configure_ajp_connectors_secret(self):
+
+        logger.info('Configuring AJP connectors secret')
+
+        document = etree.parse(self.server_xml, parser)
+        server = document.getroot()
+
+        # replace 'requiredSecret' with 'secret' in comments
+
+        services = server.findall('Service')
+        for service in services:
+
+            children = list(service)
+            for child in children:
+
+                if not isinstance(child, etree._Comment):  # pylint: disable=protected-access
+                    # not a comment -> skip
+                    continue
+
+                if 'protocol="AJP/1.3"' not in child.text:
+                    # not an AJP connector -> skip
+                    continue
+
+                child.text = re.sub(r'requiredSecret=',
+                                    r'secret=',
+                                    child.text,
+                                    flags=re.MULTILINE)
+
+        # replace 'requiredSecret' with 'secret' in Connectors
+
+        connectors = server.findall('Service/Connector')
+        for connector in connectors:
+
+            if connector.get('protocol') != 'AJP/1.3':
+                # not an AJP connector -> skip
+                continue
+
+            # remove existing 'requiredSecret' if any
+            value = connector.attrib.pop('requiredSecret', None)
+            print('AJP connector requiredSecret: %s' % value)
+
+            if connector.get('secret'):
+                # already has a 'secret' -> skip
+                continue
+
+            if not value:
+                raise Exception('Missing AJP connector secret in %s' % self.server_xml)
+
+            # store 'secret'
+            connector.set('secret', value)
+
+        with open(self.server_xml, 'wb') as f:
+            document.write(f, pretty_print=True, encoding='utf-8')
+
+    def configure_ajp_connectors_required_secret(self):
+
+        logger.info('Configuring AJP connectors requiredSecret')
+
+        document = etree.parse(self.server_xml, parser)
+        server = document.getroot()
+
+        # replace 'secret' with 'requiredSecret' in comments
+
+        services = server.findall('Service')
+        for service in services:
+
+            children = list(service)
+            for child in children:
+
+                if not isinstance(child, etree._Comment):  # pylint: disable=protected-access
+                    # not a comment -> skip
+                    continue
+
+                if 'protocol="AJP/1.3"' not in child.text:
+                    # not an AJP connector -> skip
+                    continue
+
+                child.text = re.sub(r'secret=',
+                                    r'requiredSecret=',
+                                    child.text,
+                                    flags=re.MULTILINE)
+
+        # replace 'secret' with 'requiredSecret' in Connectors
+
+        connectors = server.findall('Service/Connector')
+        for connector in connectors:
+
+            if connector.get('protocol') != 'AJP/1.3':
+                # not an AJP connector -> skip
+                continue
+
+            # remove existing 'secret' if any
+            value = connector.attrib.pop('secret', None)
+            print('AJP connector secret: %s' % value)
+
+            if connector.get('requiredSecret'):
+                # already has a 'requiredSecret' -> skip
+                continue
+
+            if not value:
+                raise Exception('Missing AJP connector requiredSecret in %s' % self.server_xml)
+
+            # store 'requiredSecret'
+            connector.set('requiredSecret', value)
+
+        with open(self.server_xml, 'wb') as f:
+            document.write(f, pretty_print=True, encoding='utf-8')
+
+    def configure_ajp_connectors(self):
+
+        tomcat_version = pki.server.Tomcat.get_version()
+
+        if tomcat_version >= pki.util.Version('9.0.31'):
+            self.configure_ajp_connectors_secret()
+        else:
+            self.configure_ajp_connectors_required_secret()
+
     def init(self):
         super(PKIInstance, self).init()
         self.validate_banner()
+        self.configure_ajp_connectors()
 
     @classmethod
     def instances(cls):
-- 
2.33.1