Add remote_access plugin 1.4.4
This commit is contained in:
commit
745719bb23
7 files changed
+479
No files matched your search
@@ -0,0 +1,29 @@
|
||||
# Changelog
|
||||
|
||||
## 1.4.4 - 2026-08-16
|
||||
|
||||
### Added
|
||||
- Direkter SSH-Zugriff aus `Setup → Hosts`
|
||||
- Direkter RDP-Zugriff aus `Setup → Hosts`
|
||||
- SSH-Icon in Monitoring- und Service-Problemansichten
|
||||
- RDP-Integration für Monitoring-Ansichten
|
||||
- Automatische Betriebssystemerkennung über `cmk/os_family`
|
||||
- Verwendung der von Checkmk ermittelten Host-IP
|
||||
- Eigene SVG-Icons für SSH und RDP
|
||||
- `Open SSH ↗` und `Open RDP ↗` Direktlinks
|
||||
|
||||
### Changed
|
||||
- Remote-Verbindungen verwenden jetzt bevorzugt `host_address`
|
||||
- Monitoring-Integration wurde auf Checkmk 2.5 angepasst
|
||||
- Autor des MKP ist `Domenik Bildhauer`
|
||||
|
||||
### Tested
|
||||
- Checkmk Community 2.5
|
||||
- Linux / Ubuntu → SSH
|
||||
- Windows 11 → RDP
|
||||
- PuTTY als SSH-Client unter Windows
|
||||
- `rdpadmin://` Protocol Handler
|
||||
- SSH-Icon in einer Monitoring-Service-Problemansicht
|
||||
|
||||
### Known / To Test
|
||||
- RDP-Icon aus einer Monitoring-Service-Problemansicht muss noch abschließend getestet werden
|
||||
@@ -0,0 +1,279 @@
|
||||
# Checkmk Remote Access
|
||||
|
||||
Direkter SSH- und RDP-Zugriff auf überwachte Hosts aus der Checkmk-Weboberfläche.
|
||||
|
||||
**Aktuelle Version:** 1.4.4
|
||||
**Autor:** Domenik Bildhauer
|
||||
**Zielplattform:** Checkmk Community 2.5
|
||||
|
||||
## Funktionen
|
||||
|
||||
Das Plugin erweitert Checkmk um Remote-Access-Funktionen für Linux-/Unix- und Windows-Hosts.
|
||||
|
||||
### Linux / Unix
|
||||
|
||||
Für Linux- und Unix-Systeme wird automatisch ein SSH-Zugriff angeboten.
|
||||
|
||||
Beispiel:
|
||||
|
||||
```text
|
||||
ssh://192.168.188.125
|
||||
```
|
||||
|
||||
Unterstützte Betriebssystemfamilien:
|
||||
|
||||
- Linux
|
||||
- Unix
|
||||
- FreeBSD
|
||||
- OpenBSD
|
||||
- Solaris
|
||||
- AIX
|
||||
|
||||
### Windows
|
||||
|
||||
Für Windows-Systeme wird ein RDP-Zugriff angeboten.
|
||||
|
||||
Beispiel:
|
||||
|
||||
```text
|
||||
rdpadmin://192.168.188.122
|
||||
```
|
||||
|
||||
`rdpadmin://` verwendet einen eigenen Windows Protocol Handler, der anschließend den Microsoft Remote Desktop Client (`mstsc.exe`) startet.
|
||||
|
||||
## Checkmk-Integration
|
||||
|
||||
### Setup → Hosts
|
||||
|
||||
In der Checkmk-Hostverwaltung werden abhängig vom Betriebssystem zusätzliche Remote-Access-Aktionen angezeigt:
|
||||
|
||||
- SSH-Icon für Linux-/Unix-Systeme
|
||||
- RDP-Icon für Windows-Systeme
|
||||
- `Open SSH ↗`
|
||||
- `Open RDP ↗`
|
||||
|
||||
### Monitoring
|
||||
|
||||
Das Plugin integriert SSH und RDP zusätzlich in die Icons-Spalte der Checkmk Monitoring Views.
|
||||
|
||||
Bei einem Linux-Host kann dadurch beispielsweise direkt aus einer Service-Problemansicht eine SSH-Verbindung gestartet werden.
|
||||
|
||||
## Automatische Betriebssystemerkennung
|
||||
|
||||
Die Entscheidung zwischen SSH und RDP erfolgt anhand der von Checkmk ermittelten Host-Labels.
|
||||
|
||||
Beispiel Linux:
|
||||
|
||||
```text
|
||||
cmk/os_family: linux
|
||||
cmk/os_platform: ubuntu
|
||||
cmk/os_name: Ubuntu
|
||||
cmk/os_version: 22.04
|
||||
```
|
||||
|
||||
Beispiel Windows:
|
||||
|
||||
```text
|
||||
cmk/os_family: windows
|
||||
```
|
||||
|
||||
Als Ziel für die Verbindung verwendet das Plugin bevorzugt `host_address`.
|
||||
|
||||
Beispiel:
|
||||
|
||||
```text
|
||||
Host:
|
||||
test-ssh.bildhauerd.com
|
||||
|
||||
Adresse:
|
||||
192.168.188.125
|
||||
|
||||
OS-Familie:
|
||||
linux
|
||||
```
|
||||
|
||||
Daraus entsteht:
|
||||
|
||||
```text
|
||||
ssh://192.168.188.125
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
Das fertige MKP befindet sich unter:
|
||||
|
||||
```text
|
||||
packages/remote_access-1.4.4.mkp
|
||||
```
|
||||
|
||||
Das Paket auf den Checkmk-Server kopieren und als Site-Benutzer installieren:
|
||||
|
||||
```bash
|
||||
mkp add /pfad/zu/remote_access-1.4.4.mkp
|
||||
mkp enable remote_access 1.4.4
|
||||
```
|
||||
|
||||
Danach den Apache der Checkmk-Site neu starten:
|
||||
|
||||
```bash
|
||||
omd restart apache
|
||||
```
|
||||
|
||||
Installation kontrollieren:
|
||||
|
||||
```bash
|
||||
mkp list
|
||||
```
|
||||
|
||||
## Upgrade
|
||||
|
||||
Eine vorherige Version zunächst deaktivieren, beispielsweise:
|
||||
|
||||
```bash
|
||||
mkp disable remote_access 1.4.3
|
||||
```
|
||||
|
||||
Danach die neue Version installieren und aktivieren:
|
||||
|
||||
```bash
|
||||
mkp add /pfad/zu/remote_access-1.4.4.mkp
|
||||
mkp enable remote_access 1.4.4
|
||||
omd restart apache
|
||||
```
|
||||
|
||||
Anschließend im Browser einen Hard-Reload durchführen.
|
||||
|
||||
## Source-Code
|
||||
|
||||
Der Source-Code befindet sich unter:
|
||||
|
||||
```text
|
||||
src/local/share/check_mk/
|
||||
```
|
||||
|
||||
Wichtige Dateien:
|
||||
|
||||
```text
|
||||
src/local/share/check_mk/web/plugins/wato/remote_access_setup.py
|
||||
|
||||
src/local/share/check_mk/web/plugins/views/remote_access_views.py
|
||||
|
||||
src/local/share/check_mk/web/htdocs/images/icons/remote_access_ssh.svg
|
||||
|
||||
src/local/share/check_mk/web/htdocs/images/icons/remote_access_rdp.svg
|
||||
```
|
||||
|
||||
### remote_access_setup.py
|
||||
|
||||
Integration der Remote-Access-Funktionen in:
|
||||
|
||||
```text
|
||||
Setup → Hosts
|
||||
```
|
||||
|
||||
### remote_access_views.py
|
||||
|
||||
Integration der Remote-Access-Icons in die Checkmk Monitoring Views.
|
||||
|
||||
Die Registrierung erfolgt über Checkmks Legacy-Web-Plugin-Schnittstelle:
|
||||
|
||||
```python
|
||||
multisite_icons_and_actions
|
||||
```
|
||||
|
||||
## Windows SSH
|
||||
|
||||
Damit ein Klick auf `ssh://` unter Windows funktioniert, muss das Protokoll einem geeigneten SSH-Client zugeordnet sein.
|
||||
|
||||
Getestet wurde die Verbindung mit PuTTY.
|
||||
|
||||
Ein direkter Aufruf funktioniert beispielsweise mit:
|
||||
|
||||
```text
|
||||
putty.exe 192.168.188.125
|
||||
```
|
||||
|
||||
## Windows RDP
|
||||
|
||||
Für RDP wird das benutzerdefinierte Protokoll
|
||||
|
||||
```text
|
||||
rdpadmin://
|
||||
```
|
||||
|
||||
verwendet.
|
||||
|
||||
Beispiel:
|
||||
|
||||
```text
|
||||
rdpadmin://192.168.188.122
|
||||
```
|
||||
|
||||
Der auf dem Windows-Client installierte Protocol Handler startet anschließend `mstsc.exe`.
|
||||
|
||||
Dadurch müssen keine `.rdp`-Dateien heruntergeladen werden.
|
||||
|
||||
## Fehlerdiagnose
|
||||
|
||||
Checkmk Web-Log:
|
||||
|
||||
```bash
|
||||
tail -n 50 ~/var/log/web.log
|
||||
```
|
||||
|
||||
Log vor einem Test leeren:
|
||||
|
||||
```bash
|
||||
: > ~/var/log/web.log
|
||||
omd restart apache
|
||||
```
|
||||
|
||||
Danach die betreffende Seite neu laden und prüfen:
|
||||
|
||||
```bash
|
||||
cat ~/var/log/web.log
|
||||
```
|
||||
|
||||
## Status 1.4.4
|
||||
|
||||
| Funktion | Status |
|
||||
|---|---|
|
||||
| Linux-Erkennung | ✅ Getestet |
|
||||
| Windows-Erkennung | ✅ Getestet |
|
||||
| SSH unter Setup → Hosts | ✅ Getestet |
|
||||
| RDP unter Setup → Hosts | ✅ Getestet |
|
||||
| SSH aus Monitoring-Ansicht | ✅ Getestet |
|
||||
| Eigene SSH-/RDP-Icons | ✅ |
|
||||
| Verwendung der Host-IP | ✅ |
|
||||
| RDP aus Monitoring-Problemansicht | ⏳ Noch abschließend zu testen |
|
||||
|
||||
## Repository-Struktur
|
||||
|
||||
```text
|
||||
remote_access/
|
||||
├── README.md
|
||||
├── CHANGELOG.md
|
||||
├── packages/
|
||||
│ └── remote_access-1.4.4.mkp
|
||||
└── src/
|
||||
└── local/
|
||||
└── share/
|
||||
└── check_mk/
|
||||
└── web/
|
||||
├── plugins/
|
||||
│ ├── wato/
|
||||
│ │ └── remote_access_setup.py
|
||||
│ └── views/
|
||||
│ └── remote_access_views.py
|
||||
└── htdocs/
|
||||
└── images/
|
||||
└── icons/
|
||||
├── remote_access_ssh.svg
|
||||
└── remote_access_rdp.svg
|
||||
```
|
||||
|
||||
## Lizenz
|
||||
|
||||
Dieses Plugin wurde für den Einsatz mit Checkmk Community entwickelt.
|
||||
|
||||
Checkmk ist eine Marke der Checkmk GmbH.
|
||||
Binary file not shown.
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="1" y="1" width="30" height="30" rx="5" fill="#0b0f12" stroke="#56616a" stroke-width="1"/>
|
||||
<rect x="7" y="7" width="18" height="13" rx="1" fill="none" stroke="#f4f6f8" stroke-width="2.5"/>
|
||||
<path d="M13 25 H19 M16 20 V25 M11 26 H21" fill="none" stroke="#f4f6f8" stroke-width="2.5" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 380 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect x="1" y="1" width="30" height="30" rx="5" fill="#0b0f12" stroke="#56616a" stroke-width="1"/>
|
||||
<path d="M8 9.5 L14.5 16 L8 22.5" fill="none" stroke="#f4f6f8" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M17 22.5 H24" fill="none" stroke="#f4f6f8" stroke-width="3" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 389 B |
@@ -0,0 +1,78 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from urllib.parse import quote
|
||||
|
||||
from cmk.gui.utils.html import HTML
|
||||
|
||||
_SSH_ICON = 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%3E%0A%3Crect%20x%3D%221%22%20y%3D%221%22%20width%3D%2230%22%20height%3D%2230%22%20rx%3D%225%22%20fill%3D%22%230b0f12%22%20stroke%3D%22%2356616a%22%20stroke-width%3D%221%22%2F%3E%0A%3Cpath%20d%3D%22M8%209.5%20L14.5%2016%20L8%2022.5%22%20fill%3D%22none%22%20stroke%3D%22%23f4f6f8%22%20stroke-width%3D%223%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%2F%3E%0A%3Cpath%20d%3D%22M17%2022.5%20H24%22%20fill%3D%22none%22%20stroke%3D%22%23f4f6f8%22%20stroke-width%3D%223%22%20stroke-linecap%3D%22round%22%2F%3E%0A%3C%2Fsvg%3E'
|
||||
_RDP_ICON = 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%3E%0A%3Crect%20x%3D%221%22%20y%3D%221%22%20width%3D%2230%22%20height%3D%2230%22%20rx%3D%225%22%20fill%3D%22%230b0f12%22%20stroke%3D%22%2356616a%22%20stroke-width%3D%221%22%2F%3E%0A%3Crect%20x%3D%227%22%20y%3D%227%22%20width%3D%2218%22%20height%3D%2213%22%20rx%3D%221%22%20fill%3D%22none%22%20stroke%3D%22%23f4f6f8%22%20stroke-width%3D%222.5%22%2F%3E%0A%3Cpath%20d%3D%22M13%2025%20H19%20M16%2020%20V25%20M11%2026%20H21%22%20fill%3D%22none%22%20stroke%3D%22%23f4f6f8%22%20stroke-width%3D%222.5%22%20stroke-linecap%3D%22round%22%2F%3E%0A%3C%2Fsvg%3E'
|
||||
|
||||
|
||||
def _remote_family(row):
|
||||
labels = row.get("host_labels") or {}
|
||||
if isinstance(labels, dict):
|
||||
return str(labels.get("cmk/os_family", "")).lower()
|
||||
return ""
|
||||
|
||||
|
||||
def _remote_target(row):
|
||||
return str(row.get("host_address") or row.get("host_name") or "")
|
||||
|
||||
|
||||
def _html_link(href, title, icon_uri):
|
||||
return HTML.without_escaping(
|
||||
'<a href="{href}" target="_top" title="{title}" '
|
||||
'style="display:inline-block;width:20px;height:20px;'
|
||||
'vertical-align:middle;background-image:url(\'{icon}\');'
|
||||
'background-repeat:no-repeat;background-position:center;'
|
||||
'background-size:20px 20px;text-decoration:none;"></a>'
|
||||
.format(
|
||||
href=href.replace("&", "&").replace('"', """),
|
||||
title=title.replace("&", "&").replace('"', """),
|
||||
icon=icon_uri.replace('"', "%22"),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def _paint_remote_ssh(what, row, tags, custom_vars, user_permissions, icon_config):
|
||||
if what not in ("host", "service"):
|
||||
return None
|
||||
if _remote_family(row) not in {"linux","unix","freebsd","openbsd","solaris","aix"}:
|
||||
return None
|
||||
target = _remote_target(row)
|
||||
if not target:
|
||||
return None
|
||||
href = "ssh://%s" % quote(target, safe=":.-[]")
|
||||
return _html_link(href, "SSH-Verbindung zu %s öffnen" % target, _SSH_ICON)
|
||||
|
||||
|
||||
def _paint_remote_rdp(what, row, tags, custom_vars, user_permissions, icon_config):
|
||||
if what not in ("host", "service"):
|
||||
return None
|
||||
if _remote_family(row) != "windows":
|
||||
return None
|
||||
target = _remote_target(row)
|
||||
if not target:
|
||||
return None
|
||||
href = "rdpadmin://%s" % quote(target, safe=":.-[]")
|
||||
return _html_link(href, "RDP-Verbindung zu %s öffnen" % target, _RDP_ICON)
|
||||
|
||||
|
||||
multisite_icons_and_actions["remote_access_ssh"] = {
|
||||
"title": "Remote Access SSH",
|
||||
"paint": _paint_remote_ssh,
|
||||
"columns": [],
|
||||
"host_columns": ["labels", "address"],
|
||||
"service_columns": [],
|
||||
"sort_index": 25,
|
||||
"toplevel": True,
|
||||
}
|
||||
|
||||
multisite_icons_and_actions["remote_access_rdp"] = {
|
||||
"title": "Remote Access RDP",
|
||||
"paint": _paint_remote_rdp,
|
||||
"columns": [],
|
||||
"host_columns": ["labels", "address"],
|
||||
"service_columns": [],
|
||||
"sort_index": 26,
|
||||
"toplevel": True,
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from urllib.parse import quote
|
||||
from cmk.gui.htmllib.html import html
|
||||
from cmk.gui.wato.pages import folders as _folders
|
||||
|
||||
ModeFolder = _folders.ModeFolder
|
||||
_SSH_ICON = 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%3E%0A%3Crect%20x%3D%221%22%20y%3D%221%22%20width%3D%2230%22%20height%3D%2230%22%20rx%3D%225%22%20fill%3D%22%230b0f12%22%20stroke%3D%22%2356616a%22%20stroke-width%3D%221%22%2F%3E%0A%3Cpath%20d%3D%22M8%209.5%20L14.5%2016%20L8%2022.5%22%20fill%3D%22none%22%20stroke%3D%22%23f4f6f8%22%20stroke-width%3D%223%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%2F%3E%0A%3Cpath%20d%3D%22M17%2022.5%20H24%22%20fill%3D%22none%22%20stroke%3D%22%23f4f6f8%22%20stroke-width%3D%223%22%20stroke-linecap%3D%22round%22%2F%3E%0A%3C%2Fsvg%3E'
|
||||
_RDP_ICON = 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%3E%0A%3Crect%20x%3D%221%22%20y%3D%221%22%20width%3D%2230%22%20height%3D%2230%22%20rx%3D%225%22%20fill%3D%22%230b0f12%22%20stroke%3D%22%2356616a%22%20stroke-width%3D%221%22%2F%3E%0A%3Crect%20x%3D%227%22%20y%3D%227%22%20width%3D%2218%22%20height%3D%2213%22%20rx%3D%221%22%20fill%3D%22none%22%20stroke%3D%22%23f4f6f8%22%20stroke-width%3D%222.5%22%2F%3E%0A%3Cpath%20d%3D%22M13%2025%20H19%20M16%2020%20V25%20M11%2026%20H21%22%20fill%3D%22none%22%20stroke%3D%22%23f4f6f8%22%20stroke-width%3D%222.5%22%20stroke-linecap%3D%22round%22%2F%3E%0A%3C%2Fsvg%3E'
|
||||
|
||||
if not getattr(ModeFolder, "_remote_access_144_patched", False):
|
||||
_original_show_host_actions = ModeFolder._show_host_actions
|
||||
|
||||
def _remote_access_data_by_host(self):
|
||||
cached = getattr(self, "_remote_access_data_cache", None)
|
||||
if cached is not None:
|
||||
return cached
|
||||
result = {}
|
||||
try:
|
||||
rows = _folders.Query(
|
||||
[_folders.Hosts.name, _folders.Hosts.labels, _folders.Hosts.address]
|
||||
).fetchall(sites=_folders.sites.live())
|
||||
for row in rows:
|
||||
if row.get("name") is not None:
|
||||
result[str(row["name"])] = {
|
||||
"labels": row.get("labels") or {},
|
||||
"address": row.get("address") or "",
|
||||
}
|
||||
except Exception:
|
||||
result = {}
|
||||
self._remote_access_data_cache = result
|
||||
return result
|
||||
|
||||
def _remote_access_icon(href, title, icon_uri):
|
||||
html.a(
|
||||
" ",
|
||||
href=href,
|
||||
target="_top",
|
||||
title=title,
|
||||
style=(
|
||||
"display:inline-block;width:22px;height:22px;margin-left:4px;"
|
||||
"vertical-align:middle;background-image:url('" + icon_uri + "');"
|
||||
"background-repeat:no-repeat;background-position:center;"
|
||||
"background-size:22px 22px;text-decoration:none;"
|
||||
),
|
||||
)
|
||||
|
||||
def _remote_access_button(href, label, title):
|
||||
html.a(
|
||||
label + " ↗",
|
||||
href=href,
|
||||
target="_top",
|
||||
title=title,
|
||||
style=(
|
||||
"display:inline-block;margin-left:4px;padding:2px 7px;"
|
||||
"border:1px solid #3f4d56;border-radius:4px;background:#11171b;"
|
||||
"color:#20e6a5;font-weight:600;font-size:12px;line-height:18px;"
|
||||
"text-decoration:none;vertical-align:middle;white-space:nowrap;"
|
||||
),
|
||||
)
|
||||
|
||||
def _remote_access_show_host_actions(self, host):
|
||||
_original_show_host_actions(self, host)
|
||||
hostname = str(host.name())
|
||||
data = _remote_access_data_by_host(self).get(hostname, {})
|
||||
family = str(data.get("labels", {}).get("cmk/os_family", "")).lower()
|
||||
target = str(data.get("address") or hostname)
|
||||
if not target:
|
||||
return
|
||||
|
||||
encoded = quote(target, safe=":.-[]")
|
||||
if family == "windows":
|
||||
href = "rdpadmin://" + encoded
|
||||
title = "RDP-Verbindung zu %s öffnen" % target
|
||||
_remote_access_icon(href, title, _RDP_ICON)
|
||||
_remote_access_button(href, "Open RDP", title)
|
||||
elif family in {"linux","unix","freebsd","openbsd","solaris","aix"}:
|
||||
href = "ssh://" + encoded
|
||||
title = "SSH-Verbindung zu %s öffnen" % target
|
||||
_remote_access_icon(href, title, _SSH_ICON)
|
||||
_remote_access_button(href, "Open SSH", title)
|
||||
|
||||
ModeFolder._show_host_actions = _remote_access_show_host_actions
|
||||
ModeFolder._remote_access_144_patched = True
|
||||
Reference in new issue
Block a user