1 from sfa.util.faults import *
2 from sfa.util.misc 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 from geni
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.get_type() in ['slice']:
24 slice = record.as_dict()
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_record = site_records[0]
43 site = site_record.as_dict()
47 site_id = api.plshell.AddSite(api.plauth, site)
52 slice_keys = ['name', 'url', 'description']
53 for key in slice_keys:
54 if key in slice and slice[key]:
55 slice_fields[key] = slice[key]
56 api.plshell.AddSlice(api.plauth, slice_fields)
62 # get the list of valid slice users from the registry and make
63 # they are added to the slice
64 researchers = record.get('researcher', [])
65 for researcher in researchers:
67 person_records = registry.resolve(credential, researcher)
68 for record in person_records:
69 if record.get_type() in ['user']:
70 person_record = record
73 person_dict = person_record.as_dict()
74 persons = api.plshell.GetPersons(api.plauth, [person_dict['email']],
75 ['person_id', 'key_ids'])
77 # Create the person record
79 person_id=api.plshell.AddPerson(api.plauth, person_dict)
81 # The line below enables the user account on the remote aggregate
82 # soon after it is created.
83 # without this the user key is not transfered to the slice
84 # (as GetSlivers returns key of only enabled users),
85 # which prevents the user from login to the slice.
86 # We may do additional checks before enabling the user.
88 api.plshell.UpdatePerson(api.plauth, person_id, {'enabled' : True})
91 key_ids = persons[0]['key_ids']
93 api.plshell.AddPersonToSlice(api.plauth, person_dict['email'],
96 # Get this users local keys
97 keylist = api.plshell.GetKeys(api.plauth, key_ids, ['key'])
98 keys = [key['key'] for key in keylist]
100 # add keys that arent already there
101 for personkey in person_dict['keys']:
102 if personkey not in keys:
103 key = {'key_type': 'ssh', 'key': personkey}
104 api.plshell.AddPersonKey(api.plauth, person_dict['email'], key)
106 # find out where this slice is currently running
107 nodelist = api.plshell.GetNodes(api.plauth, slice['node_ids'],
109 hostnames = [node['hostname'] for node in nodelist]
111 # remove nodes not in rspec
112 deleted_nodes = list(set(hostnames).difference(nodes))
113 # add nodes from rspec
114 added_nodes = list(set(nodes).difference(hostnames))
117 print >> sys.stderr, "Slice on nodes:"
119 print >> sys.stderr, n
120 print >> sys.stderr, "Wants nodes:"
122 print >> sys.stderr, n
123 print >> sys.stderr, "Deleting nodes:"
124 for n in deleted_nodes:
125 print >> sys.stderr, n
126 print >> sys.stderr, "Adding nodes:"
127 for n in added_nodes:
128 print >> sys.stderr, n
131 api.plshell.AddSliceToNodes(api.plauth, slicename, added_nodes)
132 api.plshell.DeleteSliceFromNodes(api.plauth, slicename, deleted_nodes)
136 def get_rspec(api, hrn):
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, hrn, xml):
156 ### Check the whitelist
157 ### It consists of lines of the form: <slice hrn> <bw>
159 f = open(SFA_VINI_WHITELIST)
160 for line in f.readlines():
161 (slice, maxbw) = line.split()
162 whitelist[slice] = maxbw
165 maxbw = whitelist[hrn]
167 raise PermissionError("%s not in VINI whitelist" % hrn)
172 topo.nodeTopoFromRspec(rspec)
174 # Check request against current allocations
175 topo.verifyNodeTopo(hrn, topo, maxbw)
177 nodes = topo.nodesInTopo()
180 hostnames.append(node.hostname)
181 create_slice_vini_aggregate(api, hrn, hostnames)
183 slicename = hrn_to_pl_slicename(hrn)
184 slice = get_slice(api, slicename)
186 topo.updateSliceTags(slice)
193 r.parseFile(sys.argv[1])
195 create_slice(None,'plc',rspec)
197 def fetch_context(slice_hrn, user_hrn, contexts):
200 if __name__ == "__main__":