From 11ce8a461590a46a4ec769521816e2f64e91a74a Mon Sep 17 00:00:00 2001 From: Domenik Bildhauer Date: Sun, 16 Aug 2026 19:31:55 +0200 Subject: [PATCH] Add Checkmk OS info plugin --- .gitignore | 1 + os-info/CHANGELOG.md | 10 ++ os-info/LICENSE | 5 + os-info/PROJECT.md | 12 ++ os-info/README.md | 161 ++++++++++++++++++ os-info/dist/os_info-1.0.0.mkp | Bin 0 -> 2655 bytes os-info/src/agents/plugins/os_info | 48 ++++++ .../src/agents/windows/plugins/os_info.ps1 | 23 +++ .../os_info/agent_based/os_info.py | 55 ++++++ .../os_info/checkman/os_info | 19 +++ 10 files changed, 334 insertions(+) create mode 100644 .gitignore create mode 100644 os-info/CHANGELOG.md create mode 100644 os-info/LICENSE create mode 100644 os-info/PROJECT.md create mode 100644 os-info/README.md create mode 100644 os-info/dist/os_info-1.0.0.mkp create mode 100755 os-info/src/agents/plugins/os_info create mode 100644 os-info/src/agents/windows/plugins/os_info.ps1 create mode 100644 os-info/src/cmk_addons_plugins/os_info/agent_based/os_info.py create mode 100644 os-info/src/cmk_addons_plugins/os_info/checkman/os_info diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/os-info/CHANGELOG.md b/os-info/CHANGELOG.md new file mode 100644 index 0000000..852dfdd --- /dev/null +++ b/os-info/CHANGELOG.md @@ -0,0 +1,10 @@ +# Changelog + +## 1.0.0 + +- Erste Version +- Checkmk Check API V2 +- Service `Betriebssystem` +- Linux/macOS Agent-Plug-in +- Windows PowerShell Agent-Plug-in +- Anzeige von Betriebssystem, Version/Build, Architektur und Kernel diff --git a/os-info/LICENSE b/os-info/LICENSE new file mode 100644 index 0000000..9c96f2e --- /dev/null +++ b/os-info/LICENSE @@ -0,0 +1,5 @@ +GNU GENERAL PUBLIC LICENSE +Version 2, June 1991 + +This project is distributed under the terms of the GNU General Public License version 2. +The complete license text is available from the Free Software Foundation. diff --git a/os-info/PROJECT.md b/os-info/PROJECT.md new file mode 100644 index 0000000..87bcbaf --- /dev/null +++ b/os-info/PROJECT.md @@ -0,0 +1,12 @@ +# Projektübersicht – Checkmk OS Info + +**Projekt:** Checkmk OS Info +**Version:** 1.0.0 +**Ziel:** Betriebssysteminformationen als eigenen Checkmk-Service pro Host anzeigen. +**Checkmk:** Community 2.5.x / Check API V2 + +Das Repository enthält den vollständigen Quellcode für Linux/macOS und Windows, +das Checkmk Check-Plug-in, die Checkman-Dokumentation sowie das fertige MKP unter `dist/`. + +Wichtig: MKP-Dateien werden im lokalen Site-Bereich installiert. Die Agent-Plug-ins liegen +daher nach Aktivierung unter `~/local/share/check_mk/agents/...`. diff --git a/os-info/README.md b/os-info/README.md new file mode 100644 index 0000000..49c88e0 --- /dev/null +++ b/os-info/README.md @@ -0,0 +1,161 @@ +# Checkmk OS Info + +MKP-Erweiterung für **Checkmk Community 2.5.x**, die auf überwachten Hosts einen eigenen Service **„Betriebssystem“** bereitstellt. + +## Funktionen + +Der Service zeigt unter anderem: + +- Betriebssystem bzw. Linux-Distribution +- Betriebssystem-Version / Windows-Build +- Architektur +- Kernel-Version +- OS-ID und Version-ID + +Unterstützt werden Linux, Windows und grundsätzlich auch macOS. + +## Repository-Struktur + +```text +checkmk-os-info/ +├── src/ +│ ├── agents/ +│ │ ├── plugins/ +│ │ │ └── os_info +│ │ └── windows/ +│ │ └── plugins/ +│ │ └── os_info.ps1 +│ └── cmk_addons_plugins/ +│ └── os_info/ +│ ├── agent_based/ +│ │ └── os_info.py +│ └── checkman/ +│ └── os_info +├── dist/ +│ └── os_info-1.0.0.mkp +├── CHANGELOG.md +├── LICENSE +└── README.md +``` + +## Installation des MKP + +Das fertige Paket befindet sich unter: + +```text +dist/os_info-1.0.0.mkp +``` + +Auf den Checkmk-Server kopieren und als Site-Benutzer installieren: + +```bash +mkp add /tmp/os_info-1.0.0.mkp +mkp enable os_info 1.0.0 +cmk -R +``` + +Kontrolle: + +```bash +mkp list +``` + +Der Eintrag `os_info` sollte als `Enabled (active on this site)` erscheinen. + +## Agent-Plug-in für Linux/macOS + +Nach Aktivierung des MKP liegt das Plug-in im lokalen Site-Verzeichnis: + +```text +~/local/share/check_mk/agents/plugins/os_info +``` + +Auf den Zielhost kopieren: + +```bash +scp ~/local/share/check_mk/agents/plugins/os_info \ +root@HOST:/usr/lib/check_mk_agent/plugins/os_info +``` + +Danach auf dem Zielhost: + +```bash +chmod 755 /usr/lib/check_mk_agent/plugins/os_info +/usr/lib/check_mk_agent/plugins/os_info +``` + +Die Ausgabe muss mit folgender Sektion beginnen: + +```text +<<>> +``` + +## Agent-Plug-in für Windows + +Nach Aktivierung liegt die PowerShell-Datei auf dem Checkmk-Server unter: + +```text +~/local/share/check_mk/agents/windows/plugins/os_info.ps1 +``` + +Auf dem Windows-Host nach folgendem Verzeichnis kopieren: + +```text +C:\ProgramData\checkmk\agent\plugins\os_info.ps1 +``` + +## Service Discovery + +Auf dem Checkmk-Server zunächst prüfen, ob die Agent-Sektion ankommt: + +```bash +cmk -d HOSTNAME | grep -A2 '^<<Mk3Eio=IE-)@_Yj6PVT>o<0xDoc>e2P8Bt)y0> zL`k+|_3WwRcrKpY#U3k{Olx}-N`xd-B&YzO9mnUl>0{h~d9mUbDN>4@HrF^a3BDQA zB(b{y76kNxT)=C3&A*=p@1CI`M0Deeprx_yf2-B$F3#nBzt#5J8}M%90gy5tP?7z{ z_lfpnh&hhYp1<>WYiDQMZ*{!xvkmCjq`!PNWamG@vN_rrQ6u5~O^Z&`J*~Cv!v& zj$xcoc$&nB;2Au@Q8*1!L@RX%Dj{Mcisu|BM9TjY;R%N)h*OM)jNLGf;yS!SlnH_6 zlT_%|;ed{&n4=j_DWoKX=ZF#%LB)Y3RDy^>AJHp3LNKQZJWCjdfOv33`1HfSBMt`> zM0n#gN+%6W7>qysPCsVoXH3#}%{UmH^i`IxF$t4v=IJ^l*Ca}UaFEhSRzlqz;|MWv zCA=ZCkf-OBxyVOk(@fYv_L52+D%aXlb1BK2Grw|KFP5Y-if4l$3=_fzMp_v)8cmhY zU>GnIF09;C>MONbMQ&p>MWb09ki3MKcd{}hh>@&WUT$%ZV;&*X#x&rVOrWpY3yy^d zjRV!DQu0bSpOp2zme(rY^kPf~6unKc=mt`v?QMCjdAB4p4@NUlJC!b+(1>UA22YX* zIxFT<77QaaND0SLW^Q-4a%X>e9t@u4f0qAQ{`Xz;Kkr{GAzzdKiQZS{f9-C|^1p}S ze}ZthngY5#aPOmlt|TXJfdfi~Kf(b&kMONyccyp+dMC@L?<#&LE^igRay7{l*XM?A zxl4r3&3Kr5594!{jG=w*D&H&Gzn}IkvRg;(OkU!6rz#{lo~&N6ysjd7rWMzcJS}P% zm=snluXMLW^Q4HOd1axD=ShK8o>!JF61~je?yl=trf2z|<$sp{S$r+%pF&Uefv?2> zB-dNve_P#c%m3{7Z^wT-{#$%WEX`}aSpVPI+FCdNZ+BM4|IW6*W5@r8z@s0ULrj`% z>O6u&HR+sz;sh|)v+f=w`D{{8?*T7nlS1nx<@1ySX264CgQ0mKq*18eA+TU9ruKoD z1d@s8FvOvOQpb_A*FD#D%=A#6%I7aE+%s2mia5WKX8|2e_uS2DDwUxTLwmm&qN^rJ zqX>Tc4bW(sKuTsLxh6H&nW#+{za=XKw_eRXu!KR$VpCmCOC z-X1?)7B>k-V^9#tJhgdydUo{kO8u?o1G>ctAk@xCvHr~?N)vi8k{72GjS)p;gkTTcK8}Q$=;kmXLODf( zSPPmUQhq|bafst%BK$378;4QA*b7OKUSrZ}5Au&z`kR%b2!K%BMC7V>dUkSn)bF31 z4Gzu@pB=wEI(+%-*^%VzRbk#c>6=fCBc4(uxE18uE2$vZl%{5TaL%~kO_NJ0br{Tb z-3)PAN;W)K*5){rH8nlQ%@x$`qKf+Z`67*nh&qPsNX5-+A-ft>l^E!|1(lj$H-_k} zDT*^riE08k6q5~7&1GH%QHnB#seGj9aRa@DJPky7QcA#eg+rvAxvpvnF%v@bC=d9^B~gS_fC2M@ z;RtX%Pbi09g83YiNgev=Z7SnF93vjjyuxGTU9~d}wT!#3P1SY4$*Ce6bvQ#Tjd(p< z2QE%{z|}t)%J5PKSUZkmbYU;cT!uQ-K^!hcYKX=v$Q%vKlUvn+5CbmNdqrC{XzYWr z*2}^pNW!6{k#E9dVj^zu933K&T=()?%OYHg5*0PiTbD|3j8PQIsF$iJxE7~4 zEZi9AD-#PV&VoX$ioDKZU3Jv4jLndSBg}YJl&1!Ng>%=vgug%>ysNhA5Ft|4`HRY` zD=Ahh#(0Ey#H;V|+{o39+4Eje`BLa;--eit5>ecRdyNA#Pu6l*vZ8AxZltlSb*q_0 z6+r(fb9uy!N%tm*S2IV|KrSyRCg?b3dE5P!4ACqggzJFpqDPm_mAtLB)3SCRf>YAV zT4hiPCgo-cNKVrd))^k#4D-s;NTm3B<%!ELdSckV(nL_EL| z+pCs#jT*bR?HaXC?WEs0e!8rL z!%t-+l=L1FYw{c1W8xkct_tfNDTJJE*Ske}O}kq@xq5Ij<;b31@n95(w`yUPLU}U@ zJwjz6TYIGetL_NM*`SiyQ>xLj|X=?*r~Y324eB3UoKS(IV9V{1WOj$EkJS7kvh zX|nS_JO8uuKZ|c@{Md>HrI`-v87dIZoKe7o zD47(N1q_U6Bxna=!o*LfKVP*SK`Df#VX6szu3y+SOpyDh7%?%6G5dM}qVG{U;fp=M zLPYY7!IsI4=fDA(p!aIuv1>%7Y+0oFv`~h8FESXuzxF_HNan2Bk*r~4JwfB2A__6) z6BJ>&zJa6iW@Hejj6sl&RbfB;K1B377)`mjP#csr>Y&!JHXKOA4{NqdSwk;w5K>q! zgouQ3npMMduw?6wD2%XwEY3YR&0KPgX$YbKK?*W8^Nw+y=j7~8=pPjXlpdmLb|NOs z$uJNzlMrXM=?fP~=PW|__xJbVDxuSW$chP1dYYK_v`aF(A^}dGE8hugM79~#ZeUor zK|B>xp?*MQJ0X>53L%#mm)onbutYk+j>#4l78Vv378Vv378Vv378Vv378Vv378ZX5 N{{fb3LT>/dev/null 2>&1; then + name="macOS" + version="$(sw_vers -productVersion 2>/dev/null || true)" + os_id="macos" + version_id="$version" + pretty="macOS $version" +else + name="$(uname -s 2>/dev/null || echo unknown)" + version="$kernel" + os_id="$(printf '%s' "$name" | tr '[:upper:]' '[:lower:]')" + version_id="$version" + pretty="$name $version" +fi + +sanitize() { + printf '%s' "$1" | tr '\t\r\n' ' ' +} + +printf '<<>>\n' +printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\n' \ + "$(sanitize "$name")" \ + "$(sanitize "$version")" \ + "$(sanitize "$os_id")" \ + "$(sanitize "$version_id")" \ + "$(sanitize "$pretty")" \ + "$(sanitize "$arch")" \ + "$(sanitize "$kernel")" diff --git a/os-info/src/agents/windows/plugins/os_info.ps1 b/os-info/src/agents/windows/plugins/os_info.ps1 new file mode 100644 index 0000000..dff2a05 --- /dev/null +++ b/os-info/src/agents/windows/plugins/os_info.ps1 @@ -0,0 +1,23 @@ +# Checkmk agent plug-in: operating system information +$ErrorActionPreference = "SilentlyContinue" + +$os = Get-CimInstance -ClassName Win32_OperatingSystem +$arch = $env:PROCESSOR_ARCHITECTURE +if ($os.OSArchitecture) { $arch = $os.OSArchitecture } + +$name = [string]$os.Caption +$version = [string]$os.Version +$osId = "windows" +$versionId = [string]$os.BuildNumber +$pretty = "$($os.Caption) (Build $($os.BuildNumber))" +$kernel = [string]$os.Version + +function Clean([string]$Value) { + if ($null -eq $Value) { return "" } + return ($Value -replace "[`t`r`n]", " ") +} + +Write-Output "<<>>" +Write-Output ("{0}`t{1}`t{2}`t{3}`t{4}`t{5}`t{6}" -f ` + (Clean $name), (Clean $version), (Clean $osId), (Clean $versionId), ` + (Clean $pretty), (Clean $arch), (Clean $kernel)) diff --git a/os-info/src/cmk_addons_plugins/os_info/agent_based/os_info.py b/os-info/src/cmk_addons_plugins/os_info/agent_based/os_info.py new file mode 100644 index 0000000..137eddb --- /dev/null +++ b/os-info/src/cmk_addons_plugins/os_info/agent_based/os_info.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +from collections.abc import Mapping, Sequence + +from cmk.agent_based.v2 import AgentSection, CheckPlugin, Result, Service, State, StringTable + + +Section = Mapping[str, str] + + +def parse_os_info(string_table: StringTable) -> Section: + if not string_table: + return {} + + row: Sequence[str] = string_table[0] + fields = ("name", "version", "id", "version_id", "pretty", "architecture", "kernel") + values = list(row) + [""] * max(0, len(fields) - len(row)) + return dict(zip(fields, values[: len(fields)])) + + +def discover_os_info(section: Section): + if section: + yield Service() + + +def check_os_info(section: Section): + pretty = section.get("pretty") or section.get("name") or "Unbekannt" + architecture = section.get("architecture") or "unbekannt" + kernel = section.get("kernel") or "unbekannt" + + yield Result( + state=State.OK, + summary=f"{pretty}, Architektur: {architecture}", + details=( + f"Betriebssystem: {pretty}\n" + f"Name: {section.get('name', '')}\n" + f"Version: {section.get('version', '')}\n" + f"OS-ID: {section.get('id', '')}\n" + f"Version-ID/Build: {section.get('version_id', '')}\n" + f"Architektur: {architecture}\n" + f"Kernel: {kernel}" + ), + ) + + +agent_section_os_info = AgentSection( + name="os_info", + parse_function=parse_os_info, +) + +check_plugin_os_info = CheckPlugin( + name="os_info", + service_name="Betriebssystem", + discovery_function=discover_os_info, + check_function=check_os_info, +) diff --git a/os-info/src/cmk_addons_plugins/os_info/checkman/os_info b/os-info/src/cmk_addons_plugins/os_info/checkman/os_info new file mode 100644 index 0000000..ece46de --- /dev/null +++ b/os-info/src/cmk_addons_plugins/os_info/checkman/os_info @@ -0,0 +1,19 @@ +title: Betriebssystem +agents: check_mk +catalog: operating_system +license: GPLv2 +distribution: check_mk +description: + Dieses Plug-in erzeugt pro Host den Service "Betriebssystem". + Angezeigt werden Betriebssystem/Distribution, Version bzw. Build, + Architektur und Kernel-Version. + + Der mitgelieferte Agent-Plug-in muss auf den überwachten Linux-, macOS- + oder Windows-Systemen installiert werden. +item: + Kein Item. Pro Host wird genau ein Service erzeugt. +discovery: + Ein Service wird erkannt, sobald die Agent-Sektion <<>> vorhanden ist. +check: + Der Service ist OK und dient der übersichtlichen Anzeige der erkannten + Betriebssysteminformationen.