1"""
2Network tools to run from the Master
3"""
4
5
6import logging
7import socket
8
9import salt.utils.files
10import salt.utils.network
11import salt.utils.stringutils
12
13log = logging.getLogger(__name__)
14
15
16def wollist(maclist, bcast="255.255.255.255", destport=9):
17    """
18    Send a "Magic Packet" to wake up a list of Minions.
19    This list must contain one MAC hardware address per line
20
21    CLI Example:
22
23    .. code-block:: bash
24
25        salt-run network.wollist '/path/to/maclist'
26        salt-run network.wollist '/path/to/maclist' 255.255.255.255 7
27        salt-run network.wollist '/path/to/maclist' 255.255.255.255 7
28    """
29    ret = []
30    try:
31        with salt.utils.files.fopen(maclist, "r") as ifile:
32            for mac in ifile:
33                mac = salt.utils.stringutils.to_unicode(mac).strip()
34                wol(mac, bcast, destport)
35                print("Waking up {}".format(mac))
36                ret.append(mac)
37    except Exception as err:  # pylint: disable=broad-except
38        __jid_event__.fire_event(
39            {"error": "Failed to open the MAC file. Error: {}".format(err)}, "progress"
40        )
41        return []
42    return ret
43
44
45def wol(mac, bcast="255.255.255.255", destport=9):
46    """
47    Send a "Magic Packet" to wake up a Minion
48
49    CLI Example:
50
51    .. code-block:: bash
52
53        salt-run network.wol 08-00-27-13-69-77
54        salt-run network.wol 080027136977 255.255.255.255 7
55        salt-run network.wol 08:00:27:13:69:77 255.255.255.255 7
56    """
57    dest = salt.utils.network.mac_str_to_bytes(mac)
58    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
59    sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
60    sock.sendto(b"\xff" * 6 + dest * 16, (bcast, int(destport)))
61    return True
62
63
64def wolmatch(tgt, tgt_type="glob", bcast="255.255.255.255", destport=9):
65    """
66    Send a "Magic Packet" to wake up Minions that are matched in the grains cache
67
68    CLI Example:
69
70    .. code-block:: bash
71
72        salt-run network.wolmatch minion_id
73        salt-run network.wolmatch 192.168.0.0/16 tgt_type='ipcidr' bcast=255.255.255.255 destport=7
74    """
75    ret = []
76    minions = __salt__["cache.grains"](tgt, tgt_type)
77    for minion in minions:
78        for iface, mac in minions[minion]["hwaddr_interfaces"].items():
79            if iface == "lo":
80                continue
81            mac = mac.strip()
82            wol(mac, bcast, destport)
83            log.info("Waking up %s", mac)
84            ret.append(mac)
85    return ret
86