from ceph.deployment.service_spec import \
ServiceSpec, PlacementSpec, \
HostPlacementSpec, IngressSpec, \
- TunedProfileSpec
+ TunedProfileSpec, PrometheusSpec
from ceph.utils import str_to_datetime, datetime_to_str, datetime_now
from cephadm.serve import CephadmServe
from cephadm.services.cephadmservice import CephadmDaemonDeploySpec
# should only refresh if a change has been detected
self._trigger_preview_refresh(specs=[cast(DriveGroupSpec, spec)])
+ if spec.service_type == 'prometheus':
+ spec = cast(PrometheusSpec, spec)
+ if spec.retention_time:
+ valid_units = ['y', 'w', 'd', 'h', 'm', 's']
+ m = re.search(rf"^(\d+)({'|'.join(valid_units)})$", spec.retention_time)
+ if not m:
+ raise OrchestratorError(f"Invalid retention time. Valid units are: {', '.join(valid_units)}")
+ if spec.retention_size:
+ valid_units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB']
+ m = re.search(rf"^(\d+)({'|'.join(valid_units)})$", spec.retention_size)
+ if not m:
+ raise OrchestratorError(f"Invalid retention size. Valid units are: {', '.join(valid_units)}")
+
return self._apply_service_spec(cast(ServiceSpec, spec))
@handle_orch_error
from ceph.deployment.service_spec import ServiceSpec, PlacementSpec, RGWSpec, \
NFSServiceSpec, IscsiServiceSpec, HostPlacementSpec, CustomContainerSpec, MDSSpec, \
- CustomConfig
+ CustomConfig, PrometheusSpec
from ceph.deployment.drive_selection.selector import DriveSelection
from ceph.deployment.inventory import Devices, Device
from ceph.utils import datetime_to_str, datetime_now
with with_service(cephadm_module, spec, meth, 'test'):
pass
+ @pytest.mark.parametrize(
+ "spec, raise_exception, msg",
+ [
+ # Valid retention_time values (valid units: 'y', 'w', 'd', 'h', 'm', 's')
+ (PrometheusSpec(retention_time='1y'), False, ''),
+ (PrometheusSpec(retention_time=' 10w '), False, ''),
+ (PrometheusSpec(retention_time=' 1348d'), False, ''),
+ (PrometheusSpec(retention_time='2000h '), False, ''),
+ (PrometheusSpec(retention_time='173847m'), False, ''),
+ (PrometheusSpec(retention_time='200s'), False, ''),
+ (PrometheusSpec(retention_time=' '), False, ''), # default value will be used
+
+ # Invalid retention_time values
+ (PrometheusSpec(retention_time='100k'), True, '^Invalid retention time'), # invalid unit
+ (PrometheusSpec(retention_time='10'), True, '^Invalid retention time'), # no unit
+ (PrometheusSpec(retention_time='100.00y'), True, '^Invalid retention time'), # invalid value and valid unit
+ (PrometheusSpec(retention_time='100.00k'), True, '^Invalid retention time'), # invalid value and invalid unit
+ (PrometheusSpec(retention_time='---'), True, '^Invalid retention time'), # invalid value
+
+ # Valid retention_size values (valid units: 'B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB')
+ (PrometheusSpec(retention_size='123456789B'), False, ''),
+ (PrometheusSpec(retention_size=' 200KB'), False, ''),
+ (PrometheusSpec(retention_size='99999MB '), False, ''),
+ (PrometheusSpec(retention_size=' 10GB '), False, ''),
+ (PrometheusSpec(retention_size='100TB'), False, ''),
+ (PrometheusSpec(retention_size='500PB'), False, ''),
+ (PrometheusSpec(retention_size='200EB'), False, ''),
+ (PrometheusSpec(retention_size=' '), False, ''), # default value will be used
+
+ # Invalid retention_size values
+ (PrometheusSpec(retention_size='100b'), True, '^Invalid retention size'), # invalid unit (case sensitive)
+ (PrometheusSpec(retention_size='333kb'), True, '^Invalid retention size'), # invalid unit (case sensitive)
+ (PrometheusSpec(retention_size='2000'), True, '^Invalid retention size'), # no unit
+ (PrometheusSpec(retention_size='200.00PB'), True, '^Invalid retention size'), # invalid value and valid unit
+ (PrometheusSpec(retention_size='400.B'), True, '^Invalid retention size'), # invalid value and invalid unit
+ (PrometheusSpec(retention_size='10.000s'), True, '^Invalid retention size'), # invalid value and invalid unit
+ (PrometheusSpec(retention_size='...'), True, '^Invalid retention size'), # invalid value
+
+ # valid retention_size and valid retention_time
+ (PrometheusSpec(retention_time='1y', retention_size='100GB'), False, ''),
+ # invalid retention_time and valid retention_size
+ (PrometheusSpec(retention_time='1j', retention_size='100GB'), True, '^Invalid retention time'),
+ # valid retention_time and invalid retention_size
+ (PrometheusSpec(retention_time='1y', retention_size='100gb'), True, '^Invalid retention size'),
+ # valid retention_time and invalid retention_size
+ (PrometheusSpec(retention_time='1y', retention_size='100gb'), True, '^Invalid retention size'),
+ # invalid retention_time and invalid retention_size
+ (PrometheusSpec(retention_time='1i', retention_size='100gb'), True, '^Invalid retention time'),
+ ])
+ @mock.patch("cephadm.serve.CephadmServe._run_cephadm", _run_cephadm('{}'))
+ def test_apply_prometheus(self, spec: PrometheusSpec, raise_exception: bool, msg: str, cephadm_module: CephadmOrchestrator):
+ with with_host(cephadm_module, 'test'):
+ if not raise_exception:
+ cephadm_module._apply(spec)
+ else:
+ with pytest.raises(OrchestratorError, match=msg):
+ cephadm_module._apply(spec)
+
@mock.patch("cephadm.serve.CephadmServe._run_cephadm", _run_cephadm('{}'))
def test_mds_config_purge(self, cephadm_module: CephadmOrchestrator):
spec = MDSSpec('mds', service_id='fsname', config={'test': 'foo'})
NodeExporterService, LokiService, PromtailService
from cephadm.module import CephadmOrchestrator
from ceph.deployment.service_spec import IscsiServiceSpec, MonitoringSpec, AlertManagerSpec, \
- ServiceSpec, RGWSpec, GrafanaSpec, SNMPGatewaySpec, IngressSpec, PlacementSpec, TracingSpec
+ ServiceSpec, RGWSpec, GrafanaSpec, SNMPGatewaySpec, IngressSpec, PlacementSpec, TracingSpec, PrometheusSpec
from cephadm.tests.fixtures import with_host, with_service, _run_cephadm, async_side_effect
from orchestrator import OrchestratorError
with with_host(cephadm_module, 'test'):
with with_service(cephadm_module, MonitoringSpec('node-exporter')) as _, \
- with_service(cephadm_module, MonitoringSpec('prometheus')) as _:
+ with_service(cephadm_module, PrometheusSpec('prometheus')) as _:
y = dedent("""
# This file is generated by cephadm.
'--tcp-ports', '9095'
],
stdin=json.dumps({"files": {"prometheus.yml": y, "root_cert.pem": '',
- "/etc/prometheus/alerting/custom_alerts.yml": ""}, 'retention_time': '15d'}),
+ "/etc/prometheus/alerting/custom_alerts.yml": ""},
+ 'retention_time': '15d',
+ 'retention_size': '0'}),
image='')
@patch("cephadm.serve.CephadmServe._run_cephadm")
cephadm_module.set_store("test/grafana_crt", "c")
cephadm_module.set_store("test/grafana_key", "k")
with with_service(
- cephadm_module, MonitoringSpec("prometheus")
+ cephadm_module, PrometheusSpec("prometheus")
) as _, with_service(cephadm_module, ServiceSpec("mgr")) as _, with_service(
cephadm_module, GrafanaSpec("grafana")
) as _: