Compare commits
4 commits
c1863033bc
...
0ee4239e62
Author | SHA1 | Date | |
---|---|---|---|
|
0ee4239e62 | ||
|
1c73542d29 | ||
|
456f923905 | ||
|
ae50084fcb |
6 changed files with 111 additions and 12 deletions
|
@ -2,6 +2,18 @@
|
||||||
rec {
|
rec {
|
||||||
mkFqdn = _: cfg: cfg.networking.fqdn;
|
mkFqdn = _: cfg: cfg.networking.fqdn;
|
||||||
|
|
||||||
|
probesWithTag =
|
||||||
|
{
|
||||||
|
name,
|
||||||
|
value ? null,
|
||||||
|
}:
|
||||||
|
probesConfig:
|
||||||
|
lib.filterAttrs (
|
||||||
|
k: v: lib.any (tag: tag.name == name && (value == null || tag.value == value)) v.tags
|
||||||
|
) probesConfig.monitors;
|
||||||
|
|
||||||
|
probesWithType = type: probesConfig: lib.filterAttrs (_: v: v.type == type) probesConfig.monitors;
|
||||||
|
|
||||||
fromHive =
|
fromHive =
|
||||||
{
|
{
|
||||||
builder,
|
builder,
|
||||||
|
|
|
@ -14,6 +14,10 @@ in
|
||||||
json = lib.mkOption { type = lib.types.package; };
|
json = lib.mkOption { type = lib.types.package; };
|
||||||
script = lib.mkOption { type = lib.types.package; };
|
script = lib.mkOption { type = lib.types.package; };
|
||||||
};
|
};
|
||||||
|
host = lib.mkOption {
|
||||||
|
default = null;
|
||||||
|
type = with lib.types; nullOr str;
|
||||||
|
};
|
||||||
extraFlags = lib.mkOption {
|
extraFlags = lib.mkOption {
|
||||||
default = [ ];
|
default = [ ];
|
||||||
example = [ "--scrape-http-keywords" ];
|
example = [ "--scrape-http-keywords" ];
|
||||||
|
@ -36,17 +40,23 @@ in
|
||||||
type = with lib.types; attrsOf probesFormat.type;
|
type = with lib.types; attrsOf probesFormat.type;
|
||||||
default = { };
|
default = { };
|
||||||
};
|
};
|
||||||
|
status_pages = lib.mkOption {
|
||||||
|
type = with lib.types; attrsOf probesFormat.type;
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config.statelessUptimeKuma = {
|
config.statelessUptimeKuma = {
|
||||||
lib = import ../lib { inherit lib; };
|
lib = import ../lib { inherit lib; };
|
||||||
|
extraFlags = lib.optional (cfg.host != null) "--host ${cfg.host}";
|
||||||
build = {
|
build = {
|
||||||
json = probesFormat.generate "probes.json" cfg.probesConfig;
|
json = probesFormat.generate "probes.json" cfg.probesConfig;
|
||||||
script = pkgs.writeShellApplication {
|
script = pkgs.writeShellApplication {
|
||||||
name = "deploy-uptime-kuma-probes";
|
name = "deploy-uptime-kuma-probes";
|
||||||
runtimeInputs = [ pkgs.statelessUptimeKuma ];
|
runtimeInputs = [ pkgs.statelessUptimeKuma ];
|
||||||
text = ''
|
text = ''
|
||||||
stateless-uptime-kuma apply-json -f ${cfg.build.json} ${builtins.concatStringsSep " " cfg.extraFlags}
|
args=("$@")
|
||||||
|
stateless-uptime-kuma apply-json -f ${cfg.build.json} ${builtins.concatStringsSep " " cfg.extraFlags} "''${args[@]}"
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -47,14 +47,35 @@ def cli():
|
||||||
help="Don't automatically create tags if not in tags section of input",
|
help="Don't automatically create tags if not in tags section of input",
|
||||||
default=False,
|
default=False,
|
||||||
)
|
)
|
||||||
def apply_json(file, scrape_http_keywords, no_autocreate_tags, keywords_fallback):
|
@click.option(
|
||||||
|
"--username",
|
||||||
|
prompt=True,
|
||||||
|
)
|
||||||
|
@click.option(
|
||||||
|
"--host",
|
||||||
|
prompt=True,
|
||||||
|
)
|
||||||
|
@click.option(
|
||||||
|
"--password",
|
||||||
|
prompt=True,
|
||||||
|
hide_input=True,
|
||||||
|
)
|
||||||
|
def apply_json(
|
||||||
|
file,
|
||||||
|
scrape_http_keywords,
|
||||||
|
no_autocreate_tags,
|
||||||
|
keywords_fallback,
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
host,
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Apply json probes
|
Apply json probes
|
||||||
"""
|
"""
|
||||||
logger.debug(
|
logger.debug(
|
||||||
f"Flags value:\n - scrape_http_keywords: {scrape_http_keywords}\n - no_autocreate_tags: {no_autocreate_tags}\n - keywords_fallback: {keywords_fallback}"
|
f"Flags value:\n - scrape_http_keywords: {scrape_http_keywords}\n - no_autocreate_tags: {no_autocreate_tags}\n - keywords_fallback: {keywords_fallback}"
|
||||||
)
|
)
|
||||||
with UptimeKumaApi("http://localhost:3001") as api:
|
with UptimeKumaApi(host) as api:
|
||||||
logging.debug("Reading json")
|
logging.debug("Reading json")
|
||||||
data = json.load(file)
|
data = json.load(file)
|
||||||
logging.debug("Parsing json")
|
logging.debug("Parsing json")
|
||||||
|
@ -62,9 +83,9 @@ def apply_json(file, scrape_http_keywords, no_autocreate_tags, keywords_fallback
|
||||||
if scrape_http_keywords:
|
if scrape_http_keywords:
|
||||||
hydrate_http_probes(tree)
|
hydrate_http_probes(tree)
|
||||||
logging.debug("Sync probes")
|
logging.debug("Sync probes")
|
||||||
api.login("admin", "123456789a")
|
api.login(username, password)
|
||||||
Manager(api, tree).process()
|
Manager(api, tree).process()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
cli()
|
cli(auto_envvar_prefix="STATELESS_UPTIME_KUMA")
|
||||||
|
|
|
@ -5,7 +5,7 @@ Classes to generate the item tree from json spec
|
||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from .uptime_kuma import Monitor, Notification, Tag
|
from .uptime_kuma import Monitor, Notification, StatusPage, Tag # type: ignore
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -44,8 +44,25 @@ def from_dict(api, tree, autocreate_tags=True):
|
||||||
]
|
]
|
||||||
monitor_kwargs["notifications"] = associated_notifications
|
monitor_kwargs["notifications"] = associated_notifications
|
||||||
indexed_monitors[monitor_name] = Monitor(api, monitor_name, **monitor_kwargs)
|
indexed_monitors[monitor_name] = Monitor(api, monitor_name, **monitor_kwargs)
|
||||||
|
status_pages = tree.get("status_pages", [])
|
||||||
|
indexed_status_pages = {}
|
||||||
|
for slug, kwargs in status_pages.items():
|
||||||
|
for group in kwargs.get("publicGroupList", []):
|
||||||
|
if "monitorList" in group:
|
||||||
|
monitorList = []
|
||||||
|
for monitor in group["monitorList"]:
|
||||||
|
if monitor not in indexed_monitors:
|
||||||
|
logger.error(
|
||||||
|
"Fatal: status page is referencing a monitor that doesn't exist"
|
||||||
|
)
|
||||||
|
sys.exit(1)
|
||||||
|
monitorList.append(indexed_monitors[monitor])
|
||||||
|
group["monitorList"] = monitorList
|
||||||
|
indexed_status_pages[slug] = StatusPage(api, slug, **kwargs)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"monitors": indexed_monitors.values(),
|
"monitors": indexed_monitors.values(),
|
||||||
"tags": indexed_tags.values(),
|
"tags": indexed_tags.values(),
|
||||||
"notifications": indexed_notifications.values(),
|
"notifications": indexed_notifications.values(),
|
||||||
|
"status_pages": indexed_status_pages.values(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ class Manager:
|
||||||
self.sync_tags()
|
self.sync_tags()
|
||||||
self.sync_notifications()
|
self.sync_notifications()
|
||||||
self.sync_monitors()
|
self.sync_monitors()
|
||||||
|
self.sync_status_pages()
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
|
@ -28,20 +29,25 @@ class Manager:
|
||||||
def sync_monitors(self):
|
def sync_monitors(self):
|
||||||
old = self.api.get_monitors()
|
old = self.api.get_monitors()
|
||||||
new = self.target_tree.get("monitors", [])
|
new = self.target_tree.get("monitors", [])
|
||||||
self.sync(new, old)
|
self.sync(new, old, "name")
|
||||||
|
|
||||||
def sync_notifications(self):
|
def sync_notifications(self):
|
||||||
old = self.api.get_notifications()
|
old = self.api.get_notifications()
|
||||||
new = self.target_tree.get("notifications", [])
|
new = self.target_tree.get("notifications", [])
|
||||||
self.sync(new, old)
|
self.sync(new, old, "name")
|
||||||
|
|
||||||
def sync_tags(self):
|
def sync_tags(self):
|
||||||
old = self.api.get_tags()
|
old = self.api.get_tags()
|
||||||
new = self.target_tree.get("tags", [])
|
new = self.target_tree.get("tags", [])
|
||||||
self.sync(new, old)
|
self.sync(new, old, "name")
|
||||||
|
|
||||||
def sync(self, new, old):
|
def sync_status_pages(self):
|
||||||
indexed_old = {elem["name"]: elem for elem in old}
|
old = self.api.get_status_pages()
|
||||||
|
new = self.target_tree.get("status_pages", [])
|
||||||
|
self.sync(new, old, "slug")
|
||||||
|
|
||||||
|
def sync(self, new, old, pk):
|
||||||
|
indexed_old = {elem[pk]: elem for elem in old}
|
||||||
for k in new:
|
for k in new:
|
||||||
if k.name in indexed_old:
|
if k.name in indexed_old:
|
||||||
k.id = indexed_old[k.name]["id"]
|
k.id = indexed_old[k.name]["id"]
|
||||||
|
@ -194,3 +200,36 @@ class Notification(Item):
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"Notification({str(self)})"
|
return f"Notification({str(self)})"
|
||||||
|
|
||||||
|
|
||||||
|
class StatusPage(Item):
|
||||||
|
def __init__(self, api, name, id=None, old_name=None, **kwargs):
|
||||||
|
super().__init__(api, name, id, old_name)
|
||||||
|
self.kwargs = kwargs
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
if self.saved:
|
||||||
|
return
|
||||||
|
logger.debug(f"Saving {repr(self)}")
|
||||||
|
if self.id is None:
|
||||||
|
self.api.add_status_page(
|
||||||
|
slug=self.name,
|
||||||
|
title=self.kwargs["title"],
|
||||||
|
)
|
||||||
|
rslt = self.api.get_status_page(self.name)
|
||||||
|
self.id = rslt["id"]
|
||||||
|
kwargs = self.kwargs
|
||||||
|
for group in kwargs.get("publicGroupList", []):
|
||||||
|
if "monitorList" in group:
|
||||||
|
monitorList = []
|
||||||
|
for monitor in group["monitorList"]:
|
||||||
|
monitorList.append({"id": monitor.id})
|
||||||
|
group["monitorList"] = monitorList
|
||||||
|
self.api.save_status_page(
|
||||||
|
slug=self.name,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
self.saved = True
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"StatusPage({str(self)})"
|
||||||
|
|
|
@ -30,7 +30,7 @@ buildPythonPackage rec {
|
||||||
packaging
|
packaging
|
||||||
python-socketio
|
python-socketio
|
||||||
requests
|
requests
|
||||||
];
|
] ++ python-socketio.optional-dependencies.client;
|
||||||
|
|
||||||
pythonImportsCheck = [ "uptime_kuma_api" ];
|
pythonImportsCheck = [ "uptime_kuma_api" ];
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue