Changed Rspec --> RSpec throughout.
[sfa.git] / sfa / rspecs / aggregates / rspec_manager_vini.py
index 27fde8f..2875a40 100644 (file)
@@ -1,11 +1,13 @@
 from sfa.util.faults import *
 from sfa.util.misc import *
-from sfa.util.rspec import Rspec
+from sfa.util.rspec import RSpec
 from sfa.server.registry import Registries
+from sfa.plc.nodes import *
+from sfa.rspecs.aggregates.vini.utils import *
+from sfa.rspecs.aggregates.vini.rspec import *
 import sys
-import pdb
 
-SFA_VINI_DEFAULT_RSPEC = '/etc/sfa/vini.rspec'
+SFA_VINI_WHITELIST = '/etc/sfa/vini.whitelist'
 
 """
 Copied from create_slice_aggregate() in sfa.plc.slices
@@ -111,75 +113,94 @@ def create_slice_vini_aggregate(api, hrn, nodes):
     # add nodes from rspec
     added_nodes = list(set(nodes).difference(hostnames))
 
+    """
+    print >> sys.stderr, "Slice on nodes:"
+    for n in hostnames:
+        print >> sys.stderr, n
+    print >> sys.stderr, "Wants nodes:"
+    for n in nodes:
+        print >> sys.stderr, n
+    print >> sys.stderr, "Deleting nodes:"
+    for n in deleted_nodes:
+        print >> sys.stderr, n
+    print >> sys.stderr, "Adding nodes:"
+    for n in added_nodes:
+        print >> sys.stderr, n
+    """
+
     api.plshell.AddSliceToNodes(api.plauth, slicename, added_nodes) 
     api.plshell.DeleteSliceFromNodes(api.plauth, slicename, deleted_nodes)
 
     return 1
 
 def get_rspec(api, hrn):
-    rspec = None
-    
+    topo = Topology(api)      
     if (hrn):
-        # Convert HRN to slice name
-        # Get SliceTags for the slice
-
-        # Construct LinkSpecs from the topo_rspec SliceTags
-        # The first field is the NodeId of the remote node.
-        # So the endpoints are the SliceTag node and the remote node.
+        slicename = hrn_to_pl_slicename(hrn)
+        slice = get_slice(api, slicename)
+        if slice:
+            slice.hrn = hrn
+            topo.nodeTopoFromSliceTags(slice)
+        else:
+            # call the default sfa.plc.nodes.get_rspec() method
+            return Nodes(api).get_rspec(hrn)     
 
-        # How to:
-        # - avoid duplicates?
-        # - verify both ends of the link?
-        pass
-    else:
-        # Return canned response for now...
-        r = Rspec()
-        r.parseFile(SFA_VINI_DEFAULT_RSPEC)
-        rspec = r.toxml()
+    return topo.toxml(hrn)
 
-    return rspec
 
 
+"""
+Hook called via 'sfi.py create'
+"""
 def create_slice(api, hrn, xml):
-    r = Rspec()
-    r.parseString(xml)
-    rspec = r.toGenDict()
+    ### Check the whitelist
+    ### It consists of lines of the form: <slice hrn> <bw>
+    whitelist = {}
+    f = open(SFA_VINI_WHITELIST)
+    for line in f.readlines():
+        (slice, maxbw) = line.split()
+        whitelist[slice] = maxbw
+        
+    if hrn in whitelist:
+        maxbw = whitelist[hrn]
+    else:
+        raise PermissionError("%s not in VINI whitelist" % hrn)
+        
+    rspec = RSpec(xml)
+    topo = Topology(api)
+    
+    topo.nodeTopoFromRSpec(rspec)
 
     # Check request against current allocations
-    # Request OK
-
-    nodes = rspec_to_nodeset(rspec)
-    create_slice_vini_aggregate(api, hrn, nodes)
+    topo.verifyNodeTopo(hrn, topo, maxbw)
+    
+    nodes = topo.nodesInTopo()
+    hostnames = []
+    for node in nodes:
+        hostnames.append(node.hostname)
+    create_slice_vini_aggregate(api, hrn, hostnames)
 
-    # Add VINI-specific topology attributes to slice here
+    slicename = hrn_to_pl_slicename(hrn)
+    slice = get_slice(api, slicename)
+    if slice:
+        topo.updateSliceTags(slice)    
 
     return True
 
-def rspec_to_nodeset(rspec):
-    nodedict = {}
-    nodes = set()
-    try:
-        sitespecs = rspec['Rspec'][0]['Capacity'][0]['NetSpec'][0]['SiteSpec']
-        for s in sitespecs:
-            for node in s['NodeSpec']:
-                nodedict[node['name'][0]] = node['hostname'][0]
-
-        linkspecs = rspec['Rspec'][0]['Request'][0]['NetSpec'][0]['LinkSpec']
-        for l in linkspecs:
-            for e in l['endpoint']:
-                nodes.add(nodedict[e])
-        
-    except KeyError:
-        # Bad Rspec
-        pass
-    
-    return nodes
+"""
+Returns the request context required by sfatables. At some point, this mechanism should be changed
+to refer to "contexts", which is the information that sfatables is requesting. But for now, we just
+return the basic information needed in a dict.
+"""
+def fetch_context(slice_hrn, user_hrn, contexts):
+    base_context = {'sfa':{'user':{'hrn':user_hrn}}}
+    return base_context
 
 def main():
-    r = Rspec()
+    r = RSpec()
     r.parseFile(sys.argv[1])
-    rspec = r.toGenDict()
+    rspec = r.toDict()
     create_slice(None,'plc',rspec)
-    
+
 if __name__ == "__main__":
     main()