This is an automated email from the ASF dual-hosted git repository.
sammichen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git
The following commit(s) were added to refs/heads/master by this push:
new 3bf9b69921 HDDS-8593. Add RootCARotationPoller to CertClient (#5030)
3bf9b69921 is described below
commit 3bf9b699215ff604814fb626910f0baeafaaf989
Author: Galsza <[email protected]>
AuthorDate: Sun Jul 9 13:16:52 2023 +0200
HDDS-8593. Add RootCARotationPoller to CertClient (#5030)
---
.../hadoop/ozone/TestHddsSecureDatanodeInit.java | 4 +-
.../client/DefaultCertificateClient.java | 55 +++++++++++++++++-----
.../certificate/client/SCMCertificateClient.java | 2 +-
.../client/CertificateClientTestImpl.java | 2 +-
.../client/TestDefaultCertificateClient.java | 2 +-
.../main/compose/ozonesecure/root-ca-rotation.yaml | 1 +
.../compose/ozonesecure/test-root-ca-rotation.sh | 1 +
7 files changed, 50 insertions(+), 17 deletions(-)
diff --git
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/TestHddsSecureDatanodeInit.java
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/TestHddsSecureDatanodeInit.java
index e9a6e59ff1..26abac2d95 100644
---
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/TestHddsSecureDatanodeInit.java
+++
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/TestHddsSecureDatanodeInit.java
@@ -327,7 +327,7 @@ public class TestHddsSecureDatanodeInit {
client.getCertificate().getSerialNumber().toString()));
// start monitor task to renew key and cert
- client.startCertificateMonitor();
+ client.startCertificateRenewerService();
// check after renew, client will have the new cert ID
GenericTestUtils.waitFor(() -> {
@@ -402,7 +402,7 @@ public class TestHddsSecureDatanodeInit {
client.getCertificate().getSerialNumber().toString()));
// start monitor task to renew key and cert
- client.startCertificateMonitor();
+ client.startCertificateRenewerService();
// certificate failed to renew, client still hold the old expired cert.
Thread.sleep(CERT_LIFETIME * 1000);
diff --git
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/client/DefaultCertificateClient.java
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/client/DefaultCertificateClient.java
index fb7587a838..a26bd12188 100644
---
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/client/DefaultCertificateClient.java
+++
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/client/DefaultCertificateClient.java
@@ -52,6 +52,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
+import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@@ -127,6 +128,7 @@ public abstract class DefaultCertificateClient implements
CertificateClient {
private Runnable shutdownCallback;
private SCMSecurityProtocolClientSideTranslatorPB scmSecurityClient;
private final Set<CertificateNotification> notificationReceivers;
+ private RootCaRotationPoller rootCaRotationPoller;
protected DefaultCertificateClient(
SecurityConfig securityConfig,
@@ -169,19 +171,33 @@ public abstract class DefaultCertificateClient implements
CertificateClient {
return;
}
- if (shouldStartCertificateMonitor()) {
+ if (shouldStartCertificateRenewerService()) {
+ startRootCaRotationPoller();
if (certPath != null && executorService == null) {
- startCertificateMonitor();
+ startCertificateRenewerService();
} else {
if (executorService != null) {
- getLogger().debug("CertificateLifetimeMonitor is already started.");
+ getLogger().debug("CertificateRenewerService is already started.");
} else {
getLogger().warn("Component certificate was not loaded.");
}
}
} else {
- getLogger().info("CertificateLifetimeMonitor is disabled for {}",
- component);
+ getLogger().info("CertificateRenewerService and root ca rotation " +
+ "polling is disabled for {}", component);
+ }
+ }
+
+ private void startRootCaRotationPoller() {
+ if (rootCaRotationPoller == null) {
+ rootCaRotationPoller = new RootCaRotationPoller(securityConfig,
+ rootCaCertificates, scmSecurityClient);
+ rootCaRotationPoller.addRootCARotationProcessor(
+ this::getRootCaRotationListener);
+ rootCaRotationPoller.run();
+ } else {
+ getLogger().debug("Root CA certificate rotation poller is already " +
+ "started.");
}
}
@@ -985,6 +1001,10 @@ public abstract class DefaultCertificateClient implements
CertificateClient {
executorService = null;
}
+ if (rootCaRotationPoller != null) {
+ rootCaRotationPoller.close();
+ }
+
if (serverKeyStoresFactory != null) {
serverKeyStoresFactory.destroy();
}
@@ -1292,11 +1312,21 @@ public abstract class DefaultCertificateClient
implements CertificateClient {
return scmSecurityClient;
}
- protected boolean shouldStartCertificateMonitor() {
+ protected boolean shouldStartCertificateRenewerService() {
return true;
}
- public synchronized void startCertificateMonitor() {
+ public synchronized CompletableFuture<Void> getRootCaRotationListener(
+ List<X509Certificate> rootCAs) {
+ if (rootCaCertificates.containsAll(rootCAs)) {
+ return CompletableFuture.completedFuture(null);
+ }
+ CertificateRenewerService renewerService =
+ new CertificateRenewerService(true);
+ return CompletableFuture.runAsync(renewerService, executorService);
+ }
+
+ public synchronized void startCertificateRenewerService() {
Preconditions.checkNotNull(getCertificate(),
"Component certificate should not be empty");
// Schedule task to refresh certificate before it expires
@@ -1310,13 +1340,13 @@ public abstract class DefaultCertificateClient
implements CertificateClient {
if (executorService == null) {
executorService = Executors.newScheduledThreadPool(1,
new ThreadFactoryBuilder().setNameFormat(
- getComponentName() + "-CertificateLifetimeMonitor")
+ getComponentName() + "-CertificateRenewerService")
.setDaemon(true).build());
}
this.executorService.scheduleAtFixedRate(
new CertificateRenewerService(false),
timeBeforeGracePeriod, interval, TimeUnit.MILLISECONDS);
- getLogger().info("CertificateLifetimeMonitor for {} is started with " +
+ getLogger().info("CertificateRenewerService for {} is started with " +
"first delay {} ms and interval {} ms.", component,
timeBeforeGracePeriod, interval);
}
@@ -1349,10 +1379,11 @@ public abstract class DefaultCertificateClient
implements CertificateClient {
}
String newCertId;
try {
- getLogger().info("Current certificate {} has entered the expiry" +
- " grace period {}. Starting renew key and certs.",
+ getLogger().info("Current certificate {} needs to be renewed " +
+ "remaining grace period {}. Forced renewal due to root ca " +
+ "rotation: {}.",
currentCert.getSerialNumber().toString(),
- timeLeft, securityConfig.getRenewalGracePeriod());
+ timeLeft, forceRenewal);
newCertId = renewAndStoreKeyAndCertificate(forceRenewal);
} catch (CertificateException e) {
if (e.errorCode() ==
diff --git
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/client/SCMCertificateClient.java
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/client/SCMCertificateClient.java
index 32a9326e46..262bb4b570 100644
---
a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/client/SCMCertificateClient.java
+++
b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/client/SCMCertificateClient.java
@@ -173,7 +173,7 @@ public class SCMCertificateClient extends
DefaultCertificateClient {
}
@Override
- protected boolean shouldStartCertificateMonitor() {
+ protected boolean shouldStartCertificateRenewerService() {
return false;
}
diff --git
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/client/CertificateClientTestImpl.java
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/client/CertificateClientTestImpl.java
index 57801a5c13..40395ac128 100644
---
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/client/CertificateClientTestImpl.java
+++
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/client/CertificateClientTestImpl.java
@@ -166,7 +166,7 @@ public class CertificateClientTestImpl implements
CertificateClient {
Duration.between(currentTime, gracePeriodStart);
executorService = Executors.newScheduledThreadPool(1,
- new
ThreadFactoryBuilder().setNameFormat("CertificateLifetimeMonitor")
+ new ThreadFactoryBuilder().setNameFormat("CertificateRenewerService")
.setDaemon(true).build());
this.executorService.schedule(new RenewCertTask(),
delay.toMillis(), TimeUnit.MILLISECONDS);
diff --git
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/client/TestDefaultCertificateClient.java
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/client/TestDefaultCertificateClient.java
index 1725a0b510..3bd352713a 100644
---
a/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/client/TestDefaultCertificateClient.java
+++
b/hadoop-hdds/framework/src/test/java/org/apache/hadoop/hdds/security/x509/certificate/client/TestDefaultCertificateClient.java
@@ -656,7 +656,7 @@ public class TestDefaultCertificateClient {
Thread.enumerate(threads);
Predicate<Thread> monitorFilterPredicate =
t -> t != null
- && t.getName().equals(compName + "-CertificateLifetimeMonitor");
+ && t.getName().equals(compName + "-CertificateRenewerService");
long monitorThreadCount = Arrays.stream(threads)
.filter(monitorFilterPredicate)
.count();
diff --git
a/hadoop-ozone/dist/src/main/compose/ozonesecure/root-ca-rotation.yaml
b/hadoop-ozone/dist/src/main/compose/ozonesecure/root-ca-rotation.yaml
index 8f7b944b0f..9dccb44945 100644
--- a/hadoop-ozone/dist/src/main/compose/ozonesecure/root-ca-rotation.yaml
+++ b/hadoop-ozone/dist/src/main/compose/ozonesecure/root-ca-rotation.yaml
@@ -25,6 +25,7 @@ x-root-cert-rotation-config:
- OZONE-SITE.XML_hdds.x509.renew.grace.duration=PT45S
- OZONE-SITE.XML_hdds.x509.ca.rotation.check.interval=PT1S
- OZONE-SITE.XML_hdds.x509.ca.rotation.ack.timeout=PT20S
+ - OZONE-SITE.XML_hdds.x509.rootca.certificate.polling.interval=PT10s
- OZONE-SITE.XML_hdds.block.token.expiry.time=15s
- OZONE-SITE.XML_ozone.manager.delegation.token.max-lifetime=15s
- OZONE-SITE.XML_ozone.manager.delegation.token.renew-interval=15s
diff --git
a/hadoop-ozone/dist/src/main/compose/ozonesecure/test-root-ca-rotation.sh
b/hadoop-ozone/dist/src/main/compose/ozonesecure/test-root-ca-rotation.sh
index 66f1a6d01a..9858d41eb8 100755
--- a/hadoop-ozone/dist/src/main/compose/ozonesecure/test-root-ca-rotation.sh
+++ b/hadoop-ozone/dist/src/main/compose/ozonesecure/test-root-ca-rotation.sh
@@ -40,6 +40,7 @@ wait_for_execute_command scm 30 "jps | grep
StorageContainerManagerStarter | se
# wait and verify root CA is rotated
wait_for_execute_command scm 180 "ozone admin cert info 2"
+wait_for_execute_command datanode 30 "find
/data/metadata/dn/certs/ROOTCA-2.crt"
# verify om operations and data operations
execute_commands_in_container scm "ozone sh volume create /r-v1 && ozone sh
bucket create /r-v1/r-b1"
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]