1 from sfa.util.faults import *
2 from sfa.util.namespace import *
3 from sfa.util.rspec import RSpec
4 from sfa.server.registry import Registries
5 from sfa.plc.nodes import *
6 from sfa.rspecs.aggregates.vini.utils import *
7 from sfa.rspecs.aggregates.vini.rspec import *
10 SFA_VINI_WHITELIST = '/etc/sfa/vini.whitelist'
13 Copied from create_slice_aggregate() in sfa.plc.slices
15 def create_slice_vini_aggregate(api, hrn, nodes):
16 # Get the slice record
18 registries = Registries(api)
19 registry = registries[api.hrn]
20 credential = api.getCredential()
21 records = registry.resolve(credential, hrn)
22 for record in records:
23 if record['type'] in ['slice']:
26 raise RecordNotFound(hrn)
28 # Make sure slice exists at plc, if it doesnt add it
29 slicename = hrn_to_pl_slicename(hrn)
30 slices = api.plshell.GetSlices(api.plauth, [slicename], ['node_ids'])
32 parts = slicename.split("_")
34 # if site doesnt exist add it
35 sites = api.plshell.GetSites(api.plauth, [login_base])
37 authority = get_authority(hrn)
38 site_records = registry.resolve(credential, authority)
41 raise RecordNotFound(authority)
42 site = site_records[0]
46 site_id = api.plshell.AddSite(api.plauth, site)
51 slice_keys = ['name', 'url', 'description']
52 for key in slice_keys:
53 if key in slice and slice[key]:
54 slice_fields[key] = slice[key]
55 api.plshell.AddSlice(api.plauth, slice_fields)
61 # get the list of valid slice users from the registry and make
62 # they are added to the slice
63 researchers = record.get('researcher', [])
64 for researcher in researchers:
66 person_records = registry.resolve(credential, researcher)
67 for record in person_records:
68 if record['type'] in ['user']:
69 person_record = record
72 person_dict = person_record
73 persons = api.plshell.GetPersons(api.plauth, [person_dict['email']],
74 ['person_id', 'key_ids'])
76 # Create the person record
78 person_id=api.plshell.AddPerson(api.plauth, person_dict)
80 # The line below enables the user account on the remote aggregate
81 # soon after it is created.
82 # without this the user key is not transfered to the slice
83 # (as GetSlivers returns key of only enabled users),
84 # which prevents the user from login to the slice.
85 # We may do additional checks before enabling the user.
87 api.plshell.UpdatePerson(api.plauth, person_id, {'enabled' : True})
90 key_ids = persons[0]['key_ids']
92 api.plshell.AddPersonToSlice(api.plauth, person_dict['email'],
95 # Get this users local keys
96 keylist = api.plshell.GetKeys(api.plauth, key_ids, ['key'])
97 keys = [key['key'] for key in keylist]
99 # add keys that arent already there
100 for personkey in person_dict['keys']:
101 if personkey not in keys:
102 key = {'key_type': 'ssh', 'key': personkey}
103 api.plshell.AddPersonKey(api.plauth, person_dict['email'], key)
105 # find out where this slice is currently running
106 nodelist = api.plshell.GetNodes(api.plauth, slice['node_ids'],
108 hostnames = [node['hostname'] for node in nodelist]
110 # remove nodes not in rspec
111 deleted_nodes = list(set(hostnames).difference(nodes))
112 # add nodes from rspec
113 added_nodes = list(set(nodes).difference(hostnames))
116 print >> sys.stderr, "Slice on nodes:"
118 print >> sys.stderr, n
119 print >> sys.stderr, "Wants nodes:"
121 print >> sys.stderr, n
122 print >> sys.stderr, "Deleting nodes:"
123 for n in deleted_nodes:
124 print >> sys.stderr, n
125 print >> sys.stderr, "Adding nodes:"
126 for n in added_nodes:
127 print >> sys.stderr, n
130 api.plshell.AddSliceToNodes(api.plauth, slicename, added_nodes)
131 api.plshell.DeleteSliceFromNodes(api.plauth, slicename, deleted_nodes)
135 def get_rspec(api, xrn):
136 hrn = urn_to_hrn(xrn)[0]
139 slicename = hrn_to_pl_slicename(hrn)
140 slice = get_slice(api, slicename)
143 topo.nodeTopoFromSliceTags(slice)
145 # call the default sfa.plc.nodes.get_rspec() method
146 return Nodes(api).get_rspec(hrn)
148 return topo.toxml(hrn)
153 Hook called via 'sfi.py create'
155 def create_slice(api, xrn, xml):
156 hrn = urn_to_hrn(xrn)[0]
157 ### Check the whitelist
158 ### It consists of lines of the form: <slice hrn> <bw>
160 f = open(SFA_VINI_WHITELIST)
161 for line in f.readlines():
162 (slice, maxbw) = line.split()
163 whitelist[slice] = maxbw
166 maxbw = whitelist[hrn]
168 raise PermissionError("%s not in VINI whitelist" % hrn)
173 topo.nodeTopoFromRSpec(rspec)
175 # Check request against current allocations
176 topo.verifyNodeTopo(hrn, topo, maxbw)
178 nodes = topo.nodesInTopo()
181 hostnames.append(node.hostname)
182 create_slice_vini_aggregate(api, hrn, hostnames)
184 slicename = hrn_to_pl_slicename(hrn)
185 slice = get_slice(api, slicename)
187 topo.updateSliceTags(slice)
192 Returns the request context required by sfatables. At some point, this mechanism should be changed
193 to refer to "contexts", which is the information that sfatables is requesting. But for now, we just
194 return the basic information needed in a dict.
196 def fetch_context(slice_hrn, user_hrn, contexts):
197 base_context = {'sfa':{'user':{'hrn':user_hrn},
198 'slice':{'hrn':slice_hrn}}}
203 r.parseFile(sys.argv[1])
205 create_slice(None,'plc',rspec)
207 if __name__ == "__main__":