diff --git a/bundles/uberspace-clerie-monitoring/files/prometheus-node-exporter-web-config.yml b/bundles/uberspace-clerie-monitoring/files/prometheus-node-exporter-web-config.yml new file mode 100644 index 0000000..11a1876 --- /dev/null +++ b/bundles/uberspace-clerie-monitoring/files/prometheus-node-exporter-web-config.yml @@ -0,0 +1,2 @@ +basic_auth_users: + monitor: "$2y$05$b4TibqWAj3MDv3g.SCaPZe9r6jV8Vowvn/CBZOdScwgkE7JcIuUfK" diff --git a/bundles/uberspace-clerie-monitoring/files/prometheus-node-exporter.ini b/bundles/uberspace-clerie-monitoring/files/prometheus-node-exporter.ini index d2baa9b..746b82a 100644 --- a/bundles/uberspace-clerie-monitoring/files/prometheus-node-exporter.ini +++ b/bundles/uberspace-clerie-monitoring/files/prometheus-node-exporter.ini @@ -1,6 +1,7 @@ [program:prometheus-node-exporter] command=prometheus-node-exporter --web.listen-address 0.0.0.0:9100 + --web.config.file=/home/{{ node.username }}/.config/prometheus-node-exporter/web-config.yml --collector.disable-defaults --collector.textfile --collector.textfile.directory=/home/{{ node.username }}/.local/state/prometheus-node-exporter/textfiles diff --git a/bundles/uberspace-clerie-monitoring/items.py b/bundles/uberspace-clerie-monitoring/items.py index 31c1db8..e4f01f1 100644 --- a/bundles/uberspace-clerie-monitoring/items.py +++ b/bundles/uberspace-clerie-monitoring/items.py @@ -22,6 +22,12 @@ files = uberspaceify.files({ "svc_uberspace_supervisord:prometheus-node-exporter:update", ], }, + f"/home/{node.username}/.config/prometheus-node-exporter/web-config.yml": { + "source": "prometheus-node-exporter-web-config.yml", + "triggers": [ + "svc_uberspace_supervisord:prometheus-node-exporter:restart", + ], + }, }) actions["prometheus-node-exporter-exists"] = { @@ -45,3 +51,9 @@ svc_uberspace_supervisord["prometheus-node-exporter"] = { f"file:/home/{node.username}/etc/services.d/prometheus-node-exporter.ini", ], } + +uberspace_web_backend["/.node-exporter"] = { + "backend": "http", + "port": 9100, + "remove_prefix": True, +} diff --git a/items/uberspace_web_backend.py b/items/uberspace_web_backend.py new file mode 100644 index 0000000..99ce591 --- /dev/null +++ b/items/uberspace_web_backend.py @@ -0,0 +1,138 @@ +from bundlewrap.exceptions import BundleError +from bundlewrap.items import Item + + +def backend_segments_to_dict(segments): + attributes = {} + + name = segments[0].strip() + + attributes["backend"] = segments[1].strip().rstrip(",") + + attributes["port"] = None + + if ":" in attributes["backend"]: + backend_segments = attributes["backend"].split(":") + attributes["backend"] = backend_segments[0] + attributes["port"] = int(backend_segments[1]) + + attributes["remove_prefix"] = None + + flag = segments[2] + if flag == "--remove-prefix": + attributes["remove_prefix"] = True + + return attributes + +def get_backend_config(node, name): + result = node.run("uberspace web backend list", may_fail=True) + backend_lines = result.stdout_text.splitlines() + + for line in backend_lines: + segments = line.split("=>", 1)[0].strip().split(" ") + if segments[0] == name: + d = backend_segments_to_dict(segments) + return d + +def make_display_string(name, attributes): + backend_name = attributes.get("backend") + if attributes.get("backend") == "http": + backend_name += f":{attributes.get('port')}" + + args = [ backend_name ] + + if attributes["remove_prefix"]: + args.append("--remove-prefix") + + arg_string = ", ".join(args) + + return f"{name} {arg_string}" + +def make_option_string(name, attributes): + out = [] + + out.append(name) + out.append(f" --{attributes.get('backend')}") + + if attributes.get("backend") == "http": + out.append("--port") + out.append(str(attributes.get('port'))) + + if attributes["remove_prefix"]: + out.append("--remove-prefix") + + return " ".join(out) + +class UberspaceWebBackend(Item): + """ + Manage uberspace web backends + """ + BUNDLE_ATTRIBUTE_NAME = "uberspace_web_backend" + ITEM_ATTRIBUTES = { + "backend": "apache", + "port": None, + "remove_prefix": None, + } + ITEM_TYPE_NAME = "uberspace_web_backend" + + def __repr__(self): + return f"" + + def cdict(self): + cdict = {} + for option, value in self.attributes.items(): + if value is not None: + cdict[option] = value + return cdict + + def fix(self, status): + self.node.run(f"uberspace web backend set {make_option_string(self.name, self.attributes)}", may_fail=True) + + def sdict(self): + return get_backend_config(self.node, self.name) + + @classmethod + def validate_attributes(cls, bundle, item_id, attributes): + + if attributes.get("backend") == "apache": + if attributes.get("port") is not None: + raise BundleError(_( + "do not set 'port' while using 'apache' for 'backend' on {item} in bundle '{bundle}'" + ).format( + item=item_id, + bundle=bundle.name, + )) + + if attributes.get("remove_prefix") is not None: + raise BundleError(_( + "do not set 'port' while using 'apache' for 'backend' on {item} in bundle '{bundle}'" + ).format( + item=item_id, + bundle=bundle.name, + )) + + elif attributes.get("backend") == "http": + if not isinstance(attributes.get("port"), int): + raise BundleError(_( + "'port' required and needs to be numeric while using 'http' for 'backend' on {item} in bundle '{bundle}'" + ).format( + item=item_id, + bundle=bundle.name, + )) + + if attributes.get("remove_prefix") not in [True, False, None]: + raise BundleError(_( + "expected boolean for 'remove_prefix' on {item} in bundle '{bundle}'" + ).format( + item=item_id, + bundle=bundle.name, + )) + + else: + raise BundleError(_( + "expected 'apache' or 'http' for 'backend' on {item} in bundle '{bundle}'" + ).format( + item=item_id, + bundle=bundle.name, + )) +