blind 2to3
[plcapi.git] / PLC / Methods / RebootNode.py
1 import socket
2
3 from PLC.Faults import *
4 from PLC.Method import Method
5 from PLC.Parameter import Parameter, Mixed
6 from PLC.Nodes import Node, Nodes
7 from PLC.Interfaces import Interface, Interfaces
8 from PLC.Auth import Auth
9 from PLC.POD import udp_pod
10
11 class RebootNode(Method):
12     """
13     Sends the specified node a specially formatted UDP packet which
14     should cause it to reboot immediately.
15
16     Admins can reboot any node. Techs and PIs can only reboot nodes at
17     their site.
18
19     Returns 1 if the packet was successfully sent (which only whether
20     the packet was sent, not whether the reboot was successful).
21     """
22
23     roles = ['admin', 'pi', 'tech']
24
25     accepts = [
26         Auth(),
27         Mixed(Node.fields['node_id'],
28               Node.fields['hostname'])
29         ]
30
31     returns = Parameter(int, '1 if successful')
32
33     def call(self, auth, node_id_or_hostname):
34         # Get account information
35         nodes = Nodes(self.api, [node_id_or_hostname])
36         if not nodes:
37             raise PLCInvalidArgument("No such node")
38
39         node = nodes[0]
40
41         # Authenticated function
42         assert self.caller is not None
43
44         # If we are not an admin, make sure that the caller is a
45         # member of the site at which the node is located.
46         if 'admin' not in self.caller['roles']:
47             if node['site_id'] not in self.caller['site_ids']:
48                 raise PLCPermissionDenied("Not allowed to delete nodes from specified site")
49
50         session = node['session']
51         if not session:
52             raise PLCInvalidArgument("No session key on record for that node (i.e., has never successfully booted)")
53         session = session.strip()
54
55         # Only use the hostname as a backup, try to use the primary ID
56         # address instead.
57         host = node['hostname']
58         interfaces = Interfaces(self.api, node['interface_ids'])
59         for interface in interfaces:
60             if interface['is_primary'] == 1:
61                 host = interface['ip']
62                 break
63
64         try:
65             udp_pod(host, session)
66         except socket.error as e:
67             # Ignore socket errors
68             pass
69
70         self.event_objects = {'Node': [node['node_id']]}
71         self.message = "RebootNode called"
72
73         return 1