# -*- coding: utf-8 -*- ''' Network tools to run from the Master, specific to the Claremont MakerSpace ''' import logging import socket import netifaces import time import salt.utils.network log = logging.getLogger(__name__) def wol(mac, bcast="255.255.255.255", destport=9): "Like network.wol, but sends on each interface" dest = salt.utils.network.mac_str_to_bytes(mac) for iface in netifaces.interfaces(): if iface == 'lo': continue with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock: sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) sock.setsockopt(socket.SOL_SOCKET, socket.SO_BINDTODEVICE, iface.encode('ascii')) sock.sendto(b"\xff" * 6 + dest * 16, (bcast, int(destport))) return True def wolmatch(tgt, destport=9): 'Like network.wolmatch' ret = [] minions = __salt__['cache.grains'](tgt, 'compound') for name, minion in minions.items(): if 'hwaddr_interfaces' not in minion: continue # NOTE: FIVE, NINE, and TEN all should have eth addr as well, why is there only one printed? for iface, mac in minion['hwaddr_interfaces'].items(): mac = mac.strip() if iface == 'lo' or len(mac) != len("00:00:00:00:00:00"): continue #print(name, iface, mac, minion['ip_interfaces']) wol(mac, destport=destport) log.info('Waking up %s', mac) ret.append(f"{name}: {mac}") return ret def wolmatch_ensure(tgt, destport=9): 'Ensure matched minions are online, and stay online' while True: log.info('Waking up minions') wolmatch(tgt, destport) time.sleep(5)