From 63177a9573db0c531a4e021f967d82e9190b2a8f Mon Sep 17 00:00:00 2001 From: Luigi D'Acunto Date: Mon, 28 Sep 2026 15:03:56 +0200 Subject: [PATCH] Highlight in red host names in rule conditions that no longer exist --- CHANGELOG.md | 5 ++++ README.md | 8 ++++++ user_script/checkmk_swissknife.user.js | 34 +++++++++++++++++++++++++- 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 368d7f7..3850236 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ All notable changes to **Checkmk SwissKnife** are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.24.0] - 2026-09-28 + +### Added +- On rule list pages (`mode=edit_ruleset`), exact host names in a rule's "Host name" condition that are not linked to a host (i.e. the host no longer exists in Checkmk) are now highlighted in red with a tooltip. Regexes, host groups and host tags are ignored, and the highlight works for mixed conditions ("matches regex …, is host01 or matches regex …") and for negated ones ("is not" / "does not match regex"). + ## [2.23.0] - 2026-09-28 ### Added diff --git a/README.md b/README.md index dcfd1fc..7f37d78 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ A [Tampermonkey](https://www.tampermonkey.net/) userscript that enhances the Che | **Rule Match Status** | Colors each rule row green (match) or dimmed (no match) when a ruleset is opened with host/service context | `highlightRuleMatchStatus` | | **Relevant Only Filter** | Adds a "Relevant only" toggle above the rule list to hide all non-matching and non-highlighted rows | `addRulesetFilterToggle` | | **Ruleset Free-Text Filter** | Adds a search box above the rule list on any ruleset page to hide rules and folders whose row text doesn't contain the typed string; mutually exclusive with "Relevant only" | `addRulesetTextFilter` | +| **Missing Host Highlight** | Paints in red the exact host names in a rule's "Host name" condition that are not linked to a host, i.e. hosts that no longer exist | `highlightMissingHosts` | | **Extra Column — Host Actions** | Inserts an Extra column in monitoring tables with per-host buttons: Service Discovery, copy FQDN, copy short hostname, copy IP | `addInventoryButtons` | | **Monitor Button in WATO Folder** | Adds a green eye icon next to each active host in WATO folder listings to open its monitoring view in a new tab | `addWatoFolderMonitorButtons` | | **Configure in WATO Menu** | Adds a host-selector dropdown and Open button to the monitoring view menu bar for bulk-opening hosts in WATO | `addViewWatoMenu` | @@ -90,6 +91,13 @@ Applies to: every `mode=edit_ruleset` page, with or without host/service context --- +### Missing Host Highlight +In a rule's "Host name" condition, exact host names that are not linked to a host (the host no longer exists in Checkmk) are shown in red with a wavy underline and a tooltip. Regexes, host groups and host tags are ignored. Works on mixed conditions ("matches regex …, is host01 or matches regex …") and on negated ones ("is not", "does not match regex"). + +Applies to: every `mode=edit_ruleset` page, with or without host/service context. + +--- + ### Extra Column with Host Actions Adds a dedicated **Extra** column before the Host column in all monitoring view tables. Each row gets up to four icon buttons: diff --git a/user_script/checkmk_swissknife.user.js b/user_script/checkmk_swissknife.user.js index 49a1afe..be03dc0 100644 --- a/user_script/checkmk_swissknife.user.js +++ b/user_script/checkmk_swissknife.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name Checkmk SwissKnife // @namespace https://luigidacunto.com/ -// @version 2.23.0 +// @version 2.24.0 // @checkmk 2.3.x - 2.4.x // @description Collection of UI improvements for Checkmk WATO. Each fix or enhancement is added here as an independent feature. // @author Luigi D'Acunto @@ -893,6 +893,37 @@ } + // ========================================================================= + // FEATURE: Missing Host Highlight + // + // In a rule's "Host name ..." condition, exact host names are rendered as a + // link to the host only if the host still exists; an unlinked name means the + // host was deleted. Those names are painted red. Regexes are ignored. + // ========================================================================= + + function highlightMissingHosts(doc) { + if (doc.body.dataset.cmkMissingHosts === '1') return; + const items = doc.querySelectorAll('tr.data li.condition'); + if (!items.length) return; + doc.body.dataset.cmkMissingHosts = '1'; + + injectStyles(doc, 'cmk-sk-missing-host-styles', ` + b.cmk-sk-missing-host { color: #ff4d4d !important; text-decoration: underline wavy #ff4d4d; } + `); + + items.forEach(li => { + if (!li.textContent.trim().startsWith('Host name')) return; + li.querySelectorAll('b').forEach(b => { + // Text right before each tells regex ("matches regex", "one of regex") from exact name ("is", "is not") + const before = b.previousSibling ? b.previousSibling.textContent : ''; + if (/regex/.test(before) || b.querySelector('a')) return; + b.classList.add('cmk-sk-missing-host'); + b.title = 'Host not found in Checkmk (deleted?)'; + }); + }); + } + + // ========================================================================= // FEATURE: Inventory Button on view.py // @@ -2049,6 +2080,7 @@ highlightRuleMatchStatus(doc); addRulesetFilterToggle(doc); addRulesetTextFilter(doc); + highlightMissingHosts(doc); } function tryAddInventoryButtons() {