federation in progress - associate a local slice to a foreign node
[plcapi.git] / PLC / Methods / AddSliceToNodes.py
1 from PLC.Faults import *
2 from PLC.Method import Method
3 from PLC.Parameter import Parameter, Mixed
4 from PLC.Nodes import Node, Nodes
5 from PLC.ForeignNodes import ForeignNode, ForeignNodes
6 from PLC.Slices import Slice, Slices
7 from PLC.Auth import Auth
8
9 class AddSliceToNodes(Method):
10     """
11     Adds the specified slice to the specified nodes.
12     Nodes can be either regular (local) nodes as returned by GetNodes
13     or foreign nodes as returned by GetForeignNodes
14
15     If the slice is
16     already associated with a node, no errors are returned. 
17
18     Returns 1 if successful, faults otherwise.
19     """
20
21     roles = ['admin', 'pi', 'user']
22
23     accepts = [
24         Auth(),
25         Mixed(Slice.fields['slice_id'],
26               Slice.fields['name']),
27         [Mixed(Node.fields['node_id'],
28                Node.fields['hostname'])]
29         ]
30
31     returns = Parameter(int, '1 if successful')
32
33     event_type = 'AddTo'
34     object_type = 'Node'
35     object_ids = []
36
37     def call(self, auth, slice_id_or_name, node_id_or_hostname_list):
38         # Get slice information
39         slices = Slices(self.api, [slice_id_or_name])
40         if not slices:
41             raise PLCInvalidArgument, "No such slice"
42
43         slice = slices.values()[0]
44
45         if 'admin' not in self.caller['roles']:
46             if self.caller['person_id'] in slice['person_ids']:
47                 pass
48             # Thierry : I cannot figure out how this works
49             # how is having pi role related to being in a slice ?
50             elif 'pi' not in self.caller['roles']:
51                 raise PLCPermissionDenied, "Not a member of the specified slice"
52             elif slice['site_id'] not in self.caller['site_ids']:
53                 raise PLCPermissionDenied, "Specified slice not associated with any of your sites"
54         
55          # Get specified nodes, and them to the slice
56         nodes = Nodes(self.api, node_id_or_hostname_list).values()
57         for node in nodes:
58             if slice['slice_id'] not in node['slice_ids']:
59                 slice.add_node(node, commit = False)
60
61         # the same for foreign_nodes
62         foreign_nodes = ForeignNodes (self.api, node_id_or_hostname_list).values()
63         for foreign_node in foreign_nodes:
64             if slice['slice_id'] not in foreign_node['slice_ids']:
65                 slice.add_node (foreign_node, is_foreign_node=True, commit=False)
66
67         slice.sync()
68
69         self.object_ids = [node['node_id'] for node in nodes]
70
71         return 1