|
|
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 |
|