Report the number of days until the CDS CA cert expires as a metric so we can set an alarm.
This commit is contained in:
parent
b1d11d4f69
commit
1c73c91133
|
@ -16,12 +16,15 @@
|
|||
*/
|
||||
package org.whispersystems.textsecuregcm.storage;
|
||||
|
||||
import com.codahale.metrics.SharedMetricRegistries;
|
||||
import org.bouncycastle.openssl.PEMReader;
|
||||
import org.glassfish.jersey.SslConfigurator;
|
||||
import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
|
||||
import org.whispersystems.textsecuregcm.configuration.DirectoryServerConfiguration;
|
||||
import org.whispersystems.textsecuregcm.entities.DirectoryReconciliationRequest;
|
||||
import org.whispersystems.textsecuregcm.entities.DirectoryReconciliationResponse;
|
||||
import org.whispersystems.textsecuregcm.util.CertificateExpirationGauge;
|
||||
import org.whispersystems.textsecuregcm.util.Constants;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.ws.rs.client.Client;
|
||||
|
@ -37,6 +40,8 @@ import java.security.NoSuchAlgorithmException;
|
|||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import static com.codahale.metrics.MetricRegistry.name;
|
||||
|
||||
public class DirectoryReconciliationClient {
|
||||
|
||||
private final String replicationUrl;
|
||||
|
@ -47,6 +52,10 @@ public class DirectoryReconciliationClient {
|
|||
{
|
||||
this.replicationUrl = directoryServerConfiguration.getReplicationUrl();
|
||||
this.client = initializeClient(directoryServerConfiguration);
|
||||
|
||||
SharedMetricRegistries.getOrCreate(Constants.METRICS_NAME)
|
||||
.register(name(getClass(), "days_until_certificate_expiration"),
|
||||
new CertificateExpirationGauge(getCertificate(directoryServerConfiguration.getReplicationCaCertificate())));
|
||||
}
|
||||
|
||||
public DirectoryReconciliationResponse sendChunk(DirectoryReconciliationRequest request) {
|
||||
|
@ -74,8 +83,7 @@ public class DirectoryReconciliationClient {
|
|||
throws CertificateException
|
||||
{
|
||||
try {
|
||||
PEMReader reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(caCertificatePem.getBytes())));
|
||||
X509Certificate certificate = (X509Certificate) reader.readObject();
|
||||
X509Certificate certificate = getCertificate(caCertificatePem);
|
||||
|
||||
if (certificate == null) {
|
||||
throw new CertificateException("No certificate found in parsing!");
|
||||
|
@ -92,4 +100,11 @@ public class DirectoryReconciliationClient {
|
|||
}
|
||||
}
|
||||
|
||||
private static X509Certificate getCertificate(final String certificatePem) throws CertificateException {
|
||||
try (PEMReader reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(certificatePem.getBytes())))) {
|
||||
return (X509Certificate) reader.readObject();
|
||||
} catch (IOException e) {
|
||||
throw new CertificateException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package org.whispersystems.textsecuregcm.util;
|
||||
|
||||
import com.codahale.metrics.CachedGauge;
|
||||
import org.bouncycastle.openssl.PEMReader;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Measures and reports the number of days until a certificate expires.
|
||||
*/
|
||||
public class CertificateExpirationGauge extends CachedGauge<Long> {
|
||||
|
||||
private final Instant certificateExpiration;
|
||||
|
||||
public CertificateExpirationGauge(final X509Certificate certificate) {
|
||||
super(1, TimeUnit.HOURS);
|
||||
|
||||
certificateExpiration = certificate.getNotAfter().toInstant();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Long loadValue() {
|
||||
return Duration.between(Instant.now(), certificateExpiration).toDays();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package org.whispersystems.textsecuregcm.util;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Date;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class CertificateExpirationGaugeTest {
|
||||
|
||||
@Test
|
||||
public void loadValue() {
|
||||
final X509Certificate certificate = mock(X509Certificate.class);
|
||||
|
||||
final long daysUntilExpiration = 17;
|
||||
|
||||
final Instant now = Instant.now();
|
||||
final Instant later = now.plus(Duration.ofDays(daysUntilExpiration)).plus(Duration.ofMinutes(1));
|
||||
|
||||
when(certificate.getNotAfter()).thenReturn(new Date(later.toEpochMilli()));
|
||||
|
||||
final CertificateExpirationGauge gauge = new CertificateExpirationGauge(certificate);
|
||||
|
||||
assertEquals(daysUntilExpiration, (long) gauge.loadValue());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue