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