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 *
9 SFA_VINI_DEFAULT_RSPEC = '/etc/sfa/vini.rspec'
12 Copied from create_slice_aggregate() in sfa.plc.slices
14 def create_slice_vini_aggregate(api, hrn, nodes):
15 # Get the slice record from geni
17 registries = Registries(api)
18 registry = registries[api.hrn]
19 credential = api.getCredential()
20 records = registry.resolve(credential, hrn)
21 for record in records:
22 if record.get_type() in ['slice']:
23 slice = record.as_dict()
25 raise RecordNotFound(hrn)
27 # Make sure slice exists at plc, if it doesnt add it
28 slicename = hrn_to_pl_slicename(hrn)
29 slices = api.plshell.GetSlices(api.plauth, [slicename], ['node_ids'])
31 parts = slicename.split("_")
33 # if site doesnt exist add it
34 sites = api.plshell.GetSites(api.plauth, [login_base])
36 authority = get_authority(hrn)
37 site_records = registry.resolve(credential, authority)
40 raise RecordNotFound(authority)
41 site_record = site_records[0]
42 site = site_record.as_dict()
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.get_type() in ['user']:
69 person_record = record
72 person_dict = person_record.as_dict()
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))
115 api.plshell.AddSliceToNodes(api.plauth, slicename, added_nodes)
116 api.plshell.DeleteSliceFromNodes(api.plauth, slicename, deleted_nodes)
120 def get_rspec(api, hrn):
124 # XX rspec is expected to be xml, not None.
125 # call the default sfa.plc.nodes.get_rspec() methods
126 # until things are complete here
128 rspec = nodes.get_rspec(hrn)
130 # Convert HRN to slice name
131 # Get SliceTags for the slice
133 # Construct LinkSpecs from the topo_rspec SliceTags
134 # The first field is the NodeId of the remote node.
135 # So the endpoints are the SliceTag node and the remote node.
138 # - avoid duplicates?
139 # - verify both ends of the link?
142 # Return canned response for now...
144 r.parseFile(SFA_VINI_DEFAULT_RSPEC)
150 def create_slice(api, hrn, xml):
153 rspec = r.toGenDict()
155 # Check request against current allocations
158 nodes = rspec_to_nodeset(rspec)
159 create_slice_vini_aggregate(api, hrn, nodes)
161 # Add VINI-specific topology attributes to slice here
165 def rspec_to_nodeset(rspec):
169 sitespecs = rspec['Rspec'][0]['Capacity'][0]['NetSpec'][0]['SiteSpec']
171 for node in s['NodeSpec']:
172 nodedict[node['name'][0]] = node['hostname'][0]
174 linkspecs = rspec['Rspec'][0]['Request'][0]['NetSpec'][0]['LinkSpec']
176 for e in l['endpoint']:
177 nodes.add(nodedict[e])
187 r.parseFile(sys.argv[1])
188 rspec = r.toGenDict()
189 create_slice(None,'plc',rspec)
191 if __name__ == "__main__":