#!/usr/bin/python import subprocess import json import socket import datetime def get_wan_interfaces(): wan_interfaces = [] errors = [] for table_id in range(100, 107): try: command = "ip route show table {0}".format(table_id) output = subprocess.check_output(command, shell=True).decode('utf-8') for line in output.splitlines(): if line.startswith('default via'): parts = line.split() if 'dev' in parts: idx = parts.index('dev') + 1 interface = parts[idx] wan_interfaces.append(interface) except subprocess.CalledProcessError as e: errors.append("Error checking table {0}: {1}".format(table_id, e)) return set(wan_interfaces), errors def get_interface_ips(): interface_ips = {} errors = [] try: output = subprocess.check_output("ip -o addr show", shell=True).decode('utf-8') for line in output.splitlines(): if 'inet ' in line: parts = line.split() interface = parts[1] ip_address = parts[3].split('/')[0] if interface not in interface_ips and ip_address != "10.207.35.254": interface_ips[interface] = [] if ip_address != "10.207.35.254": interface_ips[interface].append(ip_address) except subprocess.CalledProcessError as e: errors.append("Error listing interface IPs: {0}".format(e)) return interface_ips, errors def get_lan_interfaces(exclude_interfaces): lan_interfaces = [] errors = [] interface_ips, errors_ips = get_interface_ips() errors.extend(errors_ips) for interface, ips in interface_ips.items(): if (interface.startswith('eth') or 'vlan' in interface) and interface not in exclude_interfaces: lan_interfaces.extend([(interface, ip) for ip in ips]) return lan_interfaces, errors def check_outbound_connectivity(interface_ip_pairs): failed_checks = [] errors = [] for interface, ip in interface_ip_pairs: try: command = "curl -s --interface {0} -m 5 https://downloads.cytracom.net/windows/version.json".format(ip) response = subprocess.check_output(command, shell=True).decode('utf-8') json.loads(response) except (subprocess.CalledProcessError, ValueError) as e: failed_checks.append((interface, ip)) errors.append("Interface {0} with IP {1} failed outbound connectivity check due to {2}.".format(interface, ip, e)) return failed_checks, errors def main(): error_occurred = False hostname = socket.gethostname() wan_interfaces, wan_errors = get_wan_interfaces() lan_interface_ip_pairs, lan_errors = get_lan_interfaces(wan_interfaces) failed_checks, connectivity_errors = check_outbound_connectivity(lan_interface_ip_pairs) errors = wan_errors + lan_errors + connectivity_errors if errors or failed_checks: error_occurred = True message = "Errors occurred during execution. See details." else: message = "All LAN interfaces passed the outbound connectivity check." level = "info" if error_occurred: level = "error" result = { "bonder_hostname": hostname, "level": level, "message": message, "details": errors, } print(json.dumps(result)) if __name__ == "__main__": main()