};
};
};
+ eban = mkOption {
+ description = "Eban credentials for webhook";
+ type = submodule {
+ options = {
+ password = mkOption { type = str; description = "Password"; };
+ };
+ };
+ };
nrdp_tokens = mkOption { type = listOf str; description = "Tokens allowed to push status update"; };
slack_url = mkOption { type = str; description = "Slack webhook url to push status update"; };
slack_channel = mkOption { type = str; description = "Slack channel to push status update"; };
wrapProgram $out/notify_by_slack --prefix PATH : ${lib.makeBinPath [
pkgs.curl pkgs.jq
]}
+ wrapProgram $out/notify_eban_url --prefix PATH : ${lib.makeBinPath [
+ pkgs.curl
+ ]}
wrapProgram $out/check_ovh_sms --prefix PATH : ${lib.makeBinPath [
(pkgs.python3.withPackages (ps: [ps.ovh]))
]}
};
otherObjects = map
(n: (pkgs.callPackage (./. + "/objects_" + n + ".nix") { inherit emailCheck; }))
- [ "ulminfo-fr" "phare" ];
+ [ "ulminfo-fr" "phare" "eban" ];
masterObjects = pkgs.callPackage ./objects_master.nix { inherit config; };
commonObjects = pkgs.callPackage ./objects_common.nix ({
master = cfg.master;
config.myEnv.monitoring.ovh_sms.consumer_key
config.myEnv.monitoring.ovh_sms.account
]}
+ $USER210$=${config.myEnv.monitoring.eban.password}
'';
objectDefs = toObjects commonObjects
+ toObjects hostObjects
use = "linux-server";
hostgroups = "webstatus-hosts";
_webstatus_name = hostName;
+ _webstatus_vhost = "status.immae.eu";
};
};
service = [
# $OVE is to force naemon to run via shell instead of execve which fails here
notify-service-by-email = "ADMINEMAIL=\"$ADMINEMAIL$\" SERVICENOTIFICATIONID=\"$SERVICENOTIFICATIONID$\" SERVICEDESC=\"$SERVICEDESC$\" SERVICESTATE=\"$SERVICESTATE$\" SERVICEOUTPUT=\"$SERVICEOUTPUT$\" $USER2$/notify_by_email service \"$NOTIFICATIONTYPE$\" \"$HOSTALIAS$\" \"$LONGDATETIME$\" \"$CONTACTEMAIL$\" $OVE";
notify-by-slack = "HOST=\"$HOSTALIAS$\" SERVICESTATE=\"$SERVICESTATE$\" SERVICEDESC=\"$SERVICEDESC$\" SERVICEOUTPUT=\"$SERVICEOUTPUT$\" $USER2$/notify_by_slack \"$ARG1$\" \"$ARG2$\"";
+ notify-host-eban-url = "STATUS_NAME=\"Server\" PASSWORD=\"$USER210$\" HOSTSTATE=\"$HOSTSTATE$\" $USER2$/notify_eban_url";
+ notify-service-eban-url = "STATUS_NAME=\"$_SERVICEWEBSTATUS_NAME$\" PASSWORD=\"$USER210$\" SERVICESTATE=\"$SERVICESTATE$\" $USER2$/notify_eban_url";
notify-master = "$USER2$/send_nrdp.sh -u \"$USER200$\" -t \"$USER201$\" -H \"$HOSTADDRESS$\" -s \"$SERVICEDESC$\" -S \"$SERVICESTATEID$\" -o \"$SERVICEOUTPUT$ | $SERVICEPERFDATA$\"";
};
--- /dev/null
+{ ... }:
+let
+ serviceTemplate = rest: {
+ host_name = "eban.bzh";
+ use = "external-web-service";
+ contacts = "eban";
+ contact_groups = "null";
+ check_interval = "15";
+
+ servicegroups = "webstatus-resources";
+ } // rest;
+in
+{
+ contact = {
+ eban = {
+ use = "generic-contact";
+ host_notification_commands = "notify-host-eban-url";
+ service_notification_commands = "notify-service-eban-url";
+ };
+ };
+ host = {
+ "eban.bzh" = {
+ alias = "eban.bzh";
+ address = "eban.bzh";
+ use = "linux-server";
+ hostgroups = "webstatus-hosts";
+ contacts = "eban";
+ contact_groups = "null";
+ _webstatus_name = "Eban";
+ _webstatus_vhost = "status.eban.bzh";
+ };
+ };
+ service = [
+ (serviceTemplate {
+ service_description = "Eban website is up and running";
+ check_command = ["check_https" "eban.bzh" "/" "<title>"];
+ _webstatus_name = "Main Website";
+ _webstatus_url = "https://eban.bzh/";
+ })
+ (serviceTemplate {
+ service_description = "Eban blog is up and running";
+ check_command = ["check_https" "blog.eban.bzh" "/" "<title>"];
+ _webstatus_name = "Blog";
+ _webstatus_url = "https://blog.eban.bzh/";
+ })
+ (serviceTemplate {
+ service_description = "Eban gitea is up and running";
+ check_command = ["check_https" "git.eban.bzh" "/" "<title>"];
+ _webstatus_name = "Git";
+ _webstatus_url = "https://git.eban.bzh/";
+ })
+ (serviceTemplate {
+ service_description = "Eban Cloud is up and running";
+ check_command = ["check_https" "cloud.eban.bzh" "/" "<title>"];
+
+ _webstatus_name = "Cloud";
+ _webstatus_url = "https://cloud.eban.bzh/";
+ })
+ ];
+}
use = "linux-server";
hostgroups = "webstatus-hosts";
_webstatus_name = "phare";
+ _webstatus_vhost = "status.immae.eu";
};
};
service = [
contact_groups = "tiboqorl";
hostgroups = "webstatus-hosts";
_webstatus_name = "tiboqorl";
+ _webstatus_vhost = "status.immae.eu";
};
};
service = [
use = "linux-server";
hostgroups = "webstatus-hosts";
_webstatus_name = "ulminfo";
+ _webstatus_vhost = "status.immae.eu";
};
};
service = [
--- /dev/null
+#!/usr/bin/env bash
+
+PASS=$(echo "$PASSWORD" | base64 -d)
+
+if [ "$SERVICESTATE" = "CRITICAL" -o "$SERVICESTATE" = "UNKNOWN" -o "$HOSTSTATE" = "DOWN" -o "$HOSTSTATE" = "UNREACHABLE" ]; then
+ action=downAlert
+elif [ "$SERVICESTATE" = "OK" -o "$HOSTSTATE" = "UP" ]; then
+ action=upAlert
+fi
+
+if [ -n "$action" ]; then
+ curl -X GET -G --data-urlencode "service=$STATUS_NAME" --data-urlencode "mdp=$PASS" https://infra.eban.bzh/$action
+fi
upstreams."netdata".extraConfig = ''
keepalive 64;
'';
+ virtualHosts."status.eban.bzh" = {
+ acmeRoot = config.myServices.certificates.webroot;
+ useACMEHost = name;
+ forceSSL = true;
+ locations."/".proxyPass = "http://unix:/run/naemon-status/socket.sock:/";
+ };
virtualHosts."status.immae.eu" = {
acmeRoot = config.myServices.certificates.webroot;
useACMEHost = name;
};
security.acme.certs."${name}" = {
extraDomains."status.immae.eu" = null;
+ extraDomains."status.eban.bzh" = null;
user = config.services.nginx.user;
group = config.services.nginx.group;
};
return b"".join(chunks).decode()
class Host:
- def __init__(self, name, alias, status, webname):
+ def __init__(self, name, alias, status, webname, vhost):
self.name = name
self.alias = alias
self.webname = webname or alias
+ self.vhost = vhost
self.status = status
self.services = []
@classmethod
- def parse_hosts(cls, payload):
- parsed = [cls.parse(p) for p in json.loads(payload)]
+ def parse_hosts(cls, payload, vhost):
+ parsed = filter(lambda x: x.vhost == vhost, [cls.parse(p) for p in json.loads(payload)])
return {p.name: p for p in parsed}
@classmethod
def parse(cls, payload):
- return cls(payload[0], payload[1], HOST_STATUS[payload[2]], payload[3].get("WEBSTATUS_NAME"))
+ return cls(payload[0], payload[1], HOST_STATUS[payload[2]], payload[3].get("WEBSTATUS_NAME"), payload[3].get("WEBSTATUS_VHOST"))
def __repr__(self):
return "Host {}: {} ({})".format(self.name, self.alias, self.webname)
@classmethod
- def query(cls):
+ def query(cls, vhost):
answer = get_lq("""GET hosts
Filter: groups >= webstatus-hosts
Columns: name alias state custom_variables
OutputFormat: json
""")
- return cls.parse_hosts(answer)
+ return cls.parse_hosts(answer, vhost)
def fill_services(self, services):
self.services = [service for service in services if service.host == self.name]
""")
return cls.parse_groups(answer)
- def fill_services(self, services):
- self.services = [service for service in services if any([group == self.name for group in service.groups])]
+ def fill_services(self, services, hosts):
+ self.services = [service for service in services if any([group == self.name for group in service.groups]) and service.host in hosts]
def __repr__(self):
return "ServiceGroup {}: {}".format(self.name, self.alias)
def __repr__(self):
return "Service {}: {}".format(self.name, self.webname)
-def get_infos():
- hosts = Host.query()
+def get_infos(vhost):
+ hosts = Host.query(vhost)
servicegroups = ServiceGroup.query()
services = Service.query()
for host in hosts:
hosts[host].fill_services(services)
for group in servicegroups:
- servicegroups[group].fill_services(services)
+ servicegroups[group].fill_services(services, hosts)
return (hosts, servicegroups, services)
TEMPLATE='''<?xml version="1.0" encoding="UTF-8"?>
{% endfor %}
{%- endfor %}
+ {%- for group in servicegroups.values() if group.services and group.name != "webstatus-resources" %}
+ {%- if loop.first %}
<h2>Services</h2>
<div id="services">
- {%- for group in servicegroups.values() if group.services and group.name != "webstatus-resources" %}
+ {%- endif %}
<div class="servicegroup">
<h3 class="servicegroup_title">{{ group.alias }}</h3>
- {%- for service in group.services -%}
+ {%- for service in group.services if service.host in hosts -%}
{%- if loop.first %}
<ul class="services">
{% endif %}
{% endif %}
{%- endfor -%}
</div>
- {%- endfor %}
+ {%- if loop.last %}
</div>
+ {% endif %}
+ {%- endfor %}
</body>
</html>
'''
@app.route("/", methods=["GET"])
def get():
- (hosts, servicegroups, services) = get_infos()
+ (hosts, servicegroups, services) = get_infos(request.host)
resp = make_response(render_template_string(TEMPLATE, hosts=hosts, servicegroups=servicegroups))
resp.content_type = "text/html"
return resp
];
services.journald.extraConfig = ''
- MaxLevelStore=warning
+ #Should be "warning" but disabled for now, it prevents anything from being stored
+ MaxLevelStore=info
MaxRetentionSec=1year
'';
-Subproject commit 3d83a120a6247493e7cdac8d670ea85ebbfb711c
+Subproject commit 00f59f49098d79f0839541fd379e8933e3ddf9d7