repo.libs.tools.require_bundle(node, 'postgresql') repo.libs.tools.require_bundle(node, 'sshmon') from os.path import join ENABLED_FEATURES = { 'api', 'checker', 'command', 'ido-pgsql', 'mainlog', 'notification', } DAYS_TO_STRING = [ 'sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday', ] directories = { '/etc/icingaweb2': { 'group': 'icingaweb2', 'mode': '2770', 'needs': { 'pkg_apt:icingaweb2', }, }, '/etc/icinga2/features-enabled': { 'owner': 'nagios', 'group': 'nagios', 'mode': '0750', 'purge': True, 'needs': { 'pkg_apt:icinga2-ido-pgsql', }, 'triggers': { 'svc_systemd:icinga2:restart', }, }, '/etc/icinga2/conf.d': { 'owner': 'nagios', 'group': 'nagios', 'mode': '0750', 'purge': True, 'needs': { 'pkg_apt:icinga2', }, 'triggers': { 'svc_systemd:icinga2:restart', }, }, '/etc/icinga2/conf.d/hosts': { 'owner': 'nagios', 'group': 'nagios', 'mode': '0750', 'purge': True, 'needs': { 'pkg_apt:icinga2', }, 'triggers': { 'svc_systemd:icinga2:restart', }, }, } files = { ### Checks '/usr/local/share/icinga/plugins/check_by_sshmon': { 'mode': '0755', }, '/usr/local/share/icinga/plugins/check_sipgate_account_balance': { 'mode': '0755', }, '/usr/local/share/icinga/plugins/check_freifunk_node': { 'mode': '0755', }, '/usr/local/share/icinga/plugins/check_imap_for_mail_from': { 'mode': '0755', }, '/usr/local/share/icinga/plugins/check_spam_blocklist': { 'mode': '0755', }, '/usr/local/share/icinga/plugins/check_usv_snmp': { 'mode': '0755', }, '/etc/sshmon.priv': { 'content': repo.vault.decrypt_file(join('sshmon', 'sshmon.key.vault')), 'owner': 'nagios', 'group': 'nagios', 'mode': '0400', 'needs': { 'pkg_apt:icinga2-ido-pgsql', }, }, # Icinga2 '/etc/icinga2/icinga2.conf': { 'source': 'icinga2/icinga2.conf', 'owner': 'nagios', 'group': 'nagios', 'mode': '0640', 'needs': { 'pkg_apt:icinga2', }, 'triggers': { 'svc_systemd:icinga2:restart', }, }, '/etc/icinga2/notification_config.json': { 'content': repo.libs.faults.dict_as_json({ 'sipgate': { 'user': node.metadata.get('icinga2/sipgate/user'), 'password': node.metadata.get('icinga2/sipgate/pass'), }, 'ntfy': { 'url': node.metadata.get('icinga2/ntfy/url'), 'user': node.metadata.get('icinga2/ntfy/user'), 'password': node.metadata.get('icinga2/ntfy/pass'), }, }), }, '/etc/icinga2/scripts/icinga_notification_wrapper': { 'source': 'scripts/icinga_notification_wrapper', 'mode': '0755', }, '/etc/icinga2/features-available/ido-pgsql.conf': { 'source': 'icinga2/ido-pgsql.conf', 'content_type': 'mako', 'owner': 'nagios', 'group': 'nagios', 'needs': { 'pkg_apt:icinga2', }, 'triggers': { 'svc_systemd:icinga2:restart', }, }, '/etc/icinga2/conf.d/api-users.conf': { 'source': 'icinga2/api-users.conf', 'content_type': 'mako', 'owner': 'nagios', 'group': 'nagios', 'needs': { 'pkg_apt:icinga2', }, 'triggers': { 'svc_systemd:icinga2:restart', }, }, '/etc/icinga2/conf.d/app.conf': { 'source': 'icinga2/app.conf', 'owner': 'nagios', 'group': 'nagios', 'needs': { 'pkg_apt:icinga2', }, 'triggers': { 'svc_systemd:icinga2:restart', }, }, '/etc/icinga2/conf.d/check_commands.conf': { 'source': 'icinga2/check_commands.conf', 'owner': 'nagios', 'group': 'nagios', 'needs': { 'pkg_apt:icinga2', }, 'triggers': { 'svc_systemd:icinga2:restart', }, }, '/etc/icinga2/conf.d/hosts.conf': { 'source': 'icinga2/hosts.conf', 'owner': 'nagios', 'group': 'nagios', 'needs': { 'pkg_apt:icinga2', }, 'triggers': { 'svc_systemd:icinga2:restart', }, }, '/etc/icinga2/conf.d/notification_commands.conf': { 'source': 'icinga2/notification_commands.conf', 'owner': 'nagios', 'group': 'nagios', 'needs': { 'pkg_apt:icinga2', }, 'triggers': { 'svc_systemd:icinga2:restart', }, }, '/etc/icinga2/conf.d/notifications.conf': { 'source': 'icinga2/notifications.conf', 'owner': 'nagios', 'group': 'nagios', 'needs': { 'pkg_apt:icinga2', }, 'triggers': { 'svc_systemd:icinga2:restart', }, }, '/etc/icinga2/conf.d/templates.conf': { 'source': 'icinga2/templates.conf', 'owner': 'nagios', 'group': 'nagios', 'needs': { 'pkg_apt:icinga2', }, 'triggers': { 'svc_systemd:icinga2:restart', }, }, '/etc/icinga2/conf.d/timeperiods.conf': { 'source': 'icinga2/timeperiods.conf', 'owner': 'nagios', 'group': 'nagios', 'needs': { 'pkg_apt:icinga2', }, 'triggers': { 'svc_systemd:icinga2:restart', }, }, '/etc/icinga2/conf.d/users.conf': { 'source': 'icinga2/users.conf', 'owner': 'nagios', 'group': 'nagios', 'content_type': 'mako', 'needs': { 'pkg_apt:icinga2', }, 'triggers': { 'svc_systemd:icinga2:restart', }, }, # IcingaWeb2 '/etc/icingaweb2/authentication.ini': { 'source': 'icingaweb2/authentication.ini', 'mode': '0660', 'group': 'icingaweb2', }, '/etc/icingaweb2/config.ini': { 'source': 'icingaweb2/config.ini', 'mode': '0660', 'group': 'icingaweb2', }, '/etc/icingaweb2/modules/monitoring/config.ini': { 'source': 'icingaweb2/monitoring_config.ini', 'mode': '0660', 'group': 'icingaweb2', }, '/etc/icingaweb2/groups.ini': { 'source': 'icingaweb2/groups.ini', 'mode': '0660', 'group': 'icingaweb2', }, '/etc/icingaweb2/resources.ini': { 'source': 'icingaweb2/resources.ini', 'content_type': 'mako', 'mode': '0660', 'group': 'icingaweb2', }, '/etc/icingaweb2/roles.ini': { 'source': 'icingaweb2/roles.ini', 'mode': '0660', 'group': 'icingaweb2', }, # Statusmonitor '/etc/icinga2/icinga_statusmonitor.py': { 'triggers': { 'svc_systemd:icinga_statusmonitor:restart', }, }, '/etc/systemd/system/icinga_statusmonitor.service': { 'triggers': { 'action:systemd-reload', 'svc_systemd:icinga_statusmonitor:restart', }, }, } pkg_pip = { 'easysnmp': {}, # for check_usv_snmp } actions = { 'icinga2_api_setup': { 'command': 'icinga2 api setup', 'unless': 'test -e /var/lib/icinga2/certs/{}.crt'.format(node.metadata['hostname']), 'needs': { 'pkg_apt:icinga2', }, 'triggers': { 'svc_systemd:icinga2:restart', }, }, } for feature in ENABLED_FEATURES: symlinks[f'/etc/icinga2/features-enabled/{feature}.conf'] = { 'target': f'/etc/icinga2/features-available/{feature}.conf', 'owner': 'nagios', 'group': 'nagios', 'needs': { 'pkg_apt:icinga2', }, 'triggers': { 'svc_systemd:icinga2:restart', }, } icinga_run_deps = { 'pkg_apt:icinga2', 'pkg_apt:icinga2-ido-pgsql', } for name in actions: icinga_run_deps.add(f'action:{name}') for name in directories: icinga_run_deps.add(f'directory:{name}') for name in files: icinga_run_deps.add(f'file:{name}') for name in symlinks: icinga_run_deps.add(f'symlink:{name}') svc_systemd = { 'icinga2': { 'needs': icinga_run_deps, }, 'icinga_statusmonitor': { 'needs': { 'file:/etc/icinga2/icinga_statusmonitor.py', 'file:/etc/systemd/system/icinga_statusmonitor.service', 'pkg_apt:python3-flask', }, }, } # The actual hosts and services management starts here bundles = set() downtimes = [] for rnode in sorted(repo.nodes): if rnode.metadata.get('icinga_options/exclude_from_monitoring', False): continue host_ips = repo.libs.tools.resolve_identifier(repo, rnode.name) icinga_ips = {} # XXX for the love of god, PLEASE remove this once DNS is no longer # hosted at GCE if rnode.in_group('gce'): icinga_ips['ipv4'] = rnode.metadata.get('external_ipv4') else: for ip_type in ('ipv4', 'ipv6'): for ip in sorted(host_ips[ip_type]): if ip.is_private and not ip.is_link_local: icinga_ips[ip_type] = str(ip) break else: if host_ips[ip_type]: icinga_ips[ip_type] = sorted(host_ips[ip_type])[0] if not icinga_ips: raise ValueError(f'{rnode.name} requests monitoring, but has neither IPv4 nor IPv6 addresses!') files[f'/etc/icinga2/conf.d/hosts/{rnode.name}.conf'] = { 'source': 'icinga2/hosts_template.conf', 'content_type': 'mako', 'context': { 'rnode': rnode, 'address4': icinga_ips.get('ipv4', None), 'address6': icinga_ips.get('ipv6', None), }, 'owner': 'nagios', 'group': 'nagios', 'cascade_skip': False, # may contain faults 'triggers': { 'svc_systemd:icinga2:restart', }, } bundles |= set(rnode.metadata.get('icinga2_api', {}).keys()) if rnode.has_any_bundle(['apt', 'c3voc-addons']): day = rnode.metadata.get('apt/unattended-upgrades/day') hour = rnode.metadata.get('apt/unattended-upgrades/hour') minute = rnode.magic_number%30 spread = rnode.metadata.get('apt/unattended-upgrades/spread_in_group', None) if spread is not None: spread_nodes = sorted(repo.nodes_in_group(spread)) day += spread_nodes.index(rnode) downtimes.append({ 'name': 'unattended-upgrades', 'host': rnode.name, 'comment': f'Downtime for upgrade-and-reboot of node {rnode.name}', 'times': { DAYS_TO_STRING[day%7]: f'{hour}:{minute}-{hour}:{minute+30}', }, }) elif ( rnode.has_bundle('pacman') and rnode.metadata.get('pacman/unattended-upgrades/is_enabled', False) ): day = rnode.metadata.get('pacman/unattended-upgrades/day') hour = rnode.metadata.get('pacman/unattended-upgrades/hour') minute = rnode.magic_number%30 downtimes.append({ 'name': 'unattended-upgrades', 'host': rnode.name, 'comment': f'Downtime for upgrade-and-reboot of node {rnode.name}', 'times': { DAYS_TO_STRING[day%7]: f'{hour}:{minute}-{hour}:{minute+30}', }, }) files['/etc/icinga2/conf.d/groups.conf'] = { 'source': 'icinga2/groups.conf', 'content_type': 'mako', 'context': { 'bundles': bundles, }, 'owner': 'nagios', 'group': 'nagios', 'needs': { 'pkg_apt:icinga2', }, 'triggers': { 'svc_systemd:icinga2:restart', }, } files['/etc/icinga2/conf.d/downtimes.conf'] = { 'source': 'icinga2/downtimes.conf', 'content_type': 'mako', 'context': { 'downtimes': downtimes, }, 'owner': 'nagios', 'group': 'nagios', 'needs': { 'pkg_apt:icinga2', }, 'triggers': { 'svc_systemd:icinga2:restart', }, }