4e vague de démockage des sondes
This commit is contained in:
parent
3397a00d42
commit
a64386db45
8 changed files with 208 additions and 18 deletions
|
|
@ -135,6 +135,41 @@ def main() -> int:
|
||||||
|
|
||||||
exit_with(2, f"CRITICAL - {args.label}: seuils incohérents")
|
exit_with(2, f"CRITICAL - {args.label}: seuils incohérents")
|
||||||
|
|
||||||
|
elif args.probe_type == "current_value":
|
||||||
|
if args.source_type != "manual_value":
|
||||||
|
exit_with(2, f"CRITICAL - source_type non supporté: {args.source_type}")
|
||||||
|
if args.unit not in {"%", "units", "litres", "volts", "watts"}:
|
||||||
|
exit_with(2, f"CRITICAL - unité non supportée: {args.unit}")
|
||||||
|
|
||||||
|
if args.inputs_file and args.item_key:
|
||||||
|
item = load_input_item(args.inputs_file, args.item_key)
|
||||||
|
metric = float(str(item.get("value", "")).strip())
|
||||||
|
elif args.source_value:
|
||||||
|
metric = float(str(args.source_value).strip())
|
||||||
|
else:
|
||||||
|
raise ValueError("manual_value exige inputs-file/item-key ou source-value")
|
||||||
|
|
||||||
|
unit_suffix = args.unit
|
||||||
|
|
||||||
|
if args.critical_lt is not None and metric < args.critical_lt:
|
||||||
|
exit_with(2, f"CRITICAL - {args.label}: {metric:.1f} {unit_suffix}")
|
||||||
|
if args.critical_gte is not None and metric >= args.critical_gte:
|
||||||
|
exit_with(2, f"CRITICAL - {args.label}: {metric:.1f} {unit_suffix}")
|
||||||
|
if args.warning_lt is not None and metric < args.warning_lt:
|
||||||
|
exit_with(1, f"WARNING - {args.label}: {metric:.1f} {unit_suffix}")
|
||||||
|
if args.warning_gte is not None and metric >= args.warning_gte:
|
||||||
|
exit_with(1, f"WARNING - {args.label}: {metric:.1f} {unit_suffix}")
|
||||||
|
if args.ok_gte is not None and metric >= args.ok_gte:
|
||||||
|
exit_with(0, f"OK - {args.label}: {metric:.1f} {unit_suffix}")
|
||||||
|
if args.ok_lt is not None and metric < args.ok_lt:
|
||||||
|
exit_with(0, f"OK - {args.label}: {metric:.1f} {unit_suffix}")
|
||||||
|
if args.unknown_gte is not None and metric >= args.unknown_gte:
|
||||||
|
exit_with(3, f"UNKNOWN - {args.label}: {metric:.1f} {unit_suffix}")
|
||||||
|
if args.unknown_lt is not None and metric < args.unknown_lt:
|
||||||
|
exit_with(3, f"UNKNOWN - {args.label}: {metric:.1f} {unit_suffix}")
|
||||||
|
|
||||||
|
exit_with(2, f"CRITICAL - {args.label}: seuils incohérents")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
exit_with(2, f"CRITICAL - probe_type non supporté: {args.probe_type}")
|
exit_with(2, f"CRITICAL - probe_type non supporté: {args.probe_type}")
|
||||||
|
|
||||||
|
|
|
||||||
72
domains.yaml
72
domains.yaml
|
|
@ -1014,6 +1014,24 @@ domains:
|
||||||
- name: verification-tension-batteries
|
- name: verification-tension-batteries
|
||||||
date: 2026-03-15
|
date: 2026-03-15
|
||||||
notes: Vérification des tensions et cohérence des batteries
|
notes: Vérification des tensions et cohérence des batteries
|
||||||
|
probe:
|
||||||
|
type: current_value
|
||||||
|
source:
|
||||||
|
type: manual_value
|
||||||
|
inputs_file: /opt/life-noc/data/inputs/energie.yaml
|
||||||
|
item_key: verification-tension-batteries
|
||||||
|
metric:
|
||||||
|
unit: volts
|
||||||
|
thresholds:
|
||||||
|
critical_lt: 50.0
|
||||||
|
warning_lt: 51.2
|
||||||
|
ok_gte: 51.2
|
||||||
|
policy:
|
||||||
|
on_error: critical
|
||||||
|
ui:
|
||||||
|
form_mode: numeric_value
|
||||||
|
allow_complete: false
|
||||||
|
allow_manual_edit: true
|
||||||
- name: verification-smartshunt
|
- name: verification-smartshunt
|
||||||
date: 2026-03-15
|
date: 2026-03-15
|
||||||
notes: Vérification SmartShunt et cohérence du monitoring
|
notes: Vérification SmartShunt et cohérence du monitoring
|
||||||
|
|
@ -1650,6 +1668,24 @@ domains:
|
||||||
- name: verification-batterie-voiture
|
- name: verification-batterie-voiture
|
||||||
date: 2026-10-01
|
date: 2026-10-01
|
||||||
notes: Vérification de l'état de la batterie automobile
|
notes: Vérification de l'état de la batterie automobile
|
||||||
|
probe:
|
||||||
|
type: current_value
|
||||||
|
source:
|
||||||
|
type: manual_value
|
||||||
|
inputs_file: /opt/life-noc/data/inputs/voiture.yaml
|
||||||
|
item_key: verification-batterie-voiture
|
||||||
|
metric:
|
||||||
|
unit: volts
|
||||||
|
thresholds:
|
||||||
|
critical_lt: 12.2
|
||||||
|
warning_lt: 12.5
|
||||||
|
ok_gte: 12.5
|
||||||
|
policy:
|
||||||
|
on_error: critical
|
||||||
|
ui:
|
||||||
|
form_mode: numeric_value
|
||||||
|
allow_complete: false
|
||||||
|
allow_manual_edit: true
|
||||||
- name: verification-balais-essuie-glace
|
- name: verification-balais-essuie-glace
|
||||||
date: 2026-05-01
|
date: 2026-05-01
|
||||||
notes: Vérification des essuie-glaces
|
notes: Vérification des essuie-glaces
|
||||||
|
|
@ -2244,9 +2280,45 @@ domains:
|
||||||
- name: verification-ups-infrastructure
|
- name: verification-ups-infrastructure
|
||||||
date: 2026-04-15
|
date: 2026-04-15
|
||||||
notes: Vérification des UPS de l'infrastructure
|
notes: Vérification des UPS de l'infrastructure
|
||||||
|
probe:
|
||||||
|
type: current_value
|
||||||
|
source:
|
||||||
|
type: manual_value
|
||||||
|
inputs_file: /opt/life-noc/data/inputs/infrastructure-chezlepro.yaml
|
||||||
|
item_key: verification-ups-infrastructure
|
||||||
|
metric:
|
||||||
|
unit: '%'
|
||||||
|
thresholds:
|
||||||
|
critical_lt: 25
|
||||||
|
warning_lt: 50
|
||||||
|
ok_gte: 50
|
||||||
|
policy:
|
||||||
|
on_error: critical
|
||||||
|
ui:
|
||||||
|
form_mode: numeric_value
|
||||||
|
allow_complete: false
|
||||||
|
allow_manual_edit: true
|
||||||
- name: verification-capacite-stockage
|
- name: verification-capacite-stockage
|
||||||
date: 2026-04-15
|
date: 2026-04-15
|
||||||
notes: Vérifier capacité et croissance du stockage
|
notes: Vérifier capacité et croissance du stockage
|
||||||
|
probe:
|
||||||
|
type: current_value
|
||||||
|
source:
|
||||||
|
type: manual_value
|
||||||
|
inputs_file: /opt/life-noc/data/inputs/infrastructure-chezlepro.yaml
|
||||||
|
item_key: verification-capacite-stockage
|
||||||
|
metric:
|
||||||
|
unit: '%'
|
||||||
|
thresholds:
|
||||||
|
critical_lt: 15
|
||||||
|
warning_lt: 25
|
||||||
|
ok_gte: 25
|
||||||
|
policy:
|
||||||
|
on_error: critical
|
||||||
|
ui:
|
||||||
|
form_mode: numeric_value
|
||||||
|
allow_complete: false
|
||||||
|
allow_manual_edit: true
|
||||||
- name: verification-apt-cacher-ng
|
- name: verification-apt-cacher-ng
|
||||||
date: 2026-05-01
|
date: 2026-05-01
|
||||||
notes: Vérification du bon fonctionnement d'apt-cacher-ng
|
notes: Vérification du bon fonctionnement d'apt-cacher-ng
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,19 @@ apply Service "energie-inspection-batteries-lifepo4" {
|
||||||
}
|
}
|
||||||
|
|
||||||
apply Service "energie-verification-tension-batteries" {
|
apply Service "energie-verification-tension-batteries" {
|
||||||
import "service_echeance"
|
import "service_life_noc_probe"
|
||||||
vars.date_echeance = "2026-03-15"
|
vars.life_noc_probe_type = "current_value"
|
||||||
vars.mock_state = "OK"
|
vars.life_noc_source_type = "manual_value"
|
||||||
vars.mock_message = "Sous contrôle"
|
vars.life_noc_source_value = ""
|
||||||
|
vars.life_noc_inputs_file = "/opt/life-noc/data/inputs/energie.yaml"
|
||||||
|
vars.life_noc_item_key = "verification-tension-batteries"
|
||||||
|
vars.life_noc_metric_unit = "volts"
|
||||||
|
vars.life_noc_label = "verification-tension-batteries"
|
||||||
groups = [ "ENERGIE" ]
|
groups = [ "ENERGIE" ]
|
||||||
|
vars.life_noc_threshold_ok_gte = "51.2"
|
||||||
|
vars.life_noc_threshold_warning_lt = "51.2"
|
||||||
|
vars.life_noc_threshold_critical_lt = "50.0"
|
||||||
|
vars.life_noc_on_error = "critical"
|
||||||
notes = "Vérification des tensions et cohérence des batteries"
|
notes = "Vérification des tensions et cohérence des batteries"
|
||||||
vars.instructions_url = "/life-noc/item/energie/verification-tension-batteries"
|
vars.instructions_url = "/life-noc/item/energie/verification-tension-batteries"
|
||||||
assign where host.name == "life-noc"
|
assign where host.name == "life-noc"
|
||||||
|
|
|
||||||
|
|
@ -76,22 +76,38 @@ apply Service "infrastructure-chezlepro-verification-pbs-truenas" {
|
||||||
}
|
}
|
||||||
|
|
||||||
apply Service "infrastructure-chezlepro-verification-ups-infrastructure" {
|
apply Service "infrastructure-chezlepro-verification-ups-infrastructure" {
|
||||||
import "service_echeance"
|
import "service_life_noc_probe"
|
||||||
vars.date_echeance = "2026-04-15"
|
vars.life_noc_probe_type = "current_value"
|
||||||
vars.mock_state = "OK"
|
vars.life_noc_source_type = "manual_value"
|
||||||
vars.mock_message = "Sous contrôle"
|
vars.life_noc_source_value = ""
|
||||||
|
vars.life_noc_inputs_file = "/opt/life-noc/data/inputs/infrastructure-chezlepro.yaml"
|
||||||
|
vars.life_noc_item_key = "verification-ups-infrastructure"
|
||||||
|
vars.life_noc_metric_unit = "%"
|
||||||
|
vars.life_noc_label = "verification-ups-infrastructure"
|
||||||
groups = [ "INFRASTRUCTURE-CHEZLEPRO" ]
|
groups = [ "INFRASTRUCTURE-CHEZLEPRO" ]
|
||||||
|
vars.life_noc_threshold_ok_gte = "50"
|
||||||
|
vars.life_noc_threshold_warning_lt = "50"
|
||||||
|
vars.life_noc_threshold_critical_lt = "25"
|
||||||
|
vars.life_noc_on_error = "critical"
|
||||||
notes = "Vérification des UPS de l'infrastructure"
|
notes = "Vérification des UPS de l'infrastructure"
|
||||||
vars.instructions_url = "/life-noc/item/infrastructure-chezlepro/verification-ups-infrastructure"
|
vars.instructions_url = "/life-noc/item/infrastructure-chezlepro/verification-ups-infrastructure"
|
||||||
assign where host.name == "life-noc"
|
assign where host.name == "life-noc"
|
||||||
}
|
}
|
||||||
|
|
||||||
apply Service "infrastructure-chezlepro-verification-capacite-stockage" {
|
apply Service "infrastructure-chezlepro-verification-capacite-stockage" {
|
||||||
import "service_echeance"
|
import "service_life_noc_probe"
|
||||||
vars.date_echeance = "2026-04-15"
|
vars.life_noc_probe_type = "current_value"
|
||||||
vars.mock_state = "OK"
|
vars.life_noc_source_type = "manual_value"
|
||||||
vars.mock_message = "Sous contrôle"
|
vars.life_noc_source_value = ""
|
||||||
|
vars.life_noc_inputs_file = "/opt/life-noc/data/inputs/infrastructure-chezlepro.yaml"
|
||||||
|
vars.life_noc_item_key = "verification-capacite-stockage"
|
||||||
|
vars.life_noc_metric_unit = "%"
|
||||||
|
vars.life_noc_label = "verification-capacite-stockage"
|
||||||
groups = [ "INFRASTRUCTURE-CHEZLEPRO" ]
|
groups = [ "INFRASTRUCTURE-CHEZLEPRO" ]
|
||||||
|
vars.life_noc_threshold_ok_gte = "25"
|
||||||
|
vars.life_noc_threshold_warning_lt = "25"
|
||||||
|
vars.life_noc_threshold_critical_lt = "15"
|
||||||
|
vars.life_noc_on_error = "critical"
|
||||||
notes = "Vérifier capacité et croissance du stockage"
|
notes = "Vérifier capacité et croissance du stockage"
|
||||||
vars.instructions_url = "/life-noc/item/infrastructure-chezlepro/verification-capacite-stockage"
|
vars.instructions_url = "/life-noc/item/infrastructure-chezlepro/verification-capacite-stockage"
|
||||||
assign where host.name == "life-noc"
|
assign where host.name == "life-noc"
|
||||||
|
|
|
||||||
|
|
@ -96,11 +96,19 @@ apply Service "voiture-verification-timing-belt" {
|
||||||
}
|
}
|
||||||
|
|
||||||
apply Service "voiture-verification-batterie-voiture" {
|
apply Service "voiture-verification-batterie-voiture" {
|
||||||
import "service_echeance"
|
import "service_life_noc_probe"
|
||||||
vars.date_echeance = "2026-10-01"
|
vars.life_noc_probe_type = "current_value"
|
||||||
vars.mock_state = "OK"
|
vars.life_noc_source_type = "manual_value"
|
||||||
vars.mock_message = "Sous contrôle"
|
vars.life_noc_source_value = ""
|
||||||
|
vars.life_noc_inputs_file = "/opt/life-noc/data/inputs/voiture.yaml"
|
||||||
|
vars.life_noc_item_key = "verification-batterie-voiture"
|
||||||
|
vars.life_noc_metric_unit = "volts"
|
||||||
|
vars.life_noc_label = "verification-batterie-voiture"
|
||||||
groups = [ "VOITURE" ]
|
groups = [ "VOITURE" ]
|
||||||
|
vars.life_noc_threshold_ok_gte = "12.5"
|
||||||
|
vars.life_noc_threshold_warning_lt = "12.5"
|
||||||
|
vars.life_noc_threshold_critical_lt = "12.2"
|
||||||
|
vars.life_noc_on_error = "critical"
|
||||||
notes = "Vérification de l'état de la batterie automobile"
|
notes = "Vérification de l'état de la batterie automobile"
|
||||||
vars.instructions_url = "/life-noc/item/voiture/verification-batterie-voiture"
|
vars.instructions_url = "/life-noc/item/voiture/verification-batterie-voiture"
|
||||||
assign where host.name == "life-noc"
|
assign where host.name == "life-noc"
|
||||||
|
|
|
||||||
|
|
@ -194,4 +194,30 @@ def compute_state_for_item(domain: str, item_key: str) -> str:
|
||||||
return "UNKNOWN"
|
return "UNKNOWN"
|
||||||
return "CRITICAL"
|
return "CRITICAL"
|
||||||
|
|
||||||
|
if probe_type == "current_value":
|
||||||
|
if source_type != "manual_value":
|
||||||
|
return "CRITICAL"
|
||||||
|
if metric_unit not in {"%", "units", "litres", "volts", "watts"}:
|
||||||
|
return "CRITICAL"
|
||||||
|
|
||||||
|
value = float(str(item.get("value", "")).strip())
|
||||||
|
|
||||||
|
if "critical_lt" in thresholds and value < float(thresholds["critical_lt"]):
|
||||||
|
return "CRITICAL"
|
||||||
|
if "critical_gte" in thresholds and value >= float(thresholds["critical_gte"]):
|
||||||
|
return "CRITICAL"
|
||||||
|
if "warning_lt" in thresholds and value < float(thresholds["warning_lt"]):
|
||||||
|
return "WARNING"
|
||||||
|
if "warning_gte" in thresholds and value >= float(thresholds["warning_gte"]):
|
||||||
|
return "WARNING"
|
||||||
|
if "ok_gte" in thresholds and value >= float(thresholds["ok_gte"]):
|
||||||
|
return "OK"
|
||||||
|
if "ok_lt" in thresholds and value < float(thresholds["ok_lt"]):
|
||||||
|
return "OK"
|
||||||
|
if "unknown_gte" in thresholds and value >= float(thresholds["unknown_gte"]):
|
||||||
|
return "UNKNOWN"
|
||||||
|
if "unknown_lt" in thresholds and value < float(thresholds["unknown_lt"]):
|
||||||
|
return "UNKNOWN"
|
||||||
|
return "CRITICAL"
|
||||||
|
|
||||||
return "CRITICAL"
|
return "CRITICAL"
|
||||||
|
|
|
||||||
|
|
@ -202,8 +202,8 @@ def validate_probe(item: dict) -> None:
|
||||||
raise ValueError("probe doit être un objet")
|
raise ValueError("probe doit être un objet")
|
||||||
|
|
||||||
probe_type = str(probe.get("type", "")).strip()
|
probe_type = str(probe.get("type", "")).strip()
|
||||||
if probe_type not in {"elapsed_time", "days_until_due", "elapsed_distance", "remaining_quantity"}:
|
if probe_type not in {"elapsed_time", "days_until_due", "elapsed_distance", "remaining_quantity", "current_value"}:
|
||||||
raise ValueError("seuls probe.type=elapsed_time, days_until_due, elapsed_distance et remaining_quantity sont supportés")
|
raise ValueError("seuls probe.type=elapsed_time, days_until_due, elapsed_distance, remaining_quantity et current_value sont supportés")
|
||||||
|
|
||||||
source = probe.get("source")
|
source = probe.get("source")
|
||||||
if not isinstance(source, dict):
|
if not isinstance(source, dict):
|
||||||
|
|
@ -228,6 +228,11 @@ def validate_probe(item: dict) -> None:
|
||||||
raise ValueError("seul probe.source.type=manual_value est supporté pour remaining_quantity")
|
raise ValueError("seul probe.source.type=manual_value est supporté pour remaining_quantity")
|
||||||
if not has_store_ref:
|
if not has_store_ref:
|
||||||
raise ValueError("probe.source.inputs_file + item_key requis pour remaining_quantity")
|
raise ValueError("probe.source.inputs_file + item_key requis pour remaining_quantity")
|
||||||
|
elif probe_type == "current_value":
|
||||||
|
if source_type != "manual_value":
|
||||||
|
raise ValueError("seul probe.source.type=manual_value est supporté pour current_value")
|
||||||
|
if not has_store_ref:
|
||||||
|
raise ValueError("probe.source.inputs_file + item_key requis pour current_value")
|
||||||
|
|
||||||
metric = probe.get("metric")
|
metric = probe.get("metric")
|
||||||
if not isinstance(metric, dict):
|
if not isinstance(metric, dict):
|
||||||
|
|
@ -239,6 +244,8 @@ def validate_probe(item: dict) -> None:
|
||||||
raise ValueError("seul probe.metric.unit=km est supporté pour elapsed_distance")
|
raise ValueError("seul probe.metric.unit=km est supporté pour elapsed_distance")
|
||||||
if probe_type == "remaining_quantity" and metric_unit not in {"%", "units", "litres"}:
|
if probe_type == "remaining_quantity" and metric_unit not in {"%", "units", "litres"}:
|
||||||
raise ValueError("probe.metric.unit doit être %, units ou litres pour remaining_quantity")
|
raise ValueError("probe.metric.unit doit être %, units ou litres pour remaining_quantity")
|
||||||
|
if probe_type == "current_value" and metric_unit not in {"%", "units", "litres", "volts", "watts"}:
|
||||||
|
raise ValueError("probe.metric.unit doit être %, units, litres, volts ou watts pour current_value")
|
||||||
|
|
||||||
thresholds = probe.get("thresholds")
|
thresholds = probe.get("thresholds")
|
||||||
if not isinstance(thresholds, dict):
|
if not isinstance(thresholds, dict):
|
||||||
|
|
|
||||||
|
|
@ -663,6 +663,24 @@ def page_item(domain: str, item_key: str) -> HTMLResponse:
|
||||||
</form>
|
</form>
|
||||||
</section>
|
</section>
|
||||||
"""
|
"""
|
||||||
|
elif allow_manual_edit and form_mode == "numeric_value":
|
||||||
|
unit = str(service.get("probe", {}).get("metric", {}).get("unit", "")).strip()
|
||||||
|
unit_hint = f" ({html_escape(unit)})" if unit else ""
|
||||||
|
manual_form_html = f"""
|
||||||
|
<section class="card">
|
||||||
|
<h2>Mettre à jour la valeur</h2>
|
||||||
|
<p class="muted">Saisir la valeur observée{unit_hint}.</p>
|
||||||
|
<form method="post" action="/life-noc/item/{html_escape(domain)}/{html_escape(item_key)}/set" class="form-grid">
|
||||||
|
<label>Valeur courante{unit_hint}
|
||||||
|
<input type="text" inputmode="decimal" name="value" value="{html_escape(current_input.get('value', ''))}" required>
|
||||||
|
</label>
|
||||||
|
<input type="hidden" name="origin" value="manual">
|
||||||
|
<div class="actions">
|
||||||
|
<button type="submit">Enregistrer</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
"""
|
||||||
|
|
||||||
complete_form_html = ""
|
complete_form_html = ""
|
||||||
if allow_complete:
|
if allow_complete:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue