def main(dry_run: bool = False): """ main script execution :param dry_run: if the script should be run without system modification :return: """ logger.log("newversion_check", "Daily OpenBSD version Check" + ["", " dry"][dry_run]) old_version = get_actual_version() new_version = increment_version(old_version).strip() url_new = base_repository + new_version + "/" if exist_http_page(url_new): logger.log("newversion_check", "WARNING: new OpenBSD version available!", 1) add_paragraph( "OpenBSD Version Check", message="**WARNING**: new OpenBSD version available [here](" + url_new + ")") else: logger.log("newversion_check", "no new OpenBSD version available!") # logger.log("newversion_check"," check at: '"+urlnew+"'") url_new = base_repository + old_version + "/" if not exist_http_page(url_new): logger.log_error("newversion_check", "Actual OpenBSD version no more supported") add_paragraph( "OpenBSD Version Check", message="**WARNING**: actual OpenBSD version no more supported") else: logger.log("newversion_check", "Actual OpenBSD version still available!")
def run_yearly(dry_run: bool = False): """ special yearly procedures """ run_monthly(True, dry_run) if dry_run: logger.log("robot", "Dry run procedure for testing yearly procedures") else: logger.log("exec", "run yearly procedures") from p06_year import run e = run(dry_run) for k, v in e.items(): if v != "Ok": logger.log_error("robot", k + " -> " + v) # # pack yearly # cwd = os.getcwd() os.chdir(log_dir) year_log = full_logfile.parent / (full_logfile.stem + "_year_" + str(the_date.year) + ".tgz") if year_log.exists(): return # already done cmd = "tar czf " + str(year_log) + " " + \ str(full_logfile.parent / full_logfile.stem) + "_month_" + str(the_date.year) + "_*.tgz " if dry_run: logger.log("yearly", "Packing dry:") logger.log("yearly", ">>> " + cmd) logger.log("yearly", ">>> logger.new_log") else: logger.log("yearly", "Packing") system_exec(cmd) logger.new_log() os.chdir(cwd) logger.log("yearly", "Happy new year!")
def run_monthly(last: bool = False, dry_run: bool = False): """ special monthly procedure """ if dry_run: logger.log("robot", "Dry run procedure for testing monthly procedures") else: logger.log("exec", "run monthly procedures") from p05_month import run e = run(dry_run) for k, v in e.items(): if v != "Ok": logger.log_error("robot", k + " -> " + v) # # pack monthly # cwd = os.getcwd() os.chdir(log_dir) month_log = full_logfile.parent / (full_logfile.stem + "_month_" + str(the_date.year) + "_" + str(the_date.month) + ".tgz") if month_log.exists(): return # already done year_log = full_logfile.parent / (full_logfile.stem + "_year_" + str(the_date.year) + ".tgz") if year_log.exists(): return # already done cmd = "tar czf " + str(month_log) + " " + str(full_logfile) if dry_run: logger.log("monthly", "Packing dry") logger.log("monthly", ">>> " + cmd) else: logger.log("monthly", "Packing") system_exec(cmd) if not last: logger.new_log() os.chdir(cwd)
def get_http_page(url: str, user: str = "", password: str = ""): """ get the content of the http page :param url: the url to get :param user: eventually the user for connection :param password: the password associated with the user :return: the content of the page """ res, h2 = get_http_response(url, user, password) if not res: return [] try: http_response = h2.getresponse() http_data = http_response.read().decode("ascii").splitlines() except Exception as err: logger.log_error("getHttpPage", " problem during response decoding: " + str(err)) h2.close() return [] if http_response.status != 200: logger.log_error( "getHttpPage", "bad http response: " + str(http_response.status) + " : " + str(http_response.reason)) h2.close() return http_data
def add_paragraph_with_array(title: str, level: int = 2, col_titles=None, rows=None, pre_message=None, post_message=None): """ :param title: :param level: :param col_titles: :param rows: :param pre_message: :param post_message: :return: """ if post_message is None: post_message = [] if pre_message is None: pre_message = [] if rows is None: rows = [] if col_titles is None: col_titles = [] test_mail() fd = open(md_mail_file, "a") fd.write("> " + "#" * level + " " + title + " " + "#" * level + "\n") # pre message for line in pre_message: fd.write("> " + line + "\n") fd.write(">\n") # array fd.write("> |") for col_title in col_titles: fd.write(" " + str(col_title) + " |") fd.write("\n") fd.write("> |") for col_title in col_titles: fd.write(" --- |") fd.write("\n") for r in rows: if len(r) != len(col_titles): logger.log_error( "mailing", "Problems with columns: wrong dimension: " + str(r) + str(col_titles)) continue fd.write("> |") for a in r: fd.write(" " + str(a) + " |") fd.write("\n") fd.write(">\n") # post message for line in post_message: fd.write("> " + line + "\n") fd.write("\n") fd.close()
def run_30sec(dry_run: bool = False): """ procedure run every 30 seconds """ if dry_run: logger.log("robot", "Dry run procedure for testing 30 seconds procedures") from p00_30seconds import run e = run(dry_run) for k, v in e.items(): if v != "Ok": logger.log_error("robot", k + " -> " + v)
def get_http_response(url: str, user: str = "", password: str = ""): """ do http requests :param url: the url to get the response :param user: user to use for request if needed :param password: password associated to the user :return: the http result """ valid_type = ["http", "https"] if "://" not in url: url = "http://" + url dec = urllib.parse.urlparse(url) if "." not in dec.netloc: logger.log_error("get_http_response", "Bad hostname: " + dec.netloc) return False, None if dec.scheme not in valid_type: logger.log_error( "get_http_response", "unsupported dec.scheme: '" + dec.scheme + "' valid type: " + str(valid_type)) return False, None try: # connection if dec.scheme == "http": h2 = http.client.HTTPConnection(dec.netloc, timeout=50) elif dec.scheme == "https": h2 = http.client.HTTPSConnection(dec.netloc, timeout=50) request = dec.path # request construction if dec.query != "": request += "?" + dec.query h2.putrequest("GET", request) # adding user information if user != "": auth_str = user + ":" + password auth_string = base64.b64encode( auth_str.encode("ascii")).decode("ascii").replace('\n', '') h2.putheader("AUTHORIZATION", "Basic " + auth_string) h2.endheaders() return True, h2 except TimeoutError as err: logger.log_error("get_http_response", "Request to: " + str(dec.netloc) + " has timed out!!") return False, None except http.client.HTTPException as err: logger.log_error( "get_http_response", "Request to: " + str(dec.netloc) + " has http error: " + str(err)) return False, None except Exception as err: logger.log_error( "get_http_response", "Request to: " + str(dec.netloc) + " has unknown error: " + str(err)) return False, None
def run_10min(dry_run: bool = False): """ procedure run every 10 minutes """ if dry_run: logger.log("robot", "Dry run procedure for testing 10 minutes procedures") else: logger.log("exec", "run 10 minutes procedures") from p01_tenmin import run e = run(dry_run) for k, v in e.items(): if v != "Ok": logger.log_error("robot", k + " -> " + v)
def run_special(dry_run: bool = False): """ run the content of the special folder """ if dry_run: logger.log("robot", "Dry run procedure for testing special procedures") else: logger.log("exec", "run special procedures") from p07_special import run e = run(dry_run) for k, v in e.items(): if v != "Ok": logger.log_error("robot", k + " -> " + v)
def run_weekly(dry_run: bool = False): """ weekly procedure """ run_daily(dry_run) if dry_run: logger.log("robot", "Dry run procedure for testing weekly procedures") else: logger.log("exec", "run weekly procedures") from p04_week import run e = run(dry_run) for k, v in e.items(): if v != "Ok": logger.log_error("robot", k + " -> " + v)
def run_daily(dry_run: bool = False): """ daily procedure """ run_hourly(dry_run, True) if dry_run: logger.log("robot", "Dry run procedure for testing daily procedures") else: logger.log("exec", "run daily procedures") from p03_day import run e = run(dry_run) for k, v in e.items(): if v != "Ok": logger.log_error("robot", k + " -> " + v)
def run_hourly(dry_run: bool = False, from_daily: bool = False): """ hourly procedures """ run_10min(dry_run) if dry_run: logger.log("robot", "Dry run procedure for testing hourly procedures") else: logger.log("exec", "run hourly procedures") from p02_hour import run e = run(dry_run) for k, v in e.items(): if v != "Ok": logger.log_error("robot", k + " -> " + v)
def newsyslog_forced(): """ monthly log rotate has to be forced :return: """ logger.log("monthly", "newsyslog forced") ret, lines = system_exec("/usr/bin/newsyslog -F") if len(lines) != 0: # il y a un probleme logger.log_error("monthly", "problem in newsyslog execution\n" + "\n".join(lines)) add_paragraph_with_lines( "newsyslog", pre_message=["problem in newsyslog execution"], lines=lines)
def locate_database(): """ update the locate database :return: """ # /usr/libexec/locate.updatedb logger.log("weekly", "Updating locate database") ret, lines = system_exec("/usr/libexec/locate.updatedb") if len(lines) != 0: # houston, we got a problem logger.log_error( "weekly", "problem in locate database update\n" + "\n".join(lines)) add_paragraph_with_lines( "locate_database", 3, pre_message=["Problems in locate database reconstruction"], lines=lines)
def whatis_database(): """ update the whatis database :return: """ # /usr/sbin/makewhatis logger.log("weekly", "whatis database update") ret, lines = system_exec("/usr/sbin/makewhatis") if len(lines) != 0: # il y a un probleme logger.log_error( "weekly", "problem in whatis database update\n" + "\n".join(lines)) add_paragraph_with_lines( "whatis_database", 3, pre_message=["problem in whatis database update"], lines=lines)
def check_packages(): """ check the package installation :return: """ # now check packages ret, lines = system_exec("pkg_check -xq") ok = True for line in lines: if "ok" not in line: ok = False break if not ok: # houston, we got a problem logger.log_error("weekly", "problem in packages\n" + "\n".join(lines)) add_paragraph_with_lines("check_packages", 3, pre_message=["problem in packages"], lines=lines)
def check_certificates(): """ check the actual certificates to see if a renewal has to be done :return: True if the certificates are still valid """ ret, lines = system_exec("/usr/local/bin/certbot certificates") if ret != 0: logger.log_error("autoSSLRenew", "getting certificates (" + str(ret) + ")") for line in lines: logger.log_error("autoSSLRenew", line) for line in lines: if "INVALID" in line: return False if "VALID:" in line: try: days = int(line.split("VALID:")[-1].split("day")[0]) except: return False if days < 25: return False return True
def sendmail(local_mail_file, local_mailing_list): """ :param local_mail_file: :param local_mailing_list: :return: """ ret, lines = system_exec("cat " + local_mail_file + " | sendmail " + local_mailing_list) if len(lines) == 0: return True # there is a problem temp_pb = False for line in lines: if "451" in line: temp_pb = True break if not temp_pb: # this is a true problem logger.log_error("mailing", "Mail sending problem:") for line in lines: logger.log("mailing", line) return False # attempt to restart smtpd: if not restart_smtpd(): # error during restart logger.log_error("mailing", "unable to restart smtpd") return False # resend message ret, lines = system_exec("cat " + local_mail_file + " | sendmail " + local_mailing_list) if len(lines) == 0: return True logger.log_error("mailing", "Mail sending problem:") for line in lines: logger.log("mailing", line) return False
def main(dry_run: bool = False): """ main script execution :param dry_run: if the script should be run without system modification :return: """ # if check_certificates(): logger.log("autoSSLRenew", "Certificates Still valid") add_paragraph("SSL renewal", message="SSL certificates are still valid") return logger.log("autoSSLRenew", "Certificates due to renewal") ret, lines = system_exec("/usr/local/bin/certbot renew" + ["", " --dry-run"][dry_run]) if ret != 0: logger.log_error("autoSSLRenew", "certbot return code (" + str(ret) + ")") for line in lines: logger.log_error("autoSSLRenew", line) return if check_certificates() or dry_run: logger.log("autoSSLRenew", "SSL Certificates have been successfully renewed") add_paragraph( "SSL renewal", message="SSL Certificates have been successfully renewed") if dry_run: return ret, lines = system_exec("rcctl restart apache2") if ret == 0: return logger.log_error("autoSSLRenew", "Unable to restart web server after renewal") for line in lines: logger.log_error("autoSSLRenew", line) ret, lines = system_exec("rcctl restart smtpd") if ret == 0: return logger.log_error("autoSSLRenew", "Unable to restart mail server after renewal") for line in lines: logger.log_error("autoSSLRenew", line) else: logger.log_error( "autoSSLRenew", "SSL Certificates are still invalid after renew\n" + "\n".join(lines)) add_paragraph_with_lines( "SSL renewal", pre_message=["SSL Certificates are still invalid after renew"], lines=lines)