Blame SOURCES/0001-Fix-replica-reinstallation.patch

9b486d
From 5d377f31292da71f6ec4a29b13a66a9bea967102 Mon Sep 17 00:00:00 2001
9b486d
From: "Endi S. Dewata" <edewata@redhat.com>
9b486d
Date: Tue, 2 Nov 2021 14:46:02 -0500
9b486d
Subject: [PATCH] Fix replica reinstallation
9b486d
9b486d
The pkispawn and pkidestroy have been modified to ignore
9b486d
failures caused by adding an entry or attribute that is
9b486d
already exists and to check whether a file exists before
9b486d
removing it during replica removal and reinstallation.
9b486d
9b486d
One of the CA clone tests has been modified to test
9b486d
removing and reinstalling a replica.
9b486d
9b486d
Resolves: https://github.com/dogtagpki/pki/issues/3544
9b486d
---
9b486d
 .github/workflows/ca-tests.yml                |  11 ++
9b486d
 .../python/pki/server/deployment/__init__.py  |  39 +++++--
9b486d
 .../scriptlets/webapp_deployment.py           |  19 +--
9b486d
 .../cms/servlet/csadmin/LDAPConfigurator.java | 110 +++++++++++-------
9b486d
 4 files changed, 116 insertions(+), 63 deletions(-)
9b486d
9b486d
diff --git a/.github/workflows/ca-tests.yml b/.github/workflows/ca-tests.yml
9b486d
index 4832e73c65..fffcb9c3e4 100644
9b486d
--- a/.github/workflows/ca-tests.yml
9b486d
+++ b/.github/workflows/ca-tests.yml
9b486d
@@ -1137,6 +1137,17 @@ jobs:
9b486d
               --pkcs12-password-file ${PKIDIR}/pkcs12_password.conf
9b486d
           docker exec secondary pki -n caadmin ca-user-show caadmin
9b486d
 
9b486d
+      - name: Remove CA from secondary PKI container
9b486d
+        run: |
9b486d
+          docker exec secondary pkidestroy -i pki-tomcat -s CA -v
9b486d
+
9b486d
+      - name: Re-install CA in secondary PKI container
9b486d
+        run: |
9b486d
+          docker exec secondary pkispawn \
9b486d
+              -f /usr/share/pki/server/examples/installation/ca-secure-ds-secondary.cfg \
9b486d
+              -s CA \
9b486d
+              -v
9b486d
+
9b486d
       - name: Gather artifacts from primary container
9b486d
         if: always()
9b486d
         run: |
9b486d
diff --git a/base/server/python/pki/server/deployment/__init__.py b/base/server/python/pki/server/deployment/__init__.py
9b486d
index 6eb5b0a78a..d179718dd6 100644
9b486d
--- a/base/server/python/pki/server/deployment/__init__.py
9b486d
+++ b/base/server/python/pki/server/deployment/__init__.py
9b486d
@@ -1074,26 +1074,41 @@ class PKIDeployer:
9b486d
         secure_port = server_config.get_secure_port()
9b486d
 
9b486d
         uid = 'CA-%s-%s' % (self.mdict['pki_hostname'], secure_port)
9b486d
-
9b486d
         logger.info('Adding %s', uid)
9b486d
-        subsystem.add_user(
9b486d
-            uid,
9b486d
-            full_name=uid,
9b486d
-            user_type='agentType',
9b486d
-            state='1')
9b486d
 
9b486d
-        logger.info('Adding subsystem certificate into %s', uid)
9b486d
+        try:
9b486d
+            subsystem.add_user(
9b486d
+                uid,
9b486d
+                full_name=uid,
9b486d
+                user_type='agentType',
9b486d
+                state='1')
9b486d
+        except Exception:    # pylint: disable=W0703
9b486d
+            logger.warning('Unable to add %s', uid)
9b486d
+            # TODO: ignore error only if user already exists
9b486d
+
9b486d
         cert_data = pki.nssdb.convert_cert(
9b486d
             cert['data'],
9b486d
             'base64',
9b486d
             'pem')
9b486d
-        subsystem.add_user_cert(
9b486d
-            uid,
9b486d
-            cert_data=cert_data.encode(),
9b486d
-            cert_format='PEM')
9b486d
+
9b486d
+        logger.info('Adding certificate for %s', uid)
9b486d
+
9b486d
+        try:
9b486d
+            subsystem.add_user_cert(
9b486d
+                uid,
9b486d
+                cert_data=cert_data.encode(),
9b486d
+                cert_format='PEM')
9b486d
+        except Exception:    # pylint: disable=W0703
9b486d
+            logger.warning('Unable to add certificate for %s', uid)
9b486d
+            # TODO: ignore error only if user cert already exists
9b486d
 
9b486d
         logger.info('Adding %s into Subsystem Group', uid)
9b486d
-        subsystem.add_group_member('Subsystem Group', uid)
9b486d
+
9b486d
+        try:
9b486d
+            subsystem.add_group_member('Subsystem Group', uid)
9b486d
+        except Exception:    # pylint: disable=W0703
9b486d
+            logger.warning('Unable to add %s into Subsystem Group', uid)
9b486d
+            # TODO: ignore error only if user already exists in the group
9b486d
 
9b486d
     def backup_keys(self, instance, subsystem):
9b486d
 
9b486d
diff --git a/base/server/python/pki/server/deployment/scriptlets/webapp_deployment.py b/base/server/python/pki/server/deployment/scriptlets/webapp_deployment.py
9b486d
index 342477028a..f9e73fd069 100644
9b486d
--- a/base/server/python/pki/server/deployment/scriptlets/webapp_deployment.py
9b486d
+++ b/base/server/python/pki/server/deployment/scriptlets/webapp_deployment.py
9b486d
@@ -60,12 +60,13 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
9b486d
 
9b486d
         logger.info('Undeploying /%s web application', deployer.mdict['pki_subsystem'].lower())
9b486d
 
9b486d
-        # Delete <instance>/Catalina/localhost/<subsystem>.xml
9b486d
-        pki.util.remove(
9b486d
-            path=os.path.join(
9b486d
-                deployer.mdict['pki_instance_configuration_path'],
9b486d
-                "Catalina",
9b486d
-                "localhost",
9b486d
-                deployer.mdict['pki_subsystem'].lower() + ".xml"),
9b486d
-            force=deployer.mdict['pki_force_destroy']
9b486d
-        )
9b486d
+        # Delete <instance>/Catalina/localhost/<subsystem>.xml if exists
9b486d
+
9b486d
+        context_xml = os.path.join(
9b486d
+            deployer.mdict['pki_instance_configuration_path'],
9b486d
+            'Catalina',
9b486d
+            'localhost',
9b486d
+            deployer.mdict['pki_subsystem'].lower() + '.xml')
9b486d
+
9b486d
+        if os.path.exists(context_xml):
9b486d
+            pki.util.remove(context_xml)
9b486d
diff --git a/base/server/src/main/java/com/netscape/cms/servlet/csadmin/LDAPConfigurator.java b/base/server/src/main/java/com/netscape/cms/servlet/csadmin/LDAPConfigurator.java
9b486d
index 651d166321..1e0364cfea 100644
9b486d
--- a/base/server/src/main/java/com/netscape/cms/servlet/csadmin/LDAPConfigurator.java
9b486d
+++ b/base/server/src/main/java/com/netscape/cms/servlet/csadmin/LDAPConfigurator.java
9b486d
@@ -661,26 +661,35 @@ public class LDAPConfigurator {
9b486d
 
9b486d
         try {
9b486d
             connection.add(entry);
9b486d
+            // replication manager added -> done
9b486d
+            return;
9b486d
 
9b486d
         } catch (LDAPException e) {
9b486d
-            if (e.getLDAPResultCode() == LDAPException.ENTRY_ALREADY_EXISTS) {
9b486d
-                logger.warn("Entry already exists: " + dn);
9b486d
+            if (e.getLDAPResultCode() != LDAPException.ENTRY_ALREADY_EXISTS) {
9b486d
+                logger.error("Unable to add " + dn + ": " + e.getMessage(), e);
9b486d
+                throw e;
9b486d
+            }
9b486d
+            logger.warn("Replication manager already exists: " + dn);
9b486d
+        }
9b486d
 
9b486d
-                try {
9b486d
-                    logger.info("Deleting " + dn);
9b486d
-                    connection.delete(dn);
9b486d
+        logger.warn("Deleting existing replication manager: " + dn);
9b486d
 
9b486d
-                    logger.info("Re-adding " + dn);
9b486d
-                    connection.add(entry);
9b486d
+        try {
9b486d
+            connection.delete(dn);
9b486d
 
9b486d
-                } catch (LDAPException ee) {
9b486d
-                    logger.warn("Unable to recreate " + dn + ": " + ee.getMessage());
9b486d
-                }
9b486d
+        } catch (LDAPException e) {
9b486d
+            logger.error("Unable to delete " + dn + ": " + e.getMessage());
9b486d
+            throw e;
9b486d
+        }
9b486d
 
9b486d
-            } else {
9b486d
-                logger.error("Unable to add " + dn + ": " + e.getMessage(), e);
9b486d
-                throw e;
9b486d
-            }
9b486d
+        logger.warn("Adding new replication manager: " + dn);
9b486d
+
9b486d
+        try {
9b486d
+            connection.add(entry);
9b486d
+
9b486d
+        } catch (LDAPException e) {
9b486d
+            logger.error("Unable to add " + dn + ": " + e.getMessage());
9b486d
+            throw e;
9b486d
         }
9b486d
     }
9b486d
 
9b486d
@@ -799,28 +808,41 @@ public class LDAPConfigurator {
9b486d
 
9b486d
         try {
9b486d
             connection.add(entry);
9b486d
+            // replica object added -> done
9b486d
+            return true;
9b486d
 
9b486d
         } catch (LDAPException e) {
9b486d
-
9b486d
             if (e.getLDAPResultCode() != LDAPException.ENTRY_ALREADY_EXISTS) {
9b486d
+                logger.error("Unable to add " + replicaDN + ": " + e.getMessage(), e);
9b486d
                 throw e;
9b486d
             }
9b486d
+            logger.warn("Replica object already exists: " + replicaDN);
9b486d
+        }
9b486d
+
9b486d
+        logger.info("Adding replica bind DN");
9b486d
 
9b486d
-            // BZ 470918: We can't just add the new dn.
9b486d
-            // We need to do a replace until the bug is fixed.
9b486d
-            logger.warn("Entry already exists, adding bind DN");
9b486d
+        // BZ 470918: We can't just add the new dn.
9b486d
+        // We need to do a replace until the bug is fixed.
9b486d
 
9b486d
-            entry = connection.read(replicaDN);
9b486d
-            LDAPAttribute attr = entry.getAttribute("nsDS5ReplicaBindDN");
9b486d
-            attr.addValue(bindDN);
9b486d
+        entry = connection.read(replicaDN);
9b486d
+        LDAPAttribute attr = entry.getAttribute("nsDS5ReplicaBindDN");
9b486d
+        attr.addValue(bindDN);
9b486d
 
9b486d
-            LDAPModification mod = new LDAPModification(LDAPModification.REPLACE, attr);
9b486d
+        LDAPModification mod = new LDAPModification(LDAPModification.REPLACE, attr);
9b486d
+
9b486d
+        try {
9b486d
             connection.modify(replicaDN, mod);
9b486d
+            // replica bind DN added -> done
9b486d
 
9b486d
-            return false;
9b486d
+        } catch (LDAPException e) {
9b486d
+            if (e.getLDAPResultCode() != LDAPException.ATTRIBUTE_OR_VALUE_EXISTS) {
9b486d
+                logger.error("Unable to add " + bindDN + ": " + e.getMessage(), e);
9b486d
+                throw e;
9b486d
+            }
9b486d
+            logger.warn("Replica bind DN already exists: " + bindDN);
9b486d
         }
9b486d
 
9b486d
-        return true;
9b486d
+        return false;
9b486d
     }
9b486d
 
9b486d
     public void createReplicationAgreement(
9b486d
@@ -864,29 +886,33 @@ public class LDAPConfigurator {
9b486d
 
9b486d
         try {
9b486d
             connection.add(entry);
9b486d
+            // replication agreement added -> done
9b486d
+            return;
9b486d
 
9b486d
         } catch (LDAPException e) {
9b486d
-            if (e.getLDAPResultCode() == LDAPException.ENTRY_ALREADY_EXISTS) {
9b486d
-                logger.warn("Entry already exists: " + dn);
9b486d
-
9b486d
-                try {
9b486d
-                    connection.delete(dn);
9b486d
-                } catch (LDAPException ee) {
9b486d
-                    logger.error("Unable to delete " + dn + ": " + ee.getMessage(), ee);
9b486d
-                    throw ee;
9b486d
-                }
9b486d
-
9b486d
-                try {
9b486d
-                    connection.add(entry);
9b486d
-                } catch (LDAPException ee) {
9b486d
-                    logger.error("Unable to add " + dn + ": " + ee.getMessage(), ee);
9b486d
-                    throw ee;
9b486d
-                }
9b486d
-
9b486d
-            } else {
9b486d
+            if (e.getLDAPResultCode() != LDAPException.ENTRY_ALREADY_EXISTS) {
9b486d
                 logger.error("Unable to add " + dn + ": " + e.getMessage(), e);
9b486d
                 throw e;
9b486d
             }
9b486d
+            logger.warn("Replication agreement already exists: " + dn);
9b486d
+        }
9b486d
+
9b486d
+        logger.warn("Removing existing replication agreement: " + dn);
9b486d
+
9b486d
+        try {
9b486d
+            connection.delete(dn);
9b486d
+        } catch (LDAPException e) {
9b486d
+            logger.error("Unable to delete " + dn + ": " + e.getMessage(), e);
9b486d
+            throw e;
9b486d
+        }
9b486d
+
9b486d
+        logger.warn("Adding new replication agreement: " + dn);
9b486d
+
9b486d
+        try {
9b486d
+            connection.add(entry);
9b486d
+        } catch (LDAPException e) {
9b486d
+            logger.error("Unable to add " + dn + ": " + e.getMessage(), e);
9b486d
+            throw e;
9b486d
         }
9b486d
     }
9b486d
 
9b486d
-- 
9b486d
2.31.1
9b486d