diff --git a/ping.py b/ping.py new file mode 100644 index 0000000..fff66cf --- /dev/null +++ b/ping.py @@ -0,0 +1,152 @@ +#!/bin/python3 + +#importing the required modules + +import json +import subprocess + + +#file which will hold the online/offline status of servers + +file = "status.json" + + +#dictionary containing current server hostnames/ips + +servers = { + "link": "1.2.3.4", + "ganon": "5.6.7.8", + "zelda": "9.10.1.12", +} + + + + +#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)