stateless-uptime-kuma/stateless_uptime_kuma/uptime_kuma.py
2024-04-18 17:35:28 +02:00

177 lines
5.1 KiB
Python

"""
Classes to make the needed operations to reach the specified state.
"""
import logging
logger = logging.getLogger(__name__)
class Manager:
def __init__(self, api, target_tree={}, prune_unused=False):
self.api = api
self.prune_unused = prune_unused
self.target_tree = target_tree
def process(self):
self.sync_tags()
self.sync_notifications()
self.sync_monitors()
self.save()
def save(self):
for v in self.target_tree.values():
for i in v:
i.save() # this method should be safe to be called in whatever order
def sync_monitors(self):
old = self.api.get_monitors()
new = self.target_tree.get("monitors", [])
self.sync(new, old)
def sync_notifications(self):
old = self.api.get_notifications()
new = self.target_tree.get("notifications", [])
self.sync(new, old)
def sync_tags(self):
old = self.api.get_tags()
new = self.target_tree.get("tags", [])
self.sync(new, old)
def sync(self, new, old):
indexed_old = {elem["name"]: elem for elem in old}
for k in new:
if k.name in indexed_old:
k.id = indexed_old[k.name]["id"]
logger.debug(f"Synced item named {k}")
if k.old_name is not None:
logger.warn(f"Found unused oldName for {k}")
elif k.old_name in indexed_old:
k.id = indexed_old[k.old_name]["id"]
logger.info(f"Found renamed item {k.old_name} -> {k}")
else:
k.id = None # Useless
logger.debug(f"Creating key {k}")
class Item:
def __init__(self, api, name, id, old_name=None):
self.api = api
self.name = name
self.id = id
self.old_name = old_name
self.saved = False
def save(self):
raise NotImplementedError()
def __setattr__(self, name, value):
if name != "saved":
self.saved = False
object.__setattr__(self, name, value)
def __str__(self):
return self.name
class Monitor(Item):
def __init__(
self, api, name, id=None, old_name=None, tags=[], notifications=[], **kwargs
):
super().__init__(api, name, id, old_name)
self.kwargs = kwargs
self.tags = tags
self.notifications = notifications
self.saved = False
def save(self):
if self.saved:
return
logger.debug(f"Saving {repr(self)}")
for t, _ in self.tags:
t.save()
for n in self.notifications:
n.save()
if self.id is None:
rslt = self.api.add_monitor(
name=self.name,
notificationIDList=[i.id for i in self.notifications],
**self.kwargs,
)
self.id = rslt["monitorID"]
for t, value in self.tags:
self.api.add_monitor_tag(tag_id=t.id, monitor_id=self.id, value=value)
else:
rslt = self.api.edit_monitor(
self.id,
name=self.name,
notificationIDList=[i.id for i in self.notifications],
**self.kwargs,
)
current_tags = set(
(i["tag_id"], i["value"]) for i in self.api.get_monitor(self.id)["tags"]
)
for t, v in self.tags:
if (t, v) not in current_tags:
logger.debug(f"Adding tag: '{t}, {v}'")
self.api.add_monitor_tag(tag_id=t.id, monitor_id=self.id, value=v)
self.saved = True
def __repr__(self):
return f"Monitor({str(self)})"
class Tag(Item):
def __init__(self, api, name, id=None, old_name=None, color="#000000"):
super().__init__(api, name, id, old_name)
self.tag = name
self.color = color
def save(self):
if self.saved:
return
logger.debug(f"Saving {repr(self)}")
if self.id is None:
rslt = self.api.add_tag(
name=self.tag,
color=self.color,
)
self.id = rslt["id"]
else:
self.api.edit_tag(
id_=self.id,
name=self.tag,
color=self.color,
)
self.saved = True
def __repr__(self):
return f"Tag({str(self)})"
class Notification(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:
rslt = self.api.add_notification(
name=self.name,
**self.kwargs,
)
self.id = rslt["id"]
else:
self.api.edit_notification(
id_=self.id,
name=self.name,
**self.kwargs,
)
self.saved = True
def __repr__(self):
return f"Notification({str(self)})"