diff --git a/docs/widgets/services/checkmk.md b/docs/widgets/services/checkmk.md
new file mode 100644
index 000000000..b8bd54666
--- /dev/null
+++ b/docs/widgets/services/checkmk.md
@@ -0,0 +1,17 @@
+---
+title: Checkmk
+description: Checkmk Widget Configuration
+---
+
+Learn more about [Checkmk](https://github.com/Checkmk/checkmk).
+
+To setup authentication, follow the official [Checkmk API](https://docs.checkmk.com/latest/en/rest_api.html?lquery=api#bearerauth) documentation.
+
+```yaml
+widget:
+ type: checkmk
+ url: http://checkmk.host.or.ip:port
+ site: your-site-name-cla-by-default
+ username: username
+ password: password
+```
diff --git a/public/locales/en/common.json b/public/locales/en/common.json
index 59926094a..65d98db4a 100644
--- a/public/locales/en/common.json
+++ b/public/locales/en/common.json
@@ -1050,5 +1050,9 @@
"movies": "Movies",
"episodes": "Episodes",
"other": "Other"
+ },
+ "checkmk": {
+ "serviceErrors": "Service issues",
+ "hostErrors": "Host issues",
}
}
diff --git a/src/utils/proxy/handlers/credentialed.js b/src/utils/proxy/handlers/credentialed.js
index 779dbe332..da92de29f 100644
--- a/src/utils/proxy/handlers/credentialed.js
+++ b/src/utils/proxy/handlers/credentialed.js
@@ -34,6 +34,9 @@ export default async function credentialedProxyHandler(req, res, map) {
headers["X-CMC_PRO_API_KEY"] = `${widget.key}`;
} else if (widget.type === "gotify") {
headers["X-gotify-Key"] = `${widget.key}`;
+ } else if (widget.type === "checkmk") {
+ headers["Accept"] = `application/json`;
+ headers.Authorization = `Bearer ${widget.username} ${widget.password}`;
} else if (
[
"argocd",
diff --git a/src/widgets/checkmk/component.jsx b/src/widgets/checkmk/component.jsx
new file mode 100644
index 000000000..a156f4341
--- /dev/null
+++ b/src/widgets/checkmk/component.jsx
@@ -0,0 +1,40 @@
+import Block from "components/services/widget/block";
+import Container from "components/services/widget/container";
+import { useTranslation } from "next-i18next";
+
+import useWidgetAPI from "utils/proxy/use-widget-api";
+
+export default function Component({ service }) {
+ const { t } = useTranslation();
+
+ const { widget } = service;
+
+ const { data: servicesData, error: servicesError } = useWidgetAPI(widget, "services_info", {
+ columns: "state",
+ query: '{"op": "!=", "left": "state", "right": "0"}',
+ });
+ const { data: hostsData, error: hostsError } = useWidgetAPI(widget, "hosts_info", {
+ columns: "state",
+ query: '{"op": "!=", "left": "state", "right": "0"}',
+ });
+
+ if (servicesError || hostsError) {
+ return ;
+ }
+
+ if (!servicesData || !hostsData) {
+ return (
+
+
+
+
+ );
+ }
+
+ return (
+
+
+
+
+ );
+}
diff --git a/src/widgets/checkmk/widget.js b/src/widgets/checkmk/widget.js
new file mode 100644
index 000000000..b43ab46a7
--- /dev/null
+++ b/src/widgets/checkmk/widget.js
@@ -0,0 +1,19 @@
+import credentialedProxyHandler from "utils/proxy/handlers/credentialed";
+
+const widget = {
+ api: "{url}/{site}/check_mk/api/1.0/{endpoint}",
+ proxyHandler: credentialedProxyHandler,
+
+ mappings: {
+ services_info: {
+ endpoint: "domain-types/service/collections/all",
+ params: ["columns", "query"],
+ },
+ hosts_info: {
+ endpoint: "domain-types/host/collections/all",
+ params: ["columns", "query"],
+ },
+ },
+};
+
+export default widget;
diff --git a/src/widgets/components.js b/src/widgets/components.js
index 7f1bbd852..71c7f095a 100644
--- a/src/widgets/components.js
+++ b/src/widgets/components.js
@@ -16,6 +16,7 @@ const components = {
calibreweb: dynamic(() => import("./calibreweb/component")),
changedetectionio: dynamic(() => import("./changedetectionio/component")),
channelsdvrserver: dynamic(() => import("./channelsdvrserver/component")),
+ checkmk: dynamic(() => import("./checkmk/component")),
cloudflared: dynamic(() => import("./cloudflared/component")),
coinmarketcap: dynamic(() => import("./coinmarketcap/component")),
crowdsec: dynamic(() => import("./crowdsec/component")),
diff --git a/src/widgets/widgets.js b/src/widgets/widgets.js
index 8f143a934..b36ee5025 100644
--- a/src/widgets/widgets.js
+++ b/src/widgets/widgets.js
@@ -13,6 +13,7 @@ import calendar from "./calendar/widget";
import calibreweb from "./calibreweb/widget";
import changedetectionio from "./changedetectionio/widget";
import channelsdvrserver from "./channelsdvrserver/widget";
+import checkmk from "./checkmk/widget";
import cloudflared from "./cloudflared/widget";
import coinmarketcap from "./coinmarketcap/widget";
import crowdsec from "./crowdsec/widget";
@@ -151,6 +152,7 @@ const widgets = {
calibreweb,
changedetectionio,
channelsdvrserver,
+ checkmk,
cloudflared,
coinmarketcap,
crowdsec,