#!/usr/bin/env python3 """ Criticality: Normal Check updates, apt state and unattended upgrade config. """ import apt as apt_mod import apt_pkg import os from pathlib import Path import requests import sys try: from requests.packages.urllib3.exceptions import InsecureRequestWarning requests.packages.urllib3.disable_warnings(InsecureRequestWarning) except ImportError: requests.packages.urllib3.disable_warnings() sys.path.append(str(Path(__file__).parents[1].resolve())) import utils as u # noqa: E402 from utils_lib.apt import Apt # noqa: E402 from utils_lib.os import line_in_file # noqa: E402 def main(): warnings = 0 errors = 0 os.environ["DEBIAN_FRONTEND"] = "noninteractive" os.environ["PATH"] = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" print("Checking APT state:") try: apt = Apt(update=True) except apt_mod.cache.FetchFailedException as apt_cache_err: if str(apt_cache_err).endswith("no longer has a Release file."): u.error("system out of support") errors += 1 else: u.error("Apt error: {}".format(apt_cache_err)) errors += 1 apt = Apt() # detect pending upgrade upgradable = len(apt.upgradable_packages) if upgradable: u.info("there is {} upgrade pending".format(upgradable)) else: u.success("system up-to-date") # detect pending auto-remove removable = len(apt.removable_packages) if removable: u.warning("there is {} auto-removable packages".format(removable)) warnings += 1 else: u.success("system clean") # detect rc state purgeable = len(apt.purgeable_packages) if purgeable: u.info("there is {} packages in rc state".format(purgeable)) # installation try: installed = apt.install("sl") except apt_pkg.Error as apt_install_err: u.warning(apt_install_err) warnings += 1 else: if installed: u.success("installation successful") apt.remove("sl") else: u.error("installation failed") errors += 1 # unattended-upgrades if ( Path("/etc/apt/apt.conf.d/20auto-upgrades").exists() and Path("/etc/apt/apt.conf.d/50unattended-upgrades").exists() and line_in_file( r'^APT::Periodic::Update-Package-Lists "1";$', "/etc/apt/apt.conf.d/20auto-upgrades", ) and line_in_file( r'^APT::Periodic::Unattended-Upgrade "1";$', "/etc/apt/apt.conf.d/20auto-upgrades", ) and line_in_file( r"^Unattended-Upgrade::(?:(?:Allowed-Origins)|(?:Origins-Pattern)) {$", "/etc/apt/apt.conf.d/50unattended-upgrades", ) ): u.success("automatic security updates enabled") else: u.warning("automatic security updates not enabled") warnings += 1 # check ubicast repository presence ubicast_repo = Path("/etc/apt/sources.list.d/skyreach.list").exists() ubicast_package = ( True if apt.is_installed("ubicast-mediaserver") or apt.is_installed("ubicast-monitor") or apt.is_installed("ubicast-skyreach") or apt.is_installed("ubicast-skyreach-erp") or apt.is_installed("celerity-server") or apt.is_installed("celerity-utils") or apt.is_installed("celerity-workers") # older versions or apt.is_installed("python3-mediaserver") or apt.is_installed("python3-mediaserver-monitor") or apt.is_installed("campus-manager") else False ) if ubicast_repo and ubicast_package: u.success("ubicast repository present") elif not ubicast_repo and ubicast_package: u.error("ubicast repository missing") errors += 1 elif not ubicast_repo and not ubicast_package: u.info("no ubicast repository and service installed") return 2 else: u.info("no ubicast service installed") # check ubicast repository url regexp_repo = ( r"^deb (http[s]?://[A-Za-z0-9\.\-\_]+) packaging/apt/([A-Za-z0-9\.\-\_]+)/$" ) repo_url_match = line_in_file(regexp_repo, "/etc/apt/sources.list.d/skyreach.list") if repo_url_match: url, apt_token = repo_url_match.groups() u.success("url: {}, token: {}[...]".format(url, apt_token[:8])) else: url, apt_token = None, None u.error("incorrect ubicast repository url or token") errors += 1 # check server avalability if url: server_response = requests.get(url, verify=False) if server_response.ok: u.success("request to {} succeeded".format(url)) else: u.error("request to {} failed: {}".format(url, server_response.text)) errors += 1 # check repository avalability if url and apt_token: apt_url = "{}/packaging/apt/{}/Packages".format(url, apt_token) repo_response = requests.get(apt_url, verify=False) apt_url = "{}/packaging/apt/{}[...]/Packages".format(url, apt_token[:8]) if repo_response.ok: u.success("request to {} succeeded".format(apt_url)) else: u.error("request to {} failed: {}".format(apt_url, repo_response.text)) errors += 1 if errors: return 1 elif warnings: return 3 else: return 0 if __name__ == "__main__": exit(main())