prettified
[plcapi.git] / PLC / Methods / RebootNodeWithPCU.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.Auth import Auth
7
8 from PLC.Nodes import Node, Nodes
9 from PLC.PCUs import PCU, PCUs
10
11 try:
12     from pcucontrol import reboot
13     external_dependency = True
14 except:
15     external_dependency = False
16
17 class RebootNodeWithPCU(Method):
18     """
19         Uses the associated PCU to attempt to reboot the given Node.
20
21     Admins can reboot any node. Techs and PIs can only reboot nodes at
22     their site.
23
24     Returns 1 if the reboot proceeded without error (Note: this does not guarantee
25         that the reboot is successful).
26         Returns -1 if external dependencies for this call are not available.
27         Returns "error string" if the reboot failed with a specific message.
28     """
29
30     roles = ['admin', 'pi', 'tech']
31
32     accepts = [
33         Auth(),
34         Mixed(Node.fields['node_id'],
35               Node.fields['hostname']),
36         Parameter(bool, "Run as a test, or as a real reboot", nullok = True)
37         ]
38
39     returns = Parameter(int, '1 if successful')
40
41     def call(self, auth, node_id_or_hostname, testrun=None):
42     # Get account information
43         nodes = Nodes(self.api, [node_id_or_hostname])
44         if not nodes:
45             raise PLCInvalidArgument, "No such node"
46
47         if testrun is None:
48             testrun = False
49
50         node = nodes[0]
51
52         # Authenticated function
53         assert self.caller is not None
54
55         # If we are not an admin, make sure that the caller is a
56         # member of the site at which the node is located.
57         if 'admin' not in self.caller['roles']:
58             if node['site_id'] not in self.caller['site_ids']:
59                 raise PLCPermissionDenied, "Not allowed to reboot nodes from specified site"
60
61         # Verify that the node has pcus associated with it.
62         pcus = PCUs(self.api, {'pcu_id' : node['pcu_ids']} )
63         if not pcus:
64             raise PLCInvalidArgument, "No PCUs associated with Node"
65
66         pcu = pcus[0]
67
68         if not external_dependency:
69             raise PLCNotImplemented, "Could not load external module to attempt reboot"
70
71         # model, hostname, port,
72         # i = pcu['node_ids'].index(node['node_id'])
73         # p = pcu['ports'][i]
74         ret = reboot.reboot_api(node, pcu, testrun)
75
76         node.update_last_pcu_reboot(commit=True) # commits new timestamp to node 
77
78         self.event_objects = {'Node': [node['node_id']]}
79         self.message = "RebootNodeWithPCU %s with %s returned %s" % (node['node_id'], pcu['pcu_id'], ret)
80
81         return ret