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 from PLC.Nodes import Node, Nodes
8 from PLC.NodeNetworks import NodeNetwork, NodeNetworks
9 from PLC.NodeGroups import NodeGroup, NodeGroups
10 from PLC.ConfFiles import ConfFile, ConfFiles
11 from PLC.Slices import Slice, Slices
12 from PLC.Persons import Person, Persons
13 from PLC.Keys import Key, Keys
14 from PLC.SliceAttributes import SliceAttribute, SliceAttributes
16 class GetSlivers(Method):
18 Returns an array of structs representing slivers (slices bound to
19 nodes). If node_id_or_hostname_list is specified, only slivers
20 bound to the specified nodes are queried.
22 All of the information returned by this call can be gathered from
23 other calls, e.g. GetNodes, GetNodeNetworks, GetSlices, etc. This
24 function exists primarily for the benefit of Node Manager and
28 roles = ['admin', 'node']
32 [Mixed(Node.fields['node_id'],
33 Node.fields['hostname'])]
37 'timestamp': Parameter(int, "Timestamp of this call, in seconds since UNIX epoch"),
38 'node_id': Node.fields['node_id'],
39 'hostname': Node.fields['hostname'],
40 'boot_state': Node.fields['boot_state'],
41 'networks': [NodeNetwork.fields],
42 'groups': [NodeGroup.fields['name']],
43 'conf_files': [ConfFile.fields],
45 'name': Slice.fields['name'],
46 'slice_id': Slice.fields['slice_id'],
47 'instantiation': Slice.fields['instantiation'],
48 'expires': Slice.fields['expires'],
50 'key_type': Key.fields['key_type'],
51 'key': Key.fields['key']
54 'name': SliceAttribute.fields['name'],
55 'value': SliceAttribute.fields['value']
60 def call(self, auth, node_id_or_hostname_list = None):
61 timestamp = int(time.time())
63 all_nodes = Nodes(self.api, node_id_or_hostname_list)
65 nodenetwork_ids = set()
69 for node_id, node in all_nodes.iteritems():
70 nodenetwork_ids.update(node['nodenetwork_ids'])
71 nodegroup_ids.update(node['nodegroup_ids'])
72 conf_file_ids.update(node['conf_file_ids'])
73 slice_ids.update(node['slice_ids'])
75 # Get nodenetwork information
77 all_nodenetworks = NodeNetworks(self.api, nodenetwork_ids)
81 # Get node group information
83 all_nodegroups = NodeGroups(self.api, nodegroup_ids)
85 for nodegroup_id, nodegroup in all_nodegroups.iteritems():
86 conf_file_ids.update(nodegroup['conf_file_ids'])
90 # Get configuration files
92 all_conf_files = ConfFiles(self.api, conf_file_ids)
98 all_slices = Slices(self.api, slice_ids)
101 slice_attribute_ids = set()
102 for slice_id, slice in all_slices.iteritems():
103 person_ids.update(slice['person_ids'])
104 slice_attribute_ids.update(slice['slice_attribute_ids'])
107 all_persons = Persons(self.api, person_ids)
110 for person_id, person in all_persons.iteritems():
111 key_ids.update(person['key_ids'])
113 # Get user account keys
114 all_keys = Keys(self.api, key_ids)
116 # Get slice attributes
117 all_slice_attributes = SliceAttributes(self.api, slice_attribute_ids)
120 for node_id, node in all_nodes.iteritems():
121 networks = [all_nodenetworks[nodenetwork_id] for nodenetwork_id in node['nodenetwork_ids']]
122 nodegroups = [all_nodegroups[nodegroup_id] for nodegroup_id in node['nodegroup_ids']]
123 groups = [nodegroup['name'] for nodegroup in nodegroups]
125 # If a node belongs to multiple node
126 # groups for which the same configuration file is defined,
127 # it is undefined which one takes precedence.
129 for nodegroup in nodegroups:
130 for conf_file in map(lambda id: all_conf_files[id], nodegroup['conf_file_ids']):
131 conf_files[conf_file['dest']] = conf_file
133 # Node configuration files always take precedence over
134 # node group configuration files.
135 for conf_file in map(lambda id: all_conf_files[id], node['conf_file_ids']):
136 conf_files[conf_file['dest']] = conf_file
139 for slice in map(lambda id: all_slices[id], node['slice_ids']):
141 for person in map(lambda id: all_persons[id], slice['person_ids']):
142 keys += [{'key_type': all_keys[key_id]['key_type'],
143 'key': all_keys[key_id]['key']} \
144 for key_id in person['key_ids']]
147 for slice_attribute in map(lambda id: all_slice_attributes[id],
148 slice['slice_attribute_ids']):
149 # Per-node sliver attributes (slice attributes
150 # with non-null node_id fields) take precedence
151 # over global slice attributes.
152 if not attributes.has_key(slice_attribute['name']) or \
153 slice_attribute['node_id'] is not None:
154 attributes[slice_attribute['name']] = {
155 'name': slice_attribute['name'],
156 'value': slice_attribute['value']
160 'name': slice['name'],
161 'slice_id': slice['slice_id'],
162 'instantiation': slice['instantiation'],
163 'expires': slice['expires'],
165 'attributes': attributes.values()
169 'timestamp': timestamp,
170 'node_id': node['node_id'],
171 'hostname': node['hostname'],
172 'networks': networks,
174 'conf_files': conf_files.values(),