253 lines
9.4 KiB
Diff
253 lines
9.4 KiB
Diff
|
From a620e5e9e152defe144705913521c3cf556faa0e Mon Sep 17 00:00:00 2001
|
||
|
From: Mohammad Rizwan <myusuf@redhat.com>
|
||
|
Date: Mon, 26 Apr 2021 15:50:20 +0530
|
||
|
Subject: [PATCH] ipatests: wait while http/ldap/pkinit cert get renew on
|
||
|
replica
|
||
|
|
||
|
LDAP/HTTP/PKINIT certificates should be renewd on replica after
|
||
|
moving system date. Test was failing because ipa-cert-fix ran
|
||
|
while these cert was not renewd and it tried to fix it.
|
||
|
|
||
|
This test adds check for replication before calling ipa-cert-fix
|
||
|
on replica.
|
||
|
|
||
|
Fixes: https://pagure.io/freeipa/issue/8815
|
||
|
|
||
|
Signed-off-by: Mohammad Rizwan <myusuf@redhat.com>
|
||
|
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
||
|
Reviewed-By: Sergey Orlov <sorlov@redhat.com>
|
||
|
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
||
|
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
|
||
|
---
|
||
|
.../test_integration/test_ipa_cert_fix.py | 172 +++++++++++++++---
|
||
|
1 file changed, 144 insertions(+), 28 deletions(-)
|
||
|
|
||
|
diff --git a/ipatests/test_integration/test_ipa_cert_fix.py b/ipatests/test_integration/test_ipa_cert_fix.py
|
||
|
index a20996737..fa69743e2 100644
|
||
|
--- a/ipatests/test_integration/test_ipa_cert_fix.py
|
||
|
+++ b/ipatests/test_integration/test_ipa_cert_fix.py
|
||
|
@@ -5,16 +5,19 @@
|
||
|
"""
|
||
|
Module provides tests for ipa-cert-fix CLI.
|
||
|
"""
|
||
|
+from cryptography.hazmat.backends import default_backend
|
||
|
+from cryptography import x509
|
||
|
+from datetime import datetime, date
|
||
|
import pytest
|
||
|
-import re
|
||
|
import time
|
||
|
|
||
|
import logging
|
||
|
from ipaplatform.paths import paths
|
||
|
+from ipapython.ipaldap import realm_to_serverid
|
||
|
from ipatests.pytest_ipa.integration import tasks
|
||
|
from ipatests.test_integration.base import IntegrationTest
|
||
|
from ipatests.test_integration.test_caless import CALessBase, ipa_certs_cleanup
|
||
|
-
|
||
|
+from ipatests.test_integration.test_cert import get_certmonger_fs_id
|
||
|
|
||
|
logger = logging.getLogger(__name__)
|
||
|
|
||
|
@@ -59,6 +62,49 @@ def move_date(host, chrony_state, date_str):
|
||
|
host.run_command(['date', '-s', date_str])
|
||
|
|
||
|
|
||
|
+def needs_resubmit(host, req_id):
|
||
|
+ """Helper method to identify if cert request needs to be resubmitted
|
||
|
+ :param host: the host
|
||
|
+ :param req_id: request id to perform operation for
|
||
|
+
|
||
|
+ Returns True if resubmit needed else False
|
||
|
+ """
|
||
|
+ # check if cert is in monitoring state
|
||
|
+ tasks.wait_for_certmonger_status(
|
||
|
+ host, ('MONITORING'), req_id, timeout=600
|
||
|
+ )
|
||
|
+
|
||
|
+ # check if cert is valid and not expired
|
||
|
+ cmd = host.run_command(
|
||
|
+ 'getcert list -i {} | grep expires'.format(req_id)
|
||
|
+ )
|
||
|
+ cert_expiry = cmd.stdout_text.split(' ')
|
||
|
+ cert_expiry = datetime.strptime(cert_expiry[1], '%Y-%m-%d').date()
|
||
|
+ if cert_expiry > date.today():
|
||
|
+ return False
|
||
|
+ else:
|
||
|
+ return True
|
||
|
+
|
||
|
+
|
||
|
+def get_cert_expiry(host, nssdb_path, cert_nick):
|
||
|
+ """Method to get cert expiry date of given certificate
|
||
|
+
|
||
|
+ :param host: the host
|
||
|
+ :param nssdb_path: nssdb path of certificate
|
||
|
+ :param cert_nick: certificate nick name for extracting cert from nssdb
|
||
|
+ """
|
||
|
+ # get initial expiry date to compare later with renewed cert
|
||
|
+ host.run_command([
|
||
|
+ 'certutil', '-L', '-a',
|
||
|
+ '-d', nssdb_path,
|
||
|
+ '-n', cert_nick,
|
||
|
+ '-o', '/root/cert.pem'
|
||
|
+ ])
|
||
|
+ data = host.get_file_contents('/root/cert.pem')
|
||
|
+ cert = x509.load_pem_x509_certificate(data, backend=default_backend())
|
||
|
+ return cert.not_valid_after
|
||
|
+
|
||
|
+
|
||
|
@pytest.fixture
|
||
|
def expire_cert_critical():
|
||
|
"""
|
||
|
@@ -353,7 +399,19 @@ class TestCertFixReplica(IntegrationTest):
|
||
|
setup_dns=False, extra_args=['--no-ntp']
|
||
|
)
|
||
|
|
||
|
- def test_renew_expired_cert_replica(self):
|
||
|
+ @pytest.fixture
|
||
|
+ def expire_certs(self):
|
||
|
+ # move system date to expire certs
|
||
|
+ for host in self.master, self.replicas[0]:
|
||
|
+ tasks.move_date(host, 'stop', '+3years+1days')
|
||
|
+
|
||
|
+ yield
|
||
|
+
|
||
|
+ # move date back on replica and master
|
||
|
+ for host in self.master, self.replicas[0]:
|
||
|
+ tasks.move_date(host, 'start', '-3years-1days')
|
||
|
+
|
||
|
+ def test_renew_expired_cert_replica(self, expire_certs):
|
||
|
"""Test renewal of certificates on replica with ipa-cert-fix
|
||
|
|
||
|
This is to check that ipa-cert-fix renews the certificates
|
||
|
@@ -361,8 +419,6 @@ class TestCertFixReplica(IntegrationTest):
|
||
|
|
||
|
related: https://pagure.io/freeipa/issue/7885
|
||
|
"""
|
||
|
- move_date(self.master, 'stop', '+3years+1days')
|
||
|
-
|
||
|
# wait for cert expiry
|
||
|
check_status(self.master, 8, "CA_UNREACHABLE")
|
||
|
|
||
|
@@ -370,35 +426,95 @@ class TestCertFixReplica(IntegrationTest):
|
||
|
|
||
|
check_status(self.master, 9, "MONITORING")
|
||
|
|
||
|
- # move system date to expire cert on replica
|
||
|
- move_date(self.replicas[0], 'stop', '+3years+1days')
|
||
|
-
|
||
|
- # RA agent cert will be expired and in CA_UNREACHABLE state
|
||
|
- check_status(self.replicas[0], 1, "CA_UNREACHABLE")
|
||
|
-
|
||
|
- # renew RA agent cert
|
||
|
- self.replicas[0].run_command(
|
||
|
- ['ipa-cert-fix', '-v'], stdin_text='yes\n'
|
||
|
+ # replica operations
|
||
|
+ # 'Server-Cert cert-pki-ca' cert will be in CA_UNREACHABLE state
|
||
|
+ cmd = self.replicas[0].run_command(
|
||
|
+ ['getcert', 'list',
|
||
|
+ '-d', paths.PKI_TOMCAT_ALIAS_DIR,
|
||
|
+ '-n', 'Server-Cert cert-pki-ca']
|
||
|
+ )
|
||
|
+ req_id = get_certmonger_fs_id(cmd.stdout_text)
|
||
|
+ tasks.wait_for_certmonger_status(
|
||
|
+ self.replicas[0], ('CA_UNREACHABLE'), req_id, timeout=600
|
||
|
+ )
|
||
|
+ # get initial expiry date to compare later with renewed cert
|
||
|
+ initial_expiry = get_cert_expiry(
|
||
|
+ self.replicas[0],
|
||
|
+ paths.PKI_TOMCAT_ALIAS_DIR,
|
||
|
+ 'Server-Cert cert-pki-ca'
|
||
|
)
|
||
|
|
||
|
- # LDAP/HTTP/PKINIT certs will be renewed automaticaly
|
||
|
- # after moving date on replica. This 3, 1 CA cert,
|
||
|
- # 1 RA agent cert. Check for total 5 valid certs.
|
||
|
- check_status(self.replicas[0], 5, "MONITORING")
|
||
|
+ # check that HTTP,LDAP,PKINIT are renewed and in MONITORING state
|
||
|
+ instance = realm_to_serverid(self.master.domain.realm)
|
||
|
+ dirsrv_cert = paths.ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE % instance
|
||
|
+ for cert in (paths.KDC_CERT, paths.HTTPD_CERT_FILE):
|
||
|
+ cmd = self.replicas[0].run_command(
|
||
|
+ ['getcert', 'list', '-f', cert]
|
||
|
+ )
|
||
|
+ req_id = get_certmonger_fs_id(cmd.stdout_text)
|
||
|
+ tasks.wait_for_certmonger_status(
|
||
|
+ self.replicas[0], ('MONITORING'), req_id, timeout=600
|
||
|
+ )
|
||
|
|
||
|
- # get the req ids of all certs to renew remaining
|
||
|
- # certs by re-submitting it
|
||
|
- result = self.replicas[0].run_command(['getcert', 'list'])
|
||
|
- req_ids = re.findall(r'\d{14}', result.stdout_text)
|
||
|
+ cmd = self.replicas[0].run_command(
|
||
|
+ ['getcert', 'list', '-d', dirsrv_cert]
|
||
|
+ )
|
||
|
+ req_id = get_certmonger_fs_id(cmd.stdout_text)
|
||
|
+ tasks.wait_for_certmonger_status(
|
||
|
+ self.replicas[0], ('MONITORING'), req_id, timeout=600
|
||
|
+ )
|
||
|
|
||
|
- # resubmit the certs to renew them
|
||
|
- for req_id in req_ids:
|
||
|
+ # check if replication working fine
|
||
|
+ testuser = 'testuser1'
|
||
|
+ password = 'Secret@123'
|
||
|
+ stdin = (f"{self.master.config.admin_password}\n"
|
||
|
+ f"{self.master.config.admin_password}\n"
|
||
|
+ f"{self.master.config.admin_password}\n")
|
||
|
+ self.master.run_command(['kinit', 'admin'], stdin_text=stdin)
|
||
|
+ tasks.user_add(self.master, testuser, password=password)
|
||
|
+ self.replicas[0].run_command(['kinit', 'admin'], stdin_text=stdin)
|
||
|
+ self.replicas[0].run_command(['ipa', 'user-show', testuser])
|
||
|
+
|
||
|
+ # renew shared certificates by resubmitting to certmonger
|
||
|
+ cmd = self.replicas[0].run_command(
|
||
|
+ ['getcert', 'list', '-f', paths.RA_AGENT_PEM]
|
||
|
+ )
|
||
|
+ req_id = get_certmonger_fs_id(cmd.stdout_text)
|
||
|
+ if needs_resubmit(self.replicas[0], req_id):
|
||
|
self.replicas[0].run_command(
|
||
|
['getcert', 'resubmit', '-i', req_id]
|
||
|
)
|
||
|
+ tasks.wait_for_certmonger_status(
|
||
|
+ self.replicas[0], ('MONITORING'), req_id, timeout=600
|
||
|
+ )
|
||
|
+ for cert_nick in ('auditSigningCert cert-pki-ca',
|
||
|
+ 'ocspSigningCert cert-pki-ca',
|
||
|
+ 'subsystemCert cert-pki-ca'):
|
||
|
+ cmd = self.replicas[0].run_command(
|
||
|
+ ['getcert', 'list',
|
||
|
+ '-d', paths.PKI_TOMCAT_ALIAS_DIR,
|
||
|
+ '-n', cert_nick]
|
||
|
+ )
|
||
|
+ req_id = get_certmonger_fs_id(cmd.stdout_text)
|
||
|
+ if needs_resubmit(self.replicas[0], req_id):
|
||
|
+ self.replicas[0].run_command(
|
||
|
+ ['getcert', 'resubmit', '-i', req_id]
|
||
|
+ )
|
||
|
+ tasks.wait_for_certmonger_status(
|
||
|
+ self.replicas[0], ('MONITORING'), req_id, timeout=600
|
||
|
+ )
|
||
|
|
||
|
- check_status(self.master, 9, "MONITORING")
|
||
|
+ self.replicas[0].run_command(
|
||
|
+ ['ipa-cert-fix', '-v'], stdin_text='yes\n'
|
||
|
+ )
|
||
|
|
||
|
- # move date back on replica and master
|
||
|
- move_date(self.replicas[0], 'start', '-3years-1days')
|
||
|
- move_date(self.master, 'start', '-3years-1days')
|
||
|
+ check_status(self.replicas[0], 9, "MONITORING")
|
||
|
+
|
||
|
+ # Sometimes certmonger takes time to update the cert status
|
||
|
+ # So check in nssdb instead of relying on getcert command
|
||
|
+ renewed_expiry = get_cert_expiry(
|
||
|
+ self.replicas[0],
|
||
|
+ paths.PKI_TOMCAT_ALIAS_DIR,
|
||
|
+ 'Server-Cert cert-pki-ca'
|
||
|
+ )
|
||
|
+ assert renewed_expiry > initial_expiry
|
||
|
--
|
||
|
2.31.1
|
||
|
|