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['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, hrn):
138 slicename = hrn_to_pl_slicename(hrn)
139 slice = get_slice(api, slicename)
142 topo.nodeTopoFromSliceTags(slice)
144 # call the default sfa.plc.nodes.get_rspec() method
145 return Nodes(api).get_rspec(hrn)
147 return topo.toxml(hrn)
152 Hook called via 'sfi.py create'
154 def create_slice(api, hrn, xml):
155 ### Check the whitelist
156 ### It consists of lines of the form: <slice hrn> <bw>
158 f = open(SFA_VINI_WHITELIST)
159 for line in f.readlines():
160 (slice, maxbw) = line.split()
161 whitelist[slice] = maxbw
164 maxbw = whitelist[hrn]
166 raise PermissionError("%s not in VINI whitelist" % hrn)
171 topo.nodeTopoFromRSpec(rspec)
173 # Check request against current allocations
174 topo.verifyNodeTopo(hrn, topo, maxbw)
176 nodes = topo.nodesInTopo()
179 hostnames.append(node.hostname)
180 create_slice_vini_aggregate(api, hrn, hostnames)
182 slicename = hrn_to_pl_slicename(hrn)
183 slice = get_slice(api, slicename)
185 topo.updateSliceTags(slice)
190 Returns the request context required by sfatables. At some point, this mechanism should be changed
191 to refer to "contexts", which is the information that sfatables is requesting. But for now, we just
192 return the basic information needed in a dict.
194 def fetch_context(slice_hrn, user_hrn, contexts):
195 base_context = {'sfa':{'user':{'hrn':user_hrn},
196 'slice':{'hrn':slice_hrn}}}
201 r.parseFile(sys.argv[1])
203 create_slice(None,'plc',rspec)
205 if __name__ == "__main__":