Skip to content

Commit

Permalink
Feature: Headscale Service Widget (#4247)
Browse files Browse the repository at this point in the history
  • Loading branch information
erelender authored Nov 5, 2024
1 parent 6fd2b6b commit c12a5c0
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 0 deletions.
19 changes: 19 additions & 0 deletions docs/widgets/services/headscale.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
title: Headscale
description: Headscale Widget Configuration
---

Learn more about [Headscale](https://headscale.net/).

You will need to generate an API access token from the [command line](https://headscale.net/ref/remote-cli/#create-an-api-key) using `headscale apikeys create` command.

To find your node ID, you can use `headscale nodes list` command.

Allowed fields: `["name", "address", "last_seen", "status"]`.

```yaml
widget:
type: headscale
nodeId: nodeid
key: headscaleapiaccesstoken
```
1 change: 1 addition & 0 deletions docs/widgets/services/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ You can also find a list of all available service widgets in the sidebar navigat
- [Gotify](gotify.md)
- [Grafana](grafana.md)
- [HDHomeRun](hdhomerun.md)
- [Headscale](headscale.md)
- [Healthchecks](healthchecks.md)
- [Home Assistant](homeassistant.md)
- [HomeBox](homebox.md)
Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ nav:
- widgets/services/gotify.md
- widgets/services/grafana.md
- widgets/services/hdhomerun.md
- widgets/services/headscale.md
- widgets/services/healthchecks.md
- widgets/services/homeassistant.md
- widgets/services/homebox.md
Expand Down
8 changes: 8 additions & 0 deletions public/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -959,5 +959,13 @@
"tasks7d": "Tasks Due This Week",
"tasksOverdue": "Overdue Tasks",
"tasksInProgress": "Tasks In Progress"
},
"headscale": {
"name": "Name",
"address": "Address",
"last_seen": "Last Seen",
"status": "Status",
"online": "Online",
"offline": "Offline"
}
}
1 change: 1 addition & 0 deletions src/utils/proxy/handlers/credentialed.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export default async function credentialedProxyHandler(req, res, map) {
"authentik",
"cloudflared",
"ghostfolio",
"headscale",
"linkwarden",
"mealie",
"netalertx",
Expand Down
1 change: 1 addition & 0 deletions src/widgets/components.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const components = {
gotify: dynamic(() => import("./gotify/component")),
grafana: dynamic(() => import("./grafana/component")),
hdhomerun: dynamic(() => import("./hdhomerun/component")),
headscale: dynamic(() => import("./headscale/component")),
peanut: dynamic(() => import("./peanut/component")),
homeassistant: dynamic(() => import("./homeassistant/component")),
homebox: dynamic(() => import("./homebox/component")),
Expand Down
43 changes: 43 additions & 0 deletions src/widgets/headscale/component.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
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: nodeData, error: nodeError } = useWidgetAPI(widget, "node");

if (nodeError) {
return <Container service={service} error={nodeError} />;
}

if (!nodeData) {
return (
<Container service={service}>
<Block label="headscale.name" />
<Block label="headscale.address" />
<Block label="headscale.last_seen" />
<Block label="headscale.status" />
</Container>
);
}

const {
givenName,
ipAddresses: [address],
lastSeen,
online,
} = nodeData.node;

return (
<Container service={service}>
<Block label="headscale.name" value={givenName} />
<Block label="headscale.address" value={address} />
<Block label="headscale.last_seen" value={t("common.relativeDate", { value: lastSeen })} />
<Block label="headscale.status" value={t(online ? "headscale.online" : "headscale.offline")} />
</Container>
);
}
14 changes: 14 additions & 0 deletions src/widgets/headscale/widget.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import credentialedProxyHandler from "utils/proxy/handlers/credentialed";

const widget = {
api: "{url}/api/v1/{endpoint}/{nodeId}",
proxyHandler: credentialedProxyHandler,

mappings: {
node: {
endpoint: "node",
},
},
};

export default widget;
2 changes: 2 additions & 0 deletions src/widgets/widgets.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import gluetun from "./gluetun/widget";
import gotify from "./gotify/widget";
import grafana from "./grafana/widget";
import hdhomerun from "./hdhomerun/widget";
import headscale from "./headscale/widget";
import homeassistant from "./homeassistant/widget";
import homebox from "./homebox/widget";
import homebridge from "./homebridge/widget";
Expand Down Expand Up @@ -161,6 +162,7 @@ const widgets = {
gotify,
grafana,
hdhomerun,
headscale,
homeassistant,
homebox,
homebridge,
Expand Down

0 comments on commit c12a5c0

Please sign in to comment.