fapifta commented on code in PR #3982:
URL: https://github.com/apache/ozone/pull/3982#discussion_r1050585624
##########
hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/ReconServer.java:
##########
@@ -209,53 +206,27 @@ private void
initializeCertificateClient(OzoneConfiguration conf)
}
}
- /**
- * Get SCM signed certificate and store it using certificate client.
- * @param config
- * */
- private void getSCMSignedCert(OzoneConfiguration config) {
+ public void saveNewCertId(String newCertId) {
try {
- PKCS10CertificationRequest csr = ReconUtils.getCSR(config, certClient);
- LOG.info("Creating CSR for Recon.");
-
- SCMSecurityProtocolClientSideTranslatorPB secureScmClient =
- HddsServerUtil.getScmSecurityClientWithMaxRetry(config);
- HddsProtos.NodeDetailsProto.Builder reconDetailsProtoBuilder =
- HddsProtos.NodeDetailsProto.newBuilder()
- .setHostName(InetAddress.getLocalHost().getHostName())
- .setClusterId(reconStorage.getClusterID())
- .setUuid(reconStorage.getReconId())
- .setNodeType(HddsProtos.NodeType.RECON);
-
- SCMSecurityProtocolProtos.SCMGetCertResponseProto response =
- secureScmClient.getCertificateChain(
- reconDetailsProtoBuilder.build(),
- getEncodedString(csr));
- // Persist certificates.
- if (response.hasX509CACertificate()) {
- String pemEncodedCert = response.getX509Certificate();
- certClient.storeCertificate(pemEncodedCert, true);
- certClient.storeCertificate(response.getX509CACertificate(), true,
- true);
-
- // Store Root CA certificate.
- if (response.hasX509RootCACertificate()) {
- certClient.storeRootCACertificate(
- response.getX509RootCACertificate(), true);
- }
- String reconCertSerialId = getX509Certificate(pemEncodedCert).
- getSerialNumber().toString();
- reconStorage.setReconCertSerialId(reconCertSerialId);
- } else {
- throw new RuntimeException("Unable to retrieve recon certificate " +
- "chain");
+ reconStorage.setReconCertSerialId(newCertId);
+ reconStorage.persistCurrentState();
+ } catch (IOException ex) {
+ // New cert ID cannot be persisted into VERSION file.
+ LOG.error("Failed to persist new cert ID {} to VERSION file." +
+ "Terminating OzoneManager...", newCertId, ex);
+ try {
Review Comment:
I believe this try block is not necessary, as stop does not throw any
checked exception.
##########
hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/client/DefaultCertificateClient.java:
##########
@@ -1095,4 +1103,314 @@ public synchronized void close() throws IOException {
clientKeyStoresFactory.destroy();
}
}
+
+ /**
+ * Check how much time before certificate will enter expiry grace period.
+ * @return Duration, time before certificate enters the grace
+ * period defined by "hdds.x509.renew.grace.duration"
+ */
+ public Duration timeBeforeExpiryGracePeriod(X509Certificate certificate) {
+ Duration gracePeriod = securityConfig.getRenewalGracePeriod();
+ Date expireDate = certificate.getNotAfter();
+ LocalDateTime gracePeriodStart = expireDate.toInstant()
+ .atZone(ZoneId.systemDefault()).toLocalDateTime().minus(gracePeriod);
+ LocalDateTime currentTime = LocalDateTime.now();
+ if (gracePeriodStart.isBefore(currentTime)) {
+ // Cert is already in grace period time.
+ return Duration.ZERO;
+ } else {
+ return Duration.between(currentTime, gracePeriodStart);
+ }
+ }
+
+ /**
+ * Renew keys and certificate. Save the keys are certificate to disk in new
+ * directories, swap the current key directory and certs directory with the
+ * new directories.
+ * @param force, check certificate expiry time again if force is false.
+ * @return String, new certificate ID
+ * */
+ public String renewAndStoreKeyAndCertificate(boolean force)
+ throws CertificateException {
+ if (!force) {
+ synchronized (this) {
+ Preconditions.checkArgument(
+ timeBeforeExpiryGracePeriod(x509Certificate).isZero());
+ }
+ }
+
+ String newKeyPath = securityConfig.getKeyLocation(component)
+ .toString() + HDDS_NEW_KEY_CERT_DIR_NAME_SUFFIX;
+ String newCertPath = securityConfig.getCertificateLocation(component)
+ .toString() + HDDS_NEW_KEY_CERT_DIR_NAME_SUFFIX;
+ File newKeyDir = new File(newKeyPath);
+ File newCertDir = new File(newCertPath);
+ try {
+ FileUtils.deleteDirectory(newKeyDir);
+ FileUtils.deleteDirectory(newCertDir);
+ Files.createDirectories(newKeyDir.toPath());
+ Files.createDirectories(newCertDir.toPath());
+ } catch (IOException e) {
+ throw new CertificateException("Error while deleting/creating " +
+ newKeyPath + " or " + newCertPath + " directories to cleanup " +
+ " certificate storage. ", e, RENEW_ERROR);
+ }
+
+ // Generate key
+ KeyCodec newKeyCodec = new KeyCodec(securityConfig, newKeyDir.toPath());
+ KeyPair newKeyPair;
+ try {
+ newKeyPair = createKeyPair(newKeyCodec);
+ } catch (CertificateException e) {
+ throw new CertificateException("Error while creating new key pair.",
+ e, RENEW_ERROR);
+ }
+
+ // Get certificate signed
+ String newCertSerialId;
+ try {
+ CertificateSignRequest.Builder csrBuilder = getCSRBuilder(newKeyPair);
+ newCertSerialId = signAndStoreCertificate(csrBuilder.build(),
+ Paths.get(newCertPath));
+ } catch (Exception e) {
+ throw new CertificateException("Error while signing and storing new" +
+ " certificates.", e, RENEW_ERROR);
+ }
+
+ // switch Key and Certs directory on disk
+ File currentKeyDir = new File(
+ securityConfig.getKeyLocation(component).toString());
+ File currentCertDir = new File(
+ securityConfig.getCertificateLocation(component).toString());
+ File backupKeyDir = new File(
+ securityConfig.getKeyLocation(component).toString() +
+ HDDS_BACKUP_KEY_CERT_DIR_NAME_SUFFIX);
+ File backupCertDir = new File(
+ securityConfig.getCertificateLocation(component).toString() +
+ HDDS_BACKUP_KEY_CERT_DIR_NAME_SUFFIX);
+
+ if (!currentKeyDir.renameTo(backupKeyDir)) {
+ // Cannot rename current key dir to the backup dir
+ throw new CertificateException("Failed to rename " +
+ currentKeyDir.getAbsolutePath() +
+ " to " + backupKeyDir.getAbsolutePath() + " during " +
+ "certificate renew.", RENEW_ERROR);
+ }
+ if (!currentCertDir.renameTo(backupCertDir)) {
+ // Cannot rename current cert dir to the backup dir
+ rollbackBackupDir(currentKeyDir, currentCertDir, backupKeyDir,
+ backupCertDir);
+ throw new CertificateException("Failed to rename " +
+ currentCertDir.getAbsolutePath() +
+ " to " + backupCertDir.getAbsolutePath() + " during " +
+ "certificate renew.", RENEW_ERROR);
+ }
+
+ if (!newKeyDir.renameTo(currentKeyDir)) {
+ // Cannot rename new dir as the current dir
+ String msg = "Failed to rename " + newKeyDir.getAbsolutePath() +
+ " to " + currentKeyDir.getAbsolutePath() +
+ " during certificate renew.";
+ // rollback
+ rollbackBackupDir(currentKeyDir, currentCertDir, backupKeyDir,
+ backupCertDir);
+ throw new CertificateException(msg, RENEW_ERROR);
+ }
+
+ if (!newCertDir.renameTo(currentCertDir)) {
+ // Cannot rename new dir as the current dir
+ String msg = "Failed to rename " + newCertDir.getAbsolutePath() +
+ " to " + currentCertDir.getAbsolutePath() +
+ " during certificate renew.";
+ // delete new key directory
+ try {
+ Files.createDirectories(currentKeyDir.toPath());
+ } catch (IOException e) {
+ throw new CertificateException(msg, RENEW_ERROR);
+ }
+ // rollback
+ rollbackBackupDir(currentKeyDir, currentCertDir, backupKeyDir,
+ backupCertDir);
+ throw new CertificateException(msg, RENEW_ERROR);
+ }
+
+ getLogger().info("Successful renew key and certificate." +
+ " New certificate {}.", newCertSerialId);
+ return newCertSerialId;
+ }
+
+ private void rollbackBackupDir(File currentKeyDir, File currentCertDir,
+ File backupKeyDir, File backupCertDir) throws CertificateException {
+ // move backup dir back as current dir
+ if (!currentKeyDir.exists() && backupKeyDir.exists()) {
Review Comment:
This condition seems to be problematic, in the case when we already moved
parts of the new key and cert to the current location.
Let's assume we successfully move the newKeyDir to currentKeyDir, and then
moving newCertDir to currentCertDir fails, and we call this method. In that
case currentKeyDir.exists() will return true, which makes this expression to
evaluate to false, and we do not do rollback, however we indeed should, as if
we don't, and we report just a RENEW_ERROR, then things go on with the new keys
and the old certificates directory as I think.
So I believe we just need to check if the backup directory exists, also I
would consider whether we should log the fact that we skipped rollback as the
backup directory does not exists.
We might also switch to Files.move and use the REPLACE_EXISTING CopyOption,
as with renameTo we would need to check if the target exists and remove first I
guess that is why the non-existence check is added here at the first place.
##########
hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/client/DefaultCertificateClient.java:
##########
@@ -110,28 +125,43 @@ public abstract class DefaultCertificateClient implements
CertificateClient {
private long localCrlId;
private String component;
private List<String> pemEncodedCACerts = null;
- private final Lock lock;
private KeyStoresFactory serverKeyStoresFactory;
private KeyStoresFactory clientKeyStoresFactory;
+ // Prevent concurrent multiple renew case
Review Comment:
It would be nice to add some documentation about the locking model we use,
we guard the certificateMap with the object instance as a lock via
synchronized, and we guard renew with the renewLock as that happens in a
background thread as I understand, but it took me some time to track and
understand this, so we might want to preserve this information.
##########
hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/client/DefaultCertificateClient.java:
##########
@@ -517,7 +548,7 @@ private boolean verifySignature(byte[] data, byte[]
signature,
*/
@Override
public CertificateSignRequest.Builder getCSRBuilder()
- throws CertificateException {
+ throws IOException {
Review Comment:
I think we should not change the exception type here, as we catch
IOExceptions, and wrap them into a CertificateException, so I believe we should
keep the signature here, and this affects a few caller methods as well, where
the exception type marked in the signature has changed.
##########
hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/client/DefaultCertificateClient.java:
##########
@@ -1095,4 +1103,314 @@ public synchronized void close() throws IOException {
clientKeyStoresFactory.destroy();
}
}
+
+ /**
+ * Check how much time before certificate will enter expiry grace period.
+ * @return Duration, time before certificate enters the grace
+ * period defined by "hdds.x509.renew.grace.duration"
+ */
+ public Duration timeBeforeExpiryGracePeriod(X509Certificate certificate) {
+ Duration gracePeriod = securityConfig.getRenewalGracePeriod();
+ Date expireDate = certificate.getNotAfter();
+ LocalDateTime gracePeriodStart = expireDate.toInstant()
+ .atZone(ZoneId.systemDefault()).toLocalDateTime().minus(gracePeriod);
+ LocalDateTime currentTime = LocalDateTime.now();
+ if (gracePeriodStart.isBefore(currentTime)) {
+ // Cert is already in grace period time.
+ return Duration.ZERO;
+ } else {
+ return Duration.between(currentTime, gracePeriodStart);
+ }
+ }
+
+ /**
+ * Renew keys and certificate. Save the keys are certificate to disk in new
+ * directories, swap the current key directory and certs directory with the
+ * new directories.
+ * @param force, check certificate expiry time again if force is false.
+ * @return String, new certificate ID
+ * */
+ public String renewAndStoreKeyAndCertificate(boolean force)
+ throws CertificateException {
+ if (!force) {
+ synchronized (this) {
+ Preconditions.checkArgument(
+ timeBeforeExpiryGracePeriod(x509Certificate).isZero());
+ }
+ }
+
+ String newKeyPath = securityConfig.getKeyLocation(component)
+ .toString() + HDDS_NEW_KEY_CERT_DIR_NAME_SUFFIX;
+ String newCertPath = securityConfig.getCertificateLocation(component)
+ .toString() + HDDS_NEW_KEY_CERT_DIR_NAME_SUFFIX;
+ File newKeyDir = new File(newKeyPath);
+ File newCertDir = new File(newCertPath);
+ try {
+ FileUtils.deleteDirectory(newKeyDir);
+ FileUtils.deleteDirectory(newCertDir);
+ Files.createDirectories(newKeyDir.toPath());
+ Files.createDirectories(newCertDir.toPath());
+ } catch (IOException e) {
+ throw new CertificateException("Error while deleting/creating " +
+ newKeyPath + " or " + newCertPath + " directories to cleanup " +
+ " certificate storage. ", e, RENEW_ERROR);
+ }
+
+ // Generate key
+ KeyCodec newKeyCodec = new KeyCodec(securityConfig, newKeyDir.toPath());
+ KeyPair newKeyPair;
+ try {
+ newKeyPair = createKeyPair(newKeyCodec);
+ } catch (CertificateException e) {
+ throw new CertificateException("Error while creating new key pair.",
+ e, RENEW_ERROR);
+ }
+
+ // Get certificate signed
+ String newCertSerialId;
+ try {
+ CertificateSignRequest.Builder csrBuilder = getCSRBuilder(newKeyPair);
+ newCertSerialId = signAndStoreCertificate(csrBuilder.build(),
+ Paths.get(newCertPath));
+ } catch (Exception e) {
+ throw new CertificateException("Error while signing and storing new" +
+ " certificates.", e, RENEW_ERROR);
+ }
+
+ // switch Key and Certs directory on disk
+ File currentKeyDir = new File(
+ securityConfig.getKeyLocation(component).toString());
+ File currentCertDir = new File(
+ securityConfig.getCertificateLocation(component).toString());
+ File backupKeyDir = new File(
+ securityConfig.getKeyLocation(component).toString() +
+ HDDS_BACKUP_KEY_CERT_DIR_NAME_SUFFIX);
+ File backupCertDir = new File(
+ securityConfig.getCertificateLocation(component).toString() +
+ HDDS_BACKUP_KEY_CERT_DIR_NAME_SUFFIX);
+
+ if (!currentKeyDir.renameTo(backupKeyDir)) {
+ // Cannot rename current key dir to the backup dir
+ throw new CertificateException("Failed to rename " +
+ currentKeyDir.getAbsolutePath() +
+ " to " + backupKeyDir.getAbsolutePath() + " during " +
+ "certificate renew.", RENEW_ERROR);
+ }
+ if (!currentCertDir.renameTo(backupCertDir)) {
+ // Cannot rename current cert dir to the backup dir
+ rollbackBackupDir(currentKeyDir, currentCertDir, backupKeyDir,
+ backupCertDir);
+ throw new CertificateException("Failed to rename " +
+ currentCertDir.getAbsolutePath() +
+ " to " + backupCertDir.getAbsolutePath() + " during " +
+ "certificate renew.", RENEW_ERROR);
+ }
+
+ if (!newKeyDir.renameTo(currentKeyDir)) {
+ // Cannot rename new dir as the current dir
+ String msg = "Failed to rename " + newKeyDir.getAbsolutePath() +
+ " to " + currentKeyDir.getAbsolutePath() +
+ " during certificate renew.";
+ // rollback
+ rollbackBackupDir(currentKeyDir, currentCertDir, backupKeyDir,
+ backupCertDir);
+ throw new CertificateException(msg, RENEW_ERROR);
+ }
+
+ if (!newCertDir.renameTo(currentCertDir)) {
+ // Cannot rename new dir as the current dir
+ String msg = "Failed to rename " + newCertDir.getAbsolutePath() +
+ " to " + currentCertDir.getAbsolutePath() +
+ " during certificate renew.";
+ // delete new key directory
+ try {
+ Files.createDirectories(currentKeyDir.toPath());
+ } catch (IOException e) {
+ throw new CertificateException(msg, RENEW_ERROR);
+ }
+ // rollback
+ rollbackBackupDir(currentKeyDir, currentCertDir, backupKeyDir,
+ backupCertDir);
+ throw new CertificateException(msg, RENEW_ERROR);
+ }
+
+ getLogger().info("Successful renew key and certificate." +
+ " New certificate {}.", newCertSerialId);
+ return newCertSerialId;
+ }
+
+ private void rollbackBackupDir(File currentKeyDir, File currentCertDir,
+ File backupKeyDir, File backupCertDir) throws CertificateException {
+ // move backup dir back as current dir
+ if (!currentKeyDir.exists() && backupKeyDir.exists()) {
+ if (!backupKeyDir.renameTo(currentKeyDir)) {
+ String msg = "Failed to rename " + backupKeyDir.getAbsolutePath() +
+ " back to " + currentKeyDir.getAbsolutePath() +
+ " during rollback.";
+ // Need a manual recover process.
+ throw new CertificateException(msg, ROLLBACK_ERROR);
+ }
+ }
+
+ if (!currentCertDir.exists() && backupCertDir.exists()) {
Review Comment:
Similarly I would not check if the current dir exits.
##########
hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/client/DefaultCertificateClient.java:
##########
@@ -1095,4 +1089,274 @@ public synchronized void close() throws IOException {
clientKeyStoresFactory.destroy();
}
}
+
+ /**
+ * Check how much time before certificate will enter expiry grace period.
+ * @return Duration, time before certificate enters the grace
+ * period defined by "hdds.x509.renew.grace.duration"
+ */
+ public Duration timeBeforeExpiryGracePeriod(String certId)
+ throws CertificateException {
+ X509Certificate cert = getCertificate(certId);
+ Duration gracePeriod = securityConfig.getRenewalGracePeriod();
+ Date expireDate = cert.getNotAfter();
+ LocalDateTime gracePeriodStart = expireDate.toInstant()
+ .atZone(ZoneId.systemDefault()).toLocalDateTime().minus(gracePeriod);
+ LocalDateTime currentTime = LocalDateTime.now();
+ if (gracePeriodStart.isBefore(currentTime)) {
+ // Cert is already in grace period time.
+ return Duration.ZERO;
+ } else {
+ return Duration.between(currentTime, gracePeriodStart);
+ }
+ }
+
+ public String renewAndStoreKeyAndCertificate(boolean force)
+ throws CertificateException {
+ if (isRenewing.compareAndSet(false, true)) {
+ try {
+ if (!force) {
+ synchronized (this) {
+ Preconditions.checkArgument(
+ timeBeforeExpiryGracePeriod(certSerialId).isZero());
+ }
+ }
+ String newKeyPath = securityConfig.getKeyLocation(component)
+ .toString() + HDDS_NEW_KEY_CERT_DIR_NAME_SUFFIX;
+ String newCertPath = securityConfig.getCertificateLocation(component)
+ .toString() + HDDS_NEW_KEY_CERT_DIR_NAME_SUFFIX;
+ File newKeyDir = new File(newKeyPath);
+ File newCertDir = new File(newCertPath);
+
+ try {
+ FileUtils.deleteDirectory(newKeyDir);
+ FileUtils.deleteDirectory(newCertDir);
+ } catch (IOException e) {
+ throw new CertificateException("Error while deleting " + newKeyPath +
+ " or " + newCertPath + " directories to cleanup certificate " +
+ " storage. ", e, RENEW_ERROR);
+ }
+
+ try {
+ Files.createDirectories(newKeyDir.toPath());
+ Files.createDirectories(newCertDir.toPath());
+ } catch (IOException e) {
+ throw new CertificateException("Error while creating " + newKeyPath +
+ " or " + newCertPath + " directories for certificate storage.",
+ e, RENEW_ERROR);
+ }
+
+ // cleanup backup directory
+ cleanBackupDir();
+
+ // Generate key
+ KeyCodec newKeyCodec = new KeyCodec(securityConfig,
newKeyDir.toPath());
+ KeyPair newKeyPair;
+ try {
+ newKeyPair = createKeyPair(newKeyCodec);
+ } catch (CertificateException e) {
+ throw new CertificateException("Error while creating new key pair.",
+ e, RENEW_ERROR);
+ }
+
+ // Get certificate signed
+ String dnCertSerialId;
+ try {
+ CertificateSignRequest.Builder csrBuilder =
getCSRBuilder(newKeyPair);
+ dnCertSerialId = signAndStoreCertificate(csrBuilder.build(),
+ Paths.get(newCertPath));
+ } catch (Exception e) {
+ throw new CertificateException("Error while signing and storing new"
+
+ " certificates.", e, RENEW_ERROR);
+ }
+
+ // switch Key and Certs directory on disk
+ File currentKeyDir = new File(
+ securityConfig.getKeyLocation(component).toString());
+ File currentCertDir = new File(
+ securityConfig.getCertificateLocation(component).toString());
+ File backupKeyDir = new File(
+ securityConfig.getKeyLocation(component).toString() +
+ HDDS_BACKUP_KEY_CERT_DIR_NAME_SUFFIX);
+ File backupCertDir = new File(
+ securityConfig.getCertificateLocation(component).toString() +
+ HDDS_BACKUP_KEY_CERT_DIR_NAME_SUFFIX);
+
+ if (!currentKeyDir.renameTo(backupKeyDir)) {
+ // Cannot rename current key dir to the backup dir
+ throw new CertificateException("Failed to rename " +
+ currentKeyDir.getAbsolutePath() +
+ " to " + backupKeyDir.getAbsolutePath() + " during " +
+ "certificate renew.", RENEW_ERROR);
+ }
+ if (!currentCertDir.renameTo(backupCertDir)) {
+ // Cannot rename current cert dir to the backup dir
+ rollbackDir(currentKeyDir, currentCertDir, newKeyDir, newCertDir,
+ backupKeyDir, backupCertDir, "step-1");
+ throw new CertificateException("Failed to rename " +
+ currentCertDir.getAbsolutePath() +
+ " to " + backupCertDir.getAbsolutePath() + " during " +
+ "certificate renew.", RENEW_ERROR);
+ }
+
+ if (!newKeyDir.renameTo(currentKeyDir)) {
+ // Cannot rename new dir as the current dir
+ String msg = "Failed to rename " + newKeyDir.getAbsolutePath() +
+ " to " + currentKeyDir.getAbsolutePath() +
+ " during certificate renew.";
+ // rollback
+ rollbackDir(currentKeyDir, currentCertDir, newKeyDir, newCertDir,
+ backupKeyDir, backupCertDir, "step-2");
+ throw new CertificateException(msg, RENEW_ERROR);
+ }
+
+ if (!newCertDir.renameTo(currentCertDir)) {
+ // Cannot rename new dir as the current dir
+ String msg = "Failed to rename " + newCertDir.getAbsolutePath() +
+ " to " + currentCertDir.getAbsolutePath() +
+ " during certificate renew.";
+ // rollback
+ rollbackDir(currentKeyDir, currentCertDir, newKeyDir, newCertDir,
+ backupKeyDir, backupCertDir, "step-2");
+ throw new CertificateException(msg, RENEW_ERROR);
+ }
+
+ // Delete backup dir on next DN startup
+ getLogger().info("Successful renew key and certificate." +
+ " New certificate {}.", dnCertSerialId);
+ return dnCertSerialId;
+ } finally {
+ isRenewing.set(false);
+ }
+ }
+
+ throw new CertificateException("A renewAndStoreKeyAndCert process" +
+ " is running already.", RENEW_ERROR);
+ }
+
+ private void rollbackDir(File currentKeyDir, File currentCertDir,
+ File newKeyDir, File newCertDir, File backupKeyDir, File backupCertDir,
+ String step) throws CertificateException {
Review Comment:
Got it, this seems to be much much better. Thank you for taking the extra
mile to find a better way of expressing the difference.
##########
hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/client/DefaultCertificateClient.java:
##########
@@ -1095,4 +1089,274 @@ public synchronized void close() throws IOException {
clientKeyStoresFactory.destroy();
}
}
+
+ /**
+ * Check how much time before certificate will enter expiry grace period.
+ * @return Duration, time before certificate enters the grace
+ * period defined by "hdds.x509.renew.grace.duration"
+ */
+ public Duration timeBeforeExpiryGracePeriod(String certId)
+ throws CertificateException {
+ X509Certificate cert = getCertificate(certId);
+ Duration gracePeriod = securityConfig.getRenewalGracePeriod();
+ Date expireDate = cert.getNotAfter();
+ LocalDateTime gracePeriodStart = expireDate.toInstant()
+ .atZone(ZoneId.systemDefault()).toLocalDateTime().minus(gracePeriod);
+ LocalDateTime currentTime = LocalDateTime.now();
+ if (gracePeriodStart.isBefore(currentTime)) {
+ // Cert is already in grace period time.
+ return Duration.ZERO;
+ } else {
+ return Duration.between(currentTime, gracePeriodStart);
+ }
+ }
+
+ public String renewAndStoreKeyAndCertificate(boolean force)
Review Comment:
As we discussed in an online session, later on we should deal with this
separately, and move the certs and keys directory under a main directory to
simplify moving these directories. So for now we leave this as it is.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]