mirror of https://github.com/apache/cloudstack.git
Add a Prometheus metric to track host certificate expiry (#12613)
This commit is contained in:
parent
b45726f7b1
commit
4de8c2b6f6
|
|
@ -17,6 +17,7 @@
|
|||
package org.apache.cloudstack.metrics;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
|
@ -26,6 +27,7 @@ import java.util.stream.Collectors;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.ca.CAManager;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
|
@ -133,6 +135,8 @@ public class PrometheusExporterImpl extends ManagerBase implements PrometheusExp
|
|||
private ResourceCountDao _resourceCountDao;
|
||||
@Inject
|
||||
private HostTagsDao _hostTagsDao;
|
||||
@Inject
|
||||
private CAManager caManager;
|
||||
|
||||
public PrometheusExporterImpl() {
|
||||
super();
|
||||
|
|
@ -216,6 +220,9 @@ public class PrometheusExporterImpl extends ManagerBase implements PrometheusExp
|
|||
}
|
||||
|
||||
metricsList.add(new ItemHostVM(zoneName, zoneUuid, host.getName(), host.getUuid(), host.getPrivateIpAddress(), vmDao.listByHostId(host.getId()).size()));
|
||||
|
||||
addSSLCertificateExpirationMetrics(metricsList, zoneName, zoneUuid, host);
|
||||
|
||||
final CapacityVO coreCapacity = capacityDao.findByHostIdType(host.getId(), Capacity.CAPACITY_TYPE_CPU_CORE);
|
||||
|
||||
if (coreCapacity == null && !host.isInMaintenanceStates()){
|
||||
|
|
@ -253,6 +260,18 @@ public class PrometheusExporterImpl extends ManagerBase implements PrometheusExp
|
|||
addHostTagsMetrics(metricsList, dcId, zoneName, zoneUuid, totalHosts, upHosts, downHosts, total, up, down);
|
||||
}
|
||||
|
||||
private void addSSLCertificateExpirationMetrics(List<Item> metricsList, String zoneName, String zoneUuid, HostVO host) {
|
||||
if (caManager == null || caManager.getActiveCertificatesMap() == null) {
|
||||
return;
|
||||
}
|
||||
X509Certificate cert = caManager.getActiveCertificatesMap().getOrDefault(host.getPrivateIpAddress(), null);
|
||||
if (cert == null) {
|
||||
return;
|
||||
}
|
||||
long certExpiryEpoch = cert.getNotAfter().getTime() / 1000; // Convert to epoch seconds
|
||||
metricsList.add(new ItemHostCertExpiry(zoneName, zoneUuid, host.getName(), host.getUuid(), host.getPrivateIpAddress(), certExpiryEpoch));
|
||||
}
|
||||
|
||||
private String markTagMaps(HostVO host, Map<String, Integer> totalHosts, Map<String, Integer> upHosts, Map<String, Integer> downHosts) {
|
||||
List<HostTagVO> hostTagVOS = _hostTagsDao.getHostTags(host.getId());
|
||||
List<String> hostTags = new ArrayList<>();
|
||||
|
|
@ -1049,4 +1068,28 @@ public class PrometheusExporterImpl extends ManagerBase implements PrometheusExp
|
|||
return String.format("%s{zone=\"%s\",cpu=\"%d\",memory=\"%d\"} %d", name, zoneName, cpu, memory, total);
|
||||
}
|
||||
}
|
||||
|
||||
class ItemHostCertExpiry extends Item {
|
||||
String zoneName;
|
||||
String zoneUuid;
|
||||
String hostName;
|
||||
String hostUuid;
|
||||
String hostIp;
|
||||
long expiryTimestamp;
|
||||
|
||||
public ItemHostCertExpiry(final String zoneName, final String zoneUuid, final String hostName, final String hostUuid, final String hostIp, final long expiry) {
|
||||
super("cloudstack_host_cert_expiry_timestamp");
|
||||
this.zoneName = zoneName;
|
||||
this.zoneUuid = zoneUuid;
|
||||
this.hostName = hostName;
|
||||
this.hostUuid = hostUuid;
|
||||
this.hostIp = hostIp;
|
||||
this.expiryTimestamp = expiry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toMetricsString() {
|
||||
return String.format("%s{zone=\"%s\",hostname=\"%s\",ip=\"%s\"} %d", name, zoneName, hostName, hostIp, expiryTimestamp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,108 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.metrics;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class PrometheusExporterImplTest {
|
||||
|
||||
private static final String TEST_ZONE_NAME = "zone1";
|
||||
private static final String TEST_ZONE_UUID = "zone-uuid-1";
|
||||
private static final String TEST_HOST_NAME = "host1";
|
||||
private static final String TEST_HOST_UUID = "host-uuid-1";
|
||||
private static final String TEST_HOST_IP = "192.168.1.10";
|
||||
private static final long CERT_EXPIRY_TIME = 1735689600000L; // 2025-01-01 00:00:00 UTC
|
||||
private static final long CERT_EXPIRY_EPOCH = CERT_EXPIRY_TIME / 1000;
|
||||
|
||||
@Test
|
||||
public void testItemHostCertExpiryFormat() {
|
||||
PrometheusExporterImpl exporter = new PrometheusExporterImpl();
|
||||
PrometheusExporterImpl.ItemHostCertExpiry item = exporter.new ItemHostCertExpiry(
|
||||
TEST_ZONE_NAME,
|
||||
TEST_ZONE_UUID,
|
||||
TEST_HOST_NAME,
|
||||
TEST_HOST_UUID,
|
||||
TEST_HOST_IP,
|
||||
CERT_EXPIRY_EPOCH
|
||||
);
|
||||
|
||||
String metricsString = item.toMetricsString();
|
||||
String expected = String.format(
|
||||
"cloudstack_host_cert_expiry_timestamp{zone=\"%s\",hostname=\"%s\",ip=\"%s\"} %d",
|
||||
TEST_ZONE_NAME,
|
||||
TEST_HOST_NAME,
|
||||
TEST_HOST_IP,
|
||||
CERT_EXPIRY_EPOCH
|
||||
);
|
||||
assertEquals("Certificate expiry metric format should match expected format", expected, metricsString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testItemHostCertExpiryContainsCorrectMetricName() {
|
||||
PrometheusExporterImpl exporter = new PrometheusExporterImpl();
|
||||
PrometheusExporterImpl.ItemHostCertExpiry item = exporter.new ItemHostCertExpiry(
|
||||
TEST_ZONE_NAME,
|
||||
TEST_ZONE_UUID,
|
||||
TEST_HOST_NAME,
|
||||
TEST_HOST_UUID,
|
||||
TEST_HOST_IP,
|
||||
CERT_EXPIRY_EPOCH
|
||||
);
|
||||
|
||||
String metricsString = item.toMetricsString();
|
||||
assertTrue("Metric should contain correct metric name",
|
||||
metricsString.contains("cloudstack_host_cert_expiry_timestamp"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testItemHostCertExpiryContainsAllLabels() {
|
||||
PrometheusExporterImpl exporter = new PrometheusExporterImpl();
|
||||
PrometheusExporterImpl.ItemHostCertExpiry item = exporter.new ItemHostCertExpiry(
|
||||
TEST_ZONE_NAME,
|
||||
TEST_ZONE_UUID,
|
||||
TEST_HOST_NAME,
|
||||
TEST_HOST_UUID,
|
||||
TEST_HOST_IP,
|
||||
CERT_EXPIRY_EPOCH
|
||||
);
|
||||
|
||||
String metricsString = item.toMetricsString();
|
||||
assertTrue("Metric should contain zone label", metricsString.contains("zone=\"" + TEST_ZONE_NAME + "\""));
|
||||
assertTrue("Metric should contain hostname label", metricsString.contains("hostname=\"" + TEST_HOST_NAME + "\""));
|
||||
assertTrue("Metric should contain ip label", metricsString.contains("ip=\"" + TEST_HOST_IP + "\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testItemHostCertExpiryContainsTimestampValue() {
|
||||
PrometheusExporterImpl exporter = new PrometheusExporterImpl();
|
||||
PrometheusExporterImpl.ItemHostCertExpiry item = exporter.new ItemHostCertExpiry(
|
||||
TEST_ZONE_NAME,
|
||||
TEST_ZONE_UUID,
|
||||
TEST_HOST_NAME,
|
||||
TEST_HOST_UUID,
|
||||
TEST_HOST_IP,
|
||||
CERT_EXPIRY_EPOCH
|
||||
);
|
||||
|
||||
String metricsString = item.toMetricsString();
|
||||
assertTrue("Metric should contain correct timestamp value",
|
||||
metricsString.endsWith(" " + CERT_EXPIRY_EPOCH));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue