mirror of
				https://github.com/karl0ss/homepage.git
				synced 2025-11-04 08:20:58 +00:00 
			
		
		
		
	Merge pull request #455 from FauFra/main
Feature: Added support to watchtower statistics
This commit is contained in:
		
						commit
						a76813893c
					
				@ -293,6 +293,11 @@
 | 
				
			|||||||
        "child_bridges": "Child Bridges",
 | 
					        "child_bridges": "Child Bridges",
 | 
				
			||||||
        "child_bridges_status": "{{ok}}/{{total}}"
 | 
					        "child_bridges_status": "{{ok}}/{{total}}"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "watchtower":{
 | 
				
			||||||
 | 
					        "containers_scanned": "Scanned",
 | 
				
			||||||
 | 
					        "containers_updated": "Updated",
 | 
				
			||||||
 | 
					        "containers_failed": "Failed"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "autobrr": {
 | 
					    "autobrr": {
 | 
				
			||||||
        "approvedPushes": "Approved",
 | 
					        "approvedPushes": "Approved",
 | 
				
			||||||
        "rejectedPushes": "Rejected",
 | 
					        "rejectedPushes": "Rejected",
 | 
				
			||||||
 | 
				
			|||||||
@ -37,6 +37,7 @@ const components = {
 | 
				
			|||||||
  traefik: dynamic(() => import("./traefik/component")),
 | 
					  traefik: dynamic(() => import("./traefik/component")),
 | 
				
			||||||
  transmission: dynamic(() => import("./transmission/component")),
 | 
					  transmission: dynamic(() => import("./transmission/component")),
 | 
				
			||||||
  unifi: dynamic(() => import("./unifi/component")),
 | 
					  unifi: dynamic(() => import("./unifi/component")),
 | 
				
			||||||
 | 
					  watchtower: dynamic(() => import("./watchtower/component")),
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default components;
 | 
					export default components;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										36
									
								
								src/widgets/watchtower/component.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/widgets/watchtower/component.jsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Container from "components/services/widget/container";
 | 
				
			||||||
 | 
					import Block from "components/services/widget/block";
 | 
				
			||||||
 | 
					import useWidgetAPI from "utils/proxy/use-widget-api";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default function Component({ service }) {
 | 
				
			||||||
 | 
					  const { t } = useTranslation();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const { widget } = service;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const { data: watchData, error: watchError } = useWidgetAPI(widget, "watchtower");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (watchError || !watchData) {
 | 
				
			||||||
 | 
					    return <Container error={t("widget.api_error")} />;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!watchData) {
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      <Container service={service}>
 | 
				
			||||||
 | 
					        <Block label="watchtower.containers_scanned " />
 | 
				
			||||||
 | 
					        <Block label="watchtower.containers_updated" />
 | 
				
			||||||
 | 
					        <Block label="watchtower.containers_failed" />
 | 
				
			||||||
 | 
					      </Container>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <Container service={service}>
 | 
				
			||||||
 | 
					      <Block label="watchtower.containers_scanned" value={t("common.number", { value: watchData.watchtower_containers_scanned })} />
 | 
				
			||||||
 | 
					      <Block label="watchtower.containers_updated" value={t("common.number", { value: watchData.watchtower_containers_updated })} />
 | 
				
			||||||
 | 
					      <Block label="watchtower.containers_failed" value={t("common.number", { value: watchData.watchtower_containers_failed })} />
 | 
				
			||||||
 | 
					    </Container>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										48
									
								
								src/widgets/watchtower/proxy.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/widgets/watchtower/proxy.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,48 @@
 | 
				
			|||||||
 | 
					import { httpProxy } from "utils/proxy/http";
 | 
				
			||||||
 | 
					import { formatApiCall } from "utils/proxy/api-helpers";
 | 
				
			||||||
 | 
					import getServiceWidget from "utils/config/service-helpers";
 | 
				
			||||||
 | 
					import createLogger from "utils/logger";
 | 
				
			||||||
 | 
					import widgets from "widgets/widgets";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const proxyName = "watchtowerProxyHandler";
 | 
				
			||||||
 | 
					const logger = createLogger(proxyName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default async function watchtowerProxyHandler(req, res) {
 | 
				
			||||||
 | 
					    const { group, service, endpoint } = req.query;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!group || !service) {
 | 
				
			||||||
 | 
					    logger.debug("Invalid or missing service '%s' or group '%s'", service, group);
 | 
				
			||||||
 | 
					    return res.status(400).json({ error: "Invalid proxy service type" });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const widget = await getServiceWidget(group, service);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!widget) {
 | 
				
			||||||
 | 
					    logger.debug("Invalid or missing widget for service '%s' in group '%s'", service, group);
 | 
				
			||||||
 | 
					    return res.status(400).json({ error: "Invalid proxy service type" });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const url = new URL(formatApiCall(widgets[widget.type].api, { endpoint, ...widget }));  
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  const [status, contentType, data] = await httpProxy(url, {
 | 
				
			||||||
 | 
					    method: "GET",
 | 
				
			||||||
 | 
					    headers: {
 | 
				
			||||||
 | 
					      "Authorization": `Bearer ${widget.key}`,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (status !== 200 || !data) {
 | 
				
			||||||
 | 
					    logger.error("Error getting data from WatchTower: %d.  Data: %s", status, data);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const cleanData = data.toString().split("\n").filter(s => s.startsWith("watchtower"))
 | 
				
			||||||
 | 
					  const jsonRes = {}
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  cleanData.map(e => e.split(" ")).forEach(strArray => { 
 | 
				
			||||||
 | 
					    const [key, value] = strArray
 | 
				
			||||||
 | 
					    jsonRes[key] = value
 | 
				
			||||||
 | 
					  }) 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (contentType) res.setHeader("Content-Type", contentType);
 | 
				
			||||||
 | 
					  return res.status(status).send(jsonRes);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										14
									
								
								src/widgets/watchtower/widget.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/widgets/watchtower/widget.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					import watchtowerProxyHandler from "./proxy";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const widget = {
 | 
				
			||||||
 | 
					  api: "{url}/{endpoint}",
 | 
				
			||||||
 | 
					  proxyHandler: watchtowerProxyHandler,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mappings: {
 | 
				
			||||||
 | 
					    "watchtower": {
 | 
				
			||||||
 | 
					      endpoint: "v1/metrics",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default widget;
 | 
				
			||||||
@ -32,6 +32,7 @@ import tautulli from "./tautulli/widget";
 | 
				
			|||||||
import traefik from "./traefik/widget";
 | 
					import traefik from "./traefik/widget";
 | 
				
			||||||
import transmission from "./transmission/widget";
 | 
					import transmission from "./transmission/widget";
 | 
				
			||||||
import unifi from "./unifi/widget";
 | 
					import unifi from "./unifi/widget";
 | 
				
			||||||
 | 
					import watchtower from './watchtower/widget'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const widgets = {
 | 
					const widgets = {
 | 
				
			||||||
  adguard,
 | 
					  adguard,
 | 
				
			||||||
@ -70,6 +71,7 @@ const widgets = {
 | 
				
			|||||||
  transmission,
 | 
					  transmission,
 | 
				
			||||||
  unifi,
 | 
					  unifi,
 | 
				
			||||||
  unifi_console: unifi,
 | 
					  unifi_console: unifi,
 | 
				
			||||||
 | 
					  watchtower,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default widgets;
 | 
					export default widgets;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user