#!/bin/python3 #importing the required modules import json import subprocess #file which will hold the online/offline status of servers file = "status.json" #creating dictionary containing current server hostnames/ips from json try: with open("/root/servers.json") as f: servers = json.load(f) except FileNotFoundError: raise RuntimeError("servers json file not found") #function for pinging servers to check if they are offline #logic: create empty dictionary called status #loop over pre-defined servers dictionary, key is server, value is ip #ping each server's ip #if the return code for the ping is 0, the server's online status is true #else its false/offline/unreachable def online_check(): status = {} for server, ip in servers.items(): result = subprocess.run( ["ping", "-c", "2", "-W", "1", ip], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL ) if result.returncode == 0: status[server] = True else: status[server] = False return status #function for sending an email notification #logic: we are defining this subprocess as notify #any argument given to it becomes "email" #we later pass offline_message/online_message to it as the email to send def notify(email): subprocess.run( ["msmtp", "cool@dude.wow"], input=email, text=True ) #check to see if we can ping apache-intranet #(primary server for porygon monitoring) result = subprocess.run( ["ping", "-c", "5", "-W", "2", "200.201.202.203"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL ) #if apache-intranet is currently offline #and we have a current status.json #build previous status dictionary from it try: with open(file) as f: previous_status = json.load(f) except FileNotFoundError: pass if result.returncode == 0: print("apache-intranet is online") #apache-intranet is online #delete status.json #only need to keep track during outages #this server is the backup subprocess.run(["rm", "-f", file]) else: #apache-intranet is not offline #check if status.json exists #if it does we are currently in the midst of an outage check = subprocess.run(["test", "-f", file]) if check.returncode == 0: status = online_check() for server, ip in servers.items(): if status[server] == True: if previous_status.get(server) == False: online_message = f"""To: this@again.com Subject: {server} is back online {server} at {ip} looks to be back online and is now respon> """ notify(online_message) if status[server] == False: if previous_status.get(server) == True: offline_message = f"""To: lmao@haha.lol Subject: {server} is offline {server} at {ip} looks to be offline and is no longer responding to pings. """ notify(offline_message) with open(file, "w") as f: json.dump(status, f, indent=4) #if status.json does not exist #but apache-intranet is not reachable #then this is the moment porygon has become aware of the outage #we have no reference to track back online/healing alerts #only offline ones else: subprocess.run(["touch", file]) status = online_check() for server, ip in servers.items(): offline_message = f"""To: oh.no@all.offline Subject: {server} is offline {server} at {ip} looks to be offline and is no longer responding to pings. """ if status[server] == True: print(f"{server} is online") status[server] = True else: print(f"{server} is offline") notify(offline_message) with open(file, "w") as f: json.dump(status, f, indent=4)