+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<rspec id="max_rspec_slice1" xmlns="http://geni.maxgigapop.net/aggregate/rspec/20100412/" schemaLocation="http://geni.dragon.maxgigapop.net/max-rspec.xsd"
- xmlns:CtrlPlane="http://ogf.org/schema/network/topology/ctrlPlane/20080828/" CtrlPlane:schemaLocation="http://www.controlplane.net/idcp-v1.1/nmtopo-ctrlp.xsd">
- <aggregate>geni.maxgigapop.net</aggregate>
- <description>Example MAX RSpec</description>
- <lifetime id="time-1271533930-1271563981">
- <CtrlPlane:start type="CtrlPlane:TimeContent">1279848020</CtrlPlane:start>
- <CtrlPlane:end type="CtrlPlane:TimeContent">1280712039</CtrlPlane:end>
- </lifetime>
- <computeResource id="urn:aggregate=geni.maxgigapop.net:rspec=my-test-max-rspec-slice1">
- <planetlabNodeSliver id="urn:aggregate=geni.maxgigapop.net:rspec=my-test-max-rspec-slice1:domain=dragon.maxgigapop.net:node=planetlab3">
- <address>206.196.176.55</address>
- <computeCapacity>
- <cpuType>generic</cpuType>
- <cpuSpeed>2.0GHz</cpuSpeed>
- <numCpuCores>1</numCpuCores>
- <memorySize>256MB</memorySize>
- <diskSize>16GB</diskSize>
- </computeCapacity>
- <networkInterface id="urn:aggregate=geni.maxgigapop.net:rspec=my-test-max-rspec-slice1:domain=dragon.maxgigapop.net:node=planetlab3:interface=eth1.any_1">
- <deviceType>Ethernet</deviceType>
- <deviceName>eth1</deviceName>
- <capacity>100Mbps</capacity>
- <ipAddress>10.10.10.2/24</ipAddress>
- <vlanRange>any</vlanRange>
- <peerNetworkInterface>urn:aggregate=geni.maxgigapop.net:rspec=my-test-max-rspec-slice1:domain=dragon.maxgigapop.net:node=planetlab2:interface=eth1.any_1</peerNetworkInterface>
- </networkInterface>
- <networkInterface id="urn:aggregate=geni.maxgigapop.net:rspec=my-test-max-rspec-slice1:domain=dragon.maxgigapop.net:node=planetlab3:interface=eth1.any_2">
- <deviceType>Ethernet</deviceType>
- <deviceName>eth1</deviceName>
- <capacity>100Mbps</capacity>
- <ipAddress>10.10.30.1/24</ipAddress>
- <vlanRange>any</vlanRange>
- <peerNetworkInterface>urn:aggregate=geni.maxgigapop.net:rspec=my-test-max-rspec-slice1:domain=dragon.maxgigapop.net:node=planetlab5:interface=eth1.any_2</peerNetworkInterface>
- </networkInterface>
- </planetlabNodeSliver>
- <planetlabNodeSliver id="urn:aggregate=geni.maxgigapop.net:rspec=my-test-max-rspec-slice1:domain=dragon.maxgigapop.net:node=planetlab5">
- <address>206.196.176.138</address>
- <computeCapacity>
- <cpuType>generic</cpuType>
- <cpuSpeed>2.0GHz</cpuSpeed>
- <numCpuCores>1</numCpuCores>
- <memorySize>256MB</memorySize>
- <diskSize>16GB</diskSize>
- </computeCapacity>
- <networkInterface id="urn:aggregate=geni.maxgigapop.net:rspec=my-test-max-rspec-slice1:domain=dragon.maxgigapop.net:node=planetlab5:interface=eth1.any_3">
- <deviceType>Ethernet</deviceType>
- <deviceName>eth1</deviceName>
- <capacity>100Mbps</capacity>
- <ipAddress>10.10.20.2/24</ipAddress>
- <vlanRange>any</vlanRange>
- <peerNetworkInterface>urn:aggregate=geni.maxgigapop.net:rspec=my-test-max-rspec-slice1:domain=dragon.maxgigapop.net:node=planetlab2:interface=eth1.any_3</peerNetworkInterface>
- </networkInterface>
- <networkInterface id="urn:aggregate=geni.maxgigapop.net:rspec=my-test-max-rspec-slice1:domain=dragon.maxgigapop.net:node=planetlab5:interface=eth1.any_2">
- <deviceType>Ethernet</deviceType>
- <deviceName>eth1</deviceName>
- <capacity>100Mbps</capacity>
- <ipAddress>10.10.30.2/24</ipAddress>
- <vlanRange>any</vlanRange>
- <peerNetworkInterface>urn:aggregate=geni.maxgigapop.net:rspec=my-test-max-rspec-slice1:domain=dragon.maxgigapop.net:node=planetlab3:interface=eth1.any_2</peerNetworkInterface>
- </networkInterface>
- </planetlabNodeSliver>
- <planetlabNodeSliver id="urn:aggregate=geni.maxgigapop.net:rspec=my-test-max-rspec-slice1:domain=dragon.maxgigapop.net:node=planetlab2">
- <address>206.196.176.133</address>
- <computeCapacity>
- <cpuType>generic</cpuType>
- <cpuSpeed>2.0GHz</cpuSpeed>
- <numCpuCores>1</numCpuCores>
- <memorySize>256MB</memorySize>
- <diskSize>16GB</diskSize>
- </computeCapacity>
- <networkInterface id="urn:aggregate=geni.maxgigapop.net:rspec=my-test-max-rspec-slice1:domain=dragon.maxgigapop.net:node=planetlab2:interface=eth1.any_1">
- <deviceType>Ethernet</deviceType>
- <deviceName>eth1</deviceName>
- <capacity>100Mbps</capacity>
- <ipAddress>10.10.10.1/24</ipAddress>
- <vlanRange>any</vlanRange>
- <peerNetworkInterface>urn:aggregate=geni.maxgigapop.net:rspec=my-test-max-rspec-slice1:domain=dragon.maxgigapop.net:node=planetlab3:interface=eth1.any_1</peerNetworkInterface>
- </networkInterface>
- <networkInterface id="urn:aggregate=geni.maxgigapop.net:rspec=my-test-max-rspec-slice1:domain=dragon.maxgigapop.net:node=planetlab2:interface=eth1.any_3">
- <deviceType>Ethernet</deviceType>
- <deviceName>eth1</deviceName>
- <capacity>100Mbps</capacity>
- <ipAddress>10.10.20.1/24</ipAddress>
- <vlanRange>any</vlanRange>
- <peerNetworkInterface>urn:aggregate=geni.maxgigapop.net:rspec=my-test-max-rspec-slice1:domain=dragon.maxgigapop.net:node=planetlab5:interface=eth1.any_3</peerNetworkInterface>
- </networkInterface>
- </planetlabNodeSliver>
- </computeResource>
-</rspec>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>\r
-<tns:RSpec xmlns:tns="http://yuba.stanford.edu/egeni/rspec" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://yuba.stanford.edu/egeni/rspec stanford-rspec.xsd ">\r
- <tns:version>tns:version</tns:version>\r
- <tns:switchEntry>\r
- <tns:node>\r
- <tns:nodeId>tns:nodeId</tns:nodeId>\r
- <tns:type>0</tns:type>\r
- <tns:interfaceEntry>\r
- <tns:port>0</tns:port>\r
- <tns:remoteNodeId>tns:remoteNodeId</tns:remoteNodeId>\r
- <tns:remotePort>0</tns:remotePort>\r
- <tns:flowSpaceEntry>\r
- <tns:policy>readonly</tns:policy>\r
- <tns:dl_src>0F00</tns:dl_src>\r
- <tns:dl_dst>0F00</tns:dl_dst>\r
- <tns:dl_type>0</tns:dl_type>\r
- <tns:vlan_id>0</tns:vlan_id>\r
- <tns:ip_src>0F00</tns:ip_src>\r
- <tns:ip_dst>0F00</tns:ip_dst>\r
- <tns:ip_proto>0</tns:ip_proto>\r
- <tns:tp_src>0</tns:tp_src>\r
- <tns:tp_dst>0</tns:tp_dst>\r
- </tns:flowSpaceEntry>\r
- <tns:bandwidth>0.0</tns:bandwidth>\r
- <tns:latency>0.0</tns:latency>\r
- <tns:lossRate>0.0</tns:lossRate>\r
- </tns:interfaceEntry>\r
- </tns:node>\r
- <tns:switchFeatures>tns:switchFeatures</tns:switchFeatures>\r
- <tns:controllerUrl>tns:controllerUrl</tns:controllerUrl>\r
- </tns:switchEntry>\r
- <tns:hostEntry>\r
- <tns:node>\r
- <tns:nodeId>tns:nodeId</tns:nodeId>\r
- <tns:type>0</tns:type>\r
- <tns:interfaceEntry>\r
- <tns:port>0</tns:port>\r
- <tns:remoteNodeId>tns:remoteNodeId</tns:remoteNodeId>\r
- <tns:remotePort>0</tns:remotePort>\r
- <tns:flowSpaceEntry>\r
- <tns:policy>readonly</tns:policy>\r
- <tns:dl_src>0F00</tns:dl_src>\r
- <tns:dl_dst>0F00</tns:dl_dst>\r
- <tns:dl_type>0</tns:dl_type>\r
- <tns:vlan_id>0</tns:vlan_id>\r
- <tns:ip_src>0F00</tns:ip_src>\r
- <tns:ip_dst>0F00</tns:ip_dst>\r
- <tns:ip_proto>0</tns:ip_proto>\r
- <tns:tp_src>0</tns:tp_src>\r
- <tns:tp_dst>0</tns:tp_dst>\r
- </tns:flowSpaceEntry>\r
- <tns:bandwidth>0.0</tns:bandwidth>\r
- <tns:latency>0.0</tns:latency>\r
- <tns:lossRate>0.0</tns:lossRate>\r
- </tns:interfaceEntry>\r
- </tns:node>\r
- <tns:cpuUtil>0.0</tns:cpuUtil>\r
- <tns:memUtil>0.0</tns:memUtil>\r
- </tns:hostEntry>\r
- <tns:remoteNodeEntry>\r
- <tns:remoteURL>tns:remoteURL</tns:remoteURL>\r
- <tns:remoteType>tns:remoteType</tns:remoteType>\r
- <tns:node>\r
- <tns:nodeId>tns:nodeId</tns:nodeId>\r
- <tns:type>0</tns:type>\r
- <tns:interfaceEntry>\r
- <tns:port>0</tns:port>\r
- <tns:remoteNodeId>tns:remoteNodeId</tns:remoteNodeId>\r
- <tns:remotePort>0</tns:remotePort>\r
- <tns:flowSpaceEntry>\r
- <tns:policy>readonly</tns:policy>\r
- <tns:dl_src>0F00</tns:dl_src>\r
- <tns:dl_dst>0F00</tns:dl_dst>\r
- <tns:dl_type>0</tns:dl_type>\r
- <tns:vlan_id>0</tns:vlan_id>\r
- <tns:ip_src>0F00</tns:ip_src>\r
- <tns:ip_dst>0F00</tns:ip_dst>\r
- <tns:ip_proto>0</tns:ip_proto>\r
- <tns:tp_src>0</tns:tp_src>\r
- <tns:tp_dst>0</tns:tp_dst>\r
- </tns:flowSpaceEntry>\r
- <tns:bandwidth>0.0</tns:bandwidth>\r
- <tns:latency>0.0</tns:latency>\r
- <tns:lossRate>0.0</tns:lossRate>\r
- </tns:interfaceEntry>\r
- </tns:node>\r
- </tns:remoteNodeEntry>\r
- <tns:flowSpaceEntry>\r
- <tns:policy>readonly</tns:policy>\r
- <tns:dl_src>0F00</tns:dl_src>\r
- <tns:dl_dst>0F00</tns:dl_dst>\r
- <tns:dl_type>0</tns:dl_type>\r
- <tns:vlan_id>0</tns:vlan_id>\r
- <tns:ip_src>0F00</tns:ip_src>\r
- <tns:ip_dst>0F00</tns:ip_dst>\r
- <tns:ip_proto>0</tns:ip_proto>\r
- <tns:tp_src>0</tns:tp_src>\r
- <tns:tp_dst>0</tns:tp_dst>\r
- </tns:flowSpaceEntry>\r
-</tns:RSpec>\r
-\r
+++ /dev/null
-#!/usr/bin/python
-
-from sfa.util.rspec import RSpec
-import sys
-import pdb
-from sfa.util.xrn import get_authority
-from sfa.util.plxrn import hrn_to_pl_slicename
-from sfa.util.rspec import *
-from sfa.util.specdict import *
-from sfa.util.faults import *
-from sfa.util.storage import *
-from sfa.util.policy import Policy
-from sfa.server.aggregate import Aggregates
-from sfa.server.registry import Registries
-from sfa.util.faults import *
-
-import xml.dom.minidom
-
-SFA_MAX_CONF_FILE = '/etc/sfa/max_allocations'
-SFA_MAX_DEFAULT_RSPEC = '/etc/sfa/max_physical.xml'
-SFA_MAX_CANNED_RSPEC = '/etc/sfa/max_physical_canned.xml'
-
-topology = {}
-
-class SfaOutOfResource(SfaFault):
- def __init__(self, interface):
- faultString = "Interface " + interface + " not available"
- SfaFault.__init__(self, 100, faultString, '')
-
-class SfaNoPairRSpec(SfaFault):
- def __init__(self, interface, interface2):
- faultString = "Interface " + interface + " should be paired with " + interface2
- SfaFault.__init__(self, 100, faultString, '')
-
-# Returns a mapping from interfaces to the nodes they lie on and their peer interfaces
-# i -> node,i_peer
-
-def get_interface_map():
- r = RSpec()
- r.parseFile(SFA_MAX_DEFAULT_RSPEC)
- rspec = r.toDict()
- capacity = rspec['rspec']['capacity']
- netspec = capacity[0]['netspec'][0]
- linkdefs = {}
- for n in netspec['nodespec']:
- ifspecs = n['ifspec']
- nodename = n['node']
- for i in ifspecs:
- ifname = i['name']
- linkid = i['linkid']
-
- if (linkdefs.has_key(linkid)):
- linkdefs[linkid].extend([(nodename,ifname)])
- else:
- linkdefs[linkid]=[(nodename,ifname)]
-
- # topology maps interface x interface -> link,node1,node2
- topology={}
-
- for k in linkdefs.keys():
- (n1,i1) = linkdefs[k][0]
- (n2,i2) = linkdefs[k][1]
-
- topology[i1] = (n1, i2)
- topology[i2] = (n2, i1)
-
-
- return topology
-
-
-def allocations_to_rspec(allocations):
- rspec = xml.dom.minidom.parse(SFA_MAX_DEFAULT_RSPEC)
- req = rspec.firstChild.appendChild(rspec.createElement("request"))
- for (iname,ip) in allocations:
- ifspec = req.appendChild(rspec.createElement("ifspec"))
- ifspec.setAttribute("name","tns:"+iname)
- ifspec.setAttribute("ip",ip)
-
- return rspec.toxml()
-
-
-def if_endpoints(ifs):
- nodes=[]
- for l in ifs:
- nodes.extend(topology[l][0])
- return nodes
-
-def lock_state_file():
- # Noop for demo
- return True
-
-def unlock_state_file():
- return True
- # Noop for demo
-
-def read_alloc_dict():
- alloc_dict={}
- rows = open(SFA_MAX_CONF_FILE).read().split('\n')
- for r in rows:
- columns = r.split(' ')
- if (len(columns)==2):
- hrn = columns[0]
- allocs = columns[1].split(',')
- ipallocs = map(lambda alloc:alloc.split('/'), allocs)
- alloc_dict[hrn]=ipallocs
- return alloc_dict
-
-def commit_alloc_dict(d):
- f = open(SFA_MAX_CONF_FILE, 'w')
- for hrn in d.keys():
- columns = d[hrn]
- ipcolumns = map(lambda x:"/".join(x), columns)
- row = hrn+' '+','.join(ipcolumns)+'\n'
- f.write(row)
- f.close()
-
-def collapse_alloc_dict(d):
- ret = []
- for k in d.keys():
- ret.extend(d[k])
- return ret
-
-
-def alloc_links(api, hrn, links_to_add, links_to_drop):
- slicename=hrn_to_pl_slicename(hrn)
- for (iface,ip) in links_to_add:
- node = topology[iface][0][0]
- try:
- api.plshell.AddSliceTag(api.plauth, slicename, "ip_addresses", ip, node)
- api.plshell.AddSliceTag(api.plauth, slicename, "vsys", "getvlan", node)
- except Exception:
- # Probably a duplicate tag. XXX July 21
- pass
- return True
-
-def alloc_nodes(api,hrn, requested_ifs):
- requested_nodes = if_endpoints(requested_ifs)
- create_slice_max_aggregate(api, hrn, requested_nodes)
-
-# Taken from slices.py
-
-def create_slice_max_aggregate(api, hrn, nodes):
- # Get the slice record from SFA
- global topology
- topology = get_interface_map()
- slice = {}
- registries = Registries(api)
- registry = registries[api.hrn]
- credential = api.getCredential()
- records = registry.resolve(credential, hrn)
- for record in records:
- if record.get_type() in ['slice']:
- slice = record.as_dict()
- if not slice:
- raise RecordNotFound(hrn)
-
- # Make sure slice exists at plc, if it doesnt add it
- slicename = hrn_to_pl_slicename(hrn)
- slices = api.plshell.GetSlices(api.plauth, [slicename], ['node_ids'])
- if not slices:
- parts = slicename.split("_")
- login_base = parts[0]
- # if site doesnt exist add it
- sites = api.plshell.GetSites(api.plauth, [login_base])
- if not sites:
- authority = get_authority(hrn)
- site_records = registry.resolve(credential, authority)
- site_record = {}
- if not site_records:
- raise RecordNotFound(authority)
- site_record = site_records[0]
- site = site_record.as_dict()
-
- # add the site
- site.pop('site_id')
- site_id = api.plshell.AddSite(api.plauth, site)
- else:
- site = sites[0]
-
- slice_fields = {}
- slice_keys = ['name', 'url', 'description']
- for key in slice_keys:
- if key in slice and slice[key]:
- slice_fields[key] = slice[key]
- api.plshell.AddSlice(api.plauth, slice_fields)
- slice = slice_fields
- slice['node_ids'] = 0
- else:
- slice = slices[0]
-
- # get the list of valid slice users from the registry and make
- # they are added to the slice
- researchers = record.get('researcher', [])
- for researcher in researchers:
- person_record = {}
- person_records = registry.resolve(credential, researcher)
- for record in person_records:
- if record.get_type() in ['user']:
- person_record = record
- if not person_record:
- pass
- person_dict = person_record.as_dict()
- persons = api.plshell.GetPersons(api.plauth, [person_dict['email']],
- ['person_id', 'key_ids'])
-
- # Create the person record
- if not persons:
- person_id=api.plshell.AddPerson(api.plauth, person_dict)
-
- # The line below enables the user account on the remote aggregate
- # soon after it is created.
- # without this the user key is not transfered to the slice
- # (as GetSlivers returns key of only enabled users),
- # which prevents the user from login to the slice.
- # We may do additional checks before enabling the user.
-
- api.plshell.UpdatePerson(api.plauth, person_id, {'enabled' : True})
- key_ids = []
- else:
- key_ids = persons[0]['key_ids']
-
- api.plshell.AddPersonToSlice(api.plauth, person_dict['email'],
- slicename)
-
- # Get this users local keys
- keylist = api.plshell.GetKeys(api.plauth, key_ids, ['key'])
- keys = [key['key'] for key in keylist]
-
- # add keys that arent already there
- for personkey in person_dict['keys']:
- if personkey not in keys:
- key = {'key_type': 'ssh', 'key': personkey}
- api.plshell.AddPersonKey(api.plauth, person_dict['email'], key)
-
- # find out where this slice is currently running
- nodelist = api.plshell.GetNodes(api.plauth, slice['node_ids'],
- ['hostname'])
- hostnames = [node['hostname'] for node in nodelist]
-
- # remove nodes not in rspec
- deleted_nodes = list(set(hostnames).difference(nodes))
- # add nodes from rspec
- added_nodes = list(set(nodes).difference(hostnames))
-
- api.plshell.AddSliceToNodes(api.plauth, slicename, added_nodes)
- api.plshell.DeleteSliceFromNodes(api.plauth, slicename, deleted_nodes)
-
- return 1
-
-
-def ListResources(api, hrn):
- # Eg. config line:
- # plc.princeton.sapan vlan23,vlan45
-
- allocations = read_alloc_dict()
- if (hrn and allocations.has_key(hrn)):
- ret_rspec = allocations_to_rspec(allocations[hrn])
- else:
- ret_rspec = open(SFA_MAX_CANNED_RSPEC).read()
-
- return (ret_rspec)
-
-
-def CreateSliver(api, hrn, rspec_xml):
- global topology
- topology = get_interface_map()
-
- # Check if everything in rspec is either allocated by hrn
- # or not allocated at all.
- r = RSpec()
- r.parseString(rspec_xml)
- rspec = r.toDict()
-
- lock_state_file()
-
- allocations = read_alloc_dict()
- requested_allocations = rspec_to_allocations (rspec)
- current_allocations = collapse_alloc_dict(allocations)
- try:
- current_hrn_allocations=allocations[hrn]
- except KeyError:
- current_hrn_allocations=[]
-
- # Check request against current allocations
- requested_interfaces = map(lambda(elt):elt[0], requested_allocations)
- current_interfaces = map(lambda(elt):elt[0], current_allocations)
- current_hrn_interfaces = map(lambda(elt):elt[0], current_hrn_allocations)
-
- for a in requested_interfaces:
- if (a not in current_hrn_interfaces and a in current_interfaces):
- raise SfaOutOfResource(a)
- if (topology[a][1] not in requested_interfaces):
- raise SfaNoPairRSpec(a,topology[a][1])
- # Request OK
-
- # Allocations to delete
- allocations_to_delete = []
- for a in current_hrn_allocations:
- if (a not in requested_allocations):
- allocations_to_delete.extend([a])
-
- # Ok, let's do our thing
- alloc_nodes(api, hrn, requested_interfaces)
- alloc_links(api, hrn, requested_allocations, allocations_to_delete)
- allocations[hrn] = requested_allocations
- commit_alloc_dict(allocations)
-
- unlock_state_file()
-
- return True
-
-def rspec_to_allocations(rspec):
- ifs = []
- try:
- ifspecs = rspec['rspec']['request'][0]['ifspec']
- for l in ifspecs:
- ifs.extend([(l['name'].replace('tns:',''),l['ip'])])
- except KeyError:
- # Bad RSpec
- pass
- return ifs
-
-def main():
- t = get_interface_map()
- r = RSpec()
- rspec_xml = open(sys.argv[1]).read()
- #ListResources(None,'foo')
- CreateSliver(None, "plc.princeton.sap0", rspec_xml)
-
-if __name__ == "__main__":
- main()
+++ /dev/null
-import sys
-
-#The following is not essential
-#from soaplib.wsgi_soap import SimpleWSGISoapApp
-#from soaplib.serializers.primitive import *
-#from soaplib.serializers.clazz import *
-
-import socket
-import struct
-
-from sfa.util.faults import *
-from sfa.util.rspec import RSpec
-from sfa.server.registry import Registries
-from sfa.util.config import Config
-from sfa.plc.nodes import *
-
-# Message IDs for all the SFA light calls
-# This will be used by the aggrMgr controller
-SFA_GET_RESOURCES = 101
-SFA_CREATE_SLICE = 102
-SFA_START_SLICE = 103
-SFA_STOP_SLICE = 104
-SFA_DELETE_SLICE = 105
-SFA_GET_SLICES = 106
-SFA_RESET_SLICES = 107
-
-DEBUG = 1
-
-def print_buffer(buf):
- for i in range(0,len(buf)):
- print('%x' % buf[i])
-
-def extract(sock):
- # Shud we first obtain the message length?
- # msg_len = socket.ntohs(sock.recv(2))
- msg = ""
-
- while (1):
- try:
- chunk = sock.recv(1)
- except socket.error, message:
- if 'timed out' in message:
- break
- else:
- sys.exit("Socket error: " + message)
-
- if len(chunk) == 0:
- break
- msg += chunk
-
- print 'Done extracting %d bytes of response from aggrMgr' % len(msg)
- return msg
-
-def connect(server, port):
- '''Connect to the Aggregate Manager module'''
- sock = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
- sock.connect ( ( server, port) )
- sock.settimeout(1)
- if DEBUG: print 'Connected!'
- return sock
-
-def connect_aggrMgr():
- (aggr_mgr_ip, aggr_mgr_port) = Config().get_openflow_aggrMgr_info()
- if DEBUG: print """Connecting to port %d of %s""" % (aggr_mgr_port, aggr_mgr_ip)
- return connect(aggr_mgr_ip, aggr_mgr_port)
-
-def generate_slide_id(cred, hrn):
- if cred == None:
- cred = ""
- if hrn == None:
- hrn = ""
- #return cred + '_' + hrn
- return str(hrn)
-
-def msg_aggrMgr(cred, hrn, msg_id):
- slice_id = generate_slide_id(cred, hrn)
-
- msg = struct.pack('> B%ds' % len(slice_id), msg_id, slice_id)
- buf = struct.pack('> H', len(msg)+2) + msg
-
- try:
- aggrMgr_sock = connect_aggrMgr()
- aggrMgr_sock.send(buf)
- aggrMgr_sock.close()
- return 1
- except socket.error, message:
- print "Socket error"
- except IOerror, message:
- print "IO error"
- return 0
-
-def start_slice(cred, hrn):
- if DEBUG: print "Received start_slice call"
- return msg_aggrMgr(SFA_START_SLICE)
-
-def stop_slice(cred, hrn):
- if DEBUG: print "Received stop_slice call"
- return msg_aggrMgr(SFA_STOP_SLICE)
-
-def delete_slice(cred, hrn):
- if DEBUG: print "Received delete_slice call"
- return msg_aggrMgr(SFA_DELETE_SLICE)
-
-def reset_slices(cred, hrn):
- if DEBUG: print "Received reset_slices call"
- return msg_aggrMgr(SFA_RESET_SLICES)
-
-def CreateSliver(cred, hrn, rspec):
- if DEBUG: print "Received CreateSliver call"
- slice_id = generate_slide_id(cred, hrn)
-
- msg = struct.pack('> B%ds%ds' % (len(slice_id)+1, len(rspec)), SFA_CREATE_SLICE, slice_id, rspec)
- buf = struct.pack('> H', len(msg)+2) + msg
-
- try:
- aggrMgr_sock = connect_aggrMgr()
- aggrMgr_sock.send(buf)
- if DEBUG: print "Sent %d bytes and closing connection" % len(buf)
- aggrMgr_sock.close()
-
- if DEBUG: print "----------------"
- return 1
- except socket.error, message:
- print "Socket error"
- except IOerror, message:
- print "IO error"
- return 0
-
-def ListResources(cred, hrn=None):
- if DEBUG: print "Received ListResources call"
- slice_id = generate_slide_id(cred, hrn)
-
- msg = struct.pack('> B%ds' % len(slice_id), SFA_GET_RESOURCES, slice_id)
- buf = struct.pack('> H', len(msg)+2) + msg
-
- try:
- aggrMgr_sock = connect_aggrMgr()
- aggrMgr_sock.send(buf)
- resource_list = extract(aggrMgr_sock);
- aggrMgr_sock.close()
-
- if DEBUG: print "----------------"
- return resource_list
- except socket.error, message:
- print "Socket error"
- except IOerror, message:
- print "IO error"
- return None
-
-"""
-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.parseFile(sys.argv[1])
- rspec = r.toDict()
- CreateSliver(None,'plc',rspec)
-
-if __name__ == "__main__":
- main()
+++ /dev/null
-"""
-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
+++ /dev/null
-FAULT_UNHANDLEDSERVEREXCEPTION = 901
-FAULT_BADREQUESTHASH = 902
+++ /dev/null
-import traceback
-import xmlrpclib
-
-FAULTCODE = 900
-
-class UnhandledServerException(xmlrpclib.Fault):
- def __init__(self, type, value, tb):
- exc_str = ''.join(traceback.format_exception(type, value, tb))
- faultString = exc_str # "Unhandled exception: " + str(type) + "\n" + exc_str
- xmlrpclib.Fault.__init__(self, FAULTCODE + 1, faultString)
-
-class BadRequestHash(xmlrpclib.Fault):
- def __init__(self, hash = None):
- faultString = "bad request hash: " + str(hash)
- xmlrpclib.Fault.__init__(self, FAULTCODE + 2, faultString)
+++ /dev/null
-import xmlrpclib
-
-from BaseApi import BaseApi
-
-from sfa.trust.credential import Credential
-from sfa.trust.gid import GID
-from sfa.trust.trustedroot import TrustedRootList
-
-from ApiExceptionCodes import *
-
-class BadRequestHash(xmlrpclib.Fault):
- def __init__(self, hash = None):
- faultString = "bad request hash: " + str(hash)
- xmlrpclib.Fault.__init__(self, FAULT_BADREQUESTHASH, faultString)
-
-class AuthenticatedApi(BaseApi):
- def __init__(self, encoding = "utf-8", trustedRootsDir=None):
- BaseApi.__init__(self, encoding)
- if trustedRootsDir:
- self.trusted_cert_list = TrustedRootList(trustedRootsDir).get_list()
- self.trusted_cert_file_list = TrustedRootList(trustedRootsDir).get_file_list()
- else:
- self.trusted_cert_list = None
-
- def register_functions(self):
- BaseApi.register_functions(self)
- self.register_function(self.gidNoop)
-
- def verifyGidRequestHash(self, gid, hash, arglist):
- key = gid.get_pubkey()
- if not key.verify_string(str(arglist), hash):
- raise BadRequestHash(hash)
-
- def verifyCredRequestHash(self, cred, hash, arglist):
- gid = cred.get_gid_caller()
- self.verifyGidRequestHash(gid, hash, arglist)
-
- def validateGid(self, gid):
- if self.trusted_cert_list:
- gid.verify_chain(self.trusted_cert_list)
-
- def validateCred(self, cred):
- if self.trusted_cert_list:
- cred.verify(self.trusted_cert_file_list)
-
- def authenticateGid(self, gidStr, argList, requestHash):
- gid = GID(string = gidStr)
- self.validateGid(gid)
- self.verifyGidRequestHash(gid, requestHash, argList)
- return gid
-
- def authenticateCred(self, credStr, argList, requestHash):
- cred = Credential(string = credStr)
- self.validateCred(cred)
- self.verifyCredRequestHash(cred, requestHash, argList)
- return cred
-
- def gidNoop(self, gidStr, value, requestHash):
- self.authenticateGid(gidStr, [gidStr, value], requestHash)
- return value
-
- def credNoop(self, credStr, value, requestHash):
- self.authenticateCred(credStr, [credStr, value], requestHash)
- return value
-
-
+++ /dev/null
-from sfa.trust.certificate import Keypair
-from sfa.trust.gid import GID
-
-from BaseClient import BaseClient
-
-class AuthenticatedClient(BaseClient):
- def __init__(self, url, private_key_file, gid_file=None, cred_file=None):
- BaseClient.__init__(self, url)
- self.private_key_file = private_key_file
- self.gid_file = gid_file
- self.cred_file = cred_file
- self.private_key = Keypair(filename = self.private_key_file)
- if gid_file:
- self.gid = GID(filename = self.gid_file)
- if cred_file:
- self.cred = Credential(filename = self.cred_file)
-
- def computeRequestHash(self, argList):
- return self.private_key.sign_string(str(argList))
-
- def gidNoop(self, value):
- gidStr = self.gid.save_to_string(True)
- reqHash = self.computeRequestHash([gidStr, value])
- return self.server.gidNoop(gidStr, value, reqHash)
+++ /dev/null
-#
-# PLCAPI XML-RPC and SOAP interfaces
-#
-# Aaron Klingaman <alk@absarokasoft.com>
-# Mark Huang <mlhuang@cs.princeton.edu>
-#
-# Copyright (C) 2004-2006 The Trustees of Princeton University
-# $Id: API.py 14587 2009-07-19 13:18:50Z thierry $
-# $URL: https://svn.planet-lab.org/svn/PLCAPI/trunk/PLC/API.py $
-#
-
-import sys
-import traceback
-import string
-
-import xmlrpclib
-import logging
-import logging.handlers
-
-from ApiExceptionCodes import *
-
-# Wrapper around xmlrpc fault to include a traceback of the server to the
-# client. This is done to aid in debugging from a client perspective.
-
-class FaultWithTraceback(xmlrpclib.Fault):
- def __init__(self, code, faultString, exc_info):
- type, value, tb = exc_info
- exc_str = ''.join(traceback.format_exception(type, value, tb))
- faultString = faultString + "\nFAULT_TRACEBACK:" + exc_str
- xmlrpclib.Fault.__init__(self, code, faultString)
-
-# Exception to report to the caller when some non-XMLRPC fault occurs on the
-# server. For example a TypeError.
-
-class UnhandledServerException(FaultWithTraceback):
- def __init__(self, exc_info):
- type, value, tb = exc_info
- faultString = "Unhandled exception: " + str(type)
- FaultWithTraceback.__init__(self, FAULT_UNHANDLEDSERVEREXCEPTION, faultString, exc_info)
-
-# See "2.2 Characters" in the XML specification:
-#
-# #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
-# avoiding
-# [#x7F-#x84], [#x86-#x9F], [#xFDD0-#xFDDF]
-
-invalid_xml_ascii = map(chr, range(0x0, 0x8) + [0xB, 0xC] + range(0xE, 0x1F))
-xml_escape_table = string.maketrans("".join(invalid_xml_ascii), "?" * len(invalid_xml_ascii))
-
-def xmlrpclib_escape(s, replace = string.replace):
- """
- xmlrpclib does not handle invalid 7-bit control characters. This
- function augments xmlrpclib.escape, which by default only replaces
- '&', '<', and '>' with entities.
- """
-
- # This is the standard xmlrpclib.escape function
- s = replace(s, "&", "&")
- s = replace(s, "<", "<")
- s = replace(s, ">", ">",)
-
- # Replace invalid 7-bit control characters with '?'
- return s.translate(xml_escape_table)
-
-def xmlrpclib_dump(self, value, write):
- """
- xmlrpclib cannot marshal instances of subclasses of built-in
- types. This function overrides xmlrpclib.Marshaller.__dump so that
- any value that is an instance of one of its acceptable types is
- marshalled as that type.
-
- xmlrpclib also cannot handle invalid 7-bit control characters. See
- above.
- """
-
- # Use our escape function
- args = [self, value, write]
- if isinstance(value, (str, unicode)):
- args.append(xmlrpclib_escape)
-
- try:
- # Try for an exact match first
- f = self.dispatch[type(value)]
- except KeyError:
- # Try for an isinstance() match
- for (Type, f) in self.dispatch.iteritems():
- if isinstance(value, Type):
- f(*args)
- return
- raise TypeError, "cannot marshal %s objects" % type(value)
- else:
- f(*args)
-
-# You can't hide from me!
-xmlrpclib.Marshaller._Marshaller__dump = xmlrpclib_dump
-
-# SOAP support is optional
-try:
- import SOAPpy
- from SOAPpy.Parser import parseSOAPRPC
- from SOAPpy.Types import faultType
- from SOAPpy.NS import NS
- from SOAPpy.SOAPBuilder import buildSOAP
-except ImportError:
- SOAPpy = None
-
-def import_deep(name):
- mod = __import__(name)
- components = name.split('.')
- for comp in components[1:]:
- mod = getattr(mod, comp)
- return mod
-
-class BaseApi:
- def __init__(self, encoding = "utf-8"):
- self.encoding = encoding
- self.init_logger()
- self.funcs = {}
- self.register_functions()
-
- def init_logger(self):
- self.logger = logging.getLogger("ApiLogger")
- self.logger.setLevel(logging.INFO)
- self.logger.addHandler(logging.handlers.RotatingFileHandler(self.get_log_name(), maxBytes=100000, backupCount=5))
-
- def get_log_name(self):
- return "/tmp/apilogfile.txt"
-
- def register_functions(self):
- self.register_function(self.noop)
-
- def register_function(self, function, name = None):
- if name is None:
- name = function.__name__
- self.funcs[name] = function
-
- def call(self, source, method, *args):
- """
- Call the named method from the specified source with the
- specified arguments.
- """
-
- if not method in self.funcs:
- raise "Unknown method: " + method
-
- return self.funcs[method](*args)
-
- def handle(self, source, data):
- """
- Handle an XML-RPC or SOAP request from the specified source.
- """
-
- # Parse request into method name and arguments
- try:
- interface = xmlrpclib
- (args, method) = xmlrpclib.loads(data)
- methodresponse = True
- except Exception, e:
- if SOAPpy is not None:
- interface = SOAPpy
- (r, header, body, attrs) = parseSOAPRPC(data, header = 1, body = 1, attrs = 1)
- method = r._name
- args = r._aslist()
- # XXX Support named arguments
- else:
- raise e
-
- self.logger.debug("BaseApi.handle OP:" + str(method) + " from " + str(source))
-
- try:
- result = self.call(source, method, *args)
- except xmlrpclib.Fault, fault:
- self.logger.warning("FAULT: " + str(fault.faultCode) + " " + str(fault.faultString))
- self.logger.info(traceback.format_exc())
- # Handle expected faults
- if interface == xmlrpclib:
- result = FaultWithTraceback(fault.faultCode, fault.faultString, sys.exc_info())
- methodresponse = None
- elif interface == SOAPpy:
- result = faultParameter(NS.ENV_T + ":Server", "Method Failed", method)
- result._setDetail("Fault %d: %s" % (fault.faultCode, fault.faultString))
- self.logger.debug
- except:
- self.logger.warning("EXCEPTION: " + str(sys.exc_info()[0]))
- self.logger.info(traceback.format_exc())
- result = UnhandledServerException(sys.exc_info())
- methodresponse = None
-
- # Return result
- if interface == xmlrpclib:
- if not isinstance(result, xmlrpclib.Fault):
- result = (result,)
- data = xmlrpclib.dumps(result, methodresponse = True, encoding = self.encoding, allow_none = 1)
- elif interface == SOAPpy:
- data = buildSOAP(kw = {'%sResponse' % method: {'Result': result}}, encoding = self.encoding)
-
- return data
-
- def noop(self, value):
- return value
+++ /dev/null
-import xmlrpclib
-
-from ApiExceptionCodes import *
-
-class ExceptionUnmarshaller(xmlrpclib.Unmarshaller):
- def close(self):
- try:
- return xmlrpclib.Unmarshaller.close(self)
- except xmlrpclib.Fault, e:
- # if the server tagged some traceback info onto the end of the
- # exception text, then print it out on the client.
-
- if "\nFAULT_TRACEBACK:" in e.faultString:
- parts = e.faultString.split("\nFAULT_TRACEBACK:")
- e.faultString = parts[0]
- if BaseClient.VerboseExceptions:
- print "\n|Server Traceback:", "\n|".join(parts[1].split("\n"))
-
- raise e
-
-class ExceptionReportingTransport(xmlrpclib.Transport):
- def make_connection(self, host):
- import httplib
- if host.startswith("https:"):
- return httplib.HTTPS(host)
- else:
- return httplib.HTTP(host)
-
- def getparser(self):
- unmarshaller = ExceptionUnmarshaller()
- parser = xmlrpclib.ExpatParser(unmarshaller)
- return parser, unmarshaller
-
-class BaseClient():
-
- VerboseExceptions = False
-
- def __init__(self, url):
- self.url = url
- self.server = xmlrpclib.ServerProxy(self.url, ExceptionReportingTransport())
-
- def noop(self, value):
- return self.server.noop(value)
-
- @staticmethod
- def EnableVerboseExceptions(x=True):
- BaseClient.VerboseExceptions = x
-
+++ /dev/null
-#
-# Apache mod_python interface
-#
-# Aaron Klingaman <alk@absarokasoft.com>
-# Mark Huang <mlhuang@cs.princeton.edu>
-#
-# Copyright (C) 2004-2006 The Trustees of Princeton University
-#
-
-import sys
-import traceback
-import xmlrpclib
-from mod_python import apache
-
-from sfa.util.logging import sfa_logger
-from API import RemoteApi
-api = RemoteApi()
-
-def handler(req):
- try:
- if req.method != "POST":
- req.content_type = "text/html"
- req.send_http_header()
- req.write("""
-<html><head>
-<title>PLCAPI XML-RPC/SOAP Interface</title>
-</head><body>
-<h1>PLCAPI XML-RPC/SOAP Interface</h1>
-<p>Please use XML-RPC or SOAP to access the PLCAPI.</p>
-</body></html>
-""")
- return apache.OK
-
- # Read request
- request = req.read(int(req.headers_in['content-length']))
-
- # mod_python < 3.2: The IP address portion of remote_addr is
- # incorrect (always 0.0.0.0) when IPv6 is enabled.
- # http://issues.apache.org/jira/browse/MODPYTHON-64?page=all
- (remote_ip, remote_port) = req.connection.remote_addr
- remote_addr = (req.connection.remote_ip, remote_port)
-
- # Handle request
- response = api.handle(remote_addr, request)
-
- # Write response
- req.content_type = "text/xml; charset=" + api.encoding
- req.send_http_header()
- req.write(response)
-
- return apache.OK
-
- except Exception, err:
- # Log error in /var/log/httpd/(ssl_)?error_log
- sfa_logger().log_exc("%r"%err)
- return apache.HTTP_INTERNAL_SERVER_ERROR
+++ /dev/null
-from AuthenticatedApi import AuthenticatedApi, BadRequestHash
-
-class RemoteApi(AuthenticatedApi):
- def __init__(self, encoding="utf-8", trustedRootsDir="/usr/local/testapi/var/trusted_roots"):
- return AuthenticatedApi.__init__(self, encoding)
-
- def get_log_name(self):
- return "/usr/local/testapi/var/logfile.txt"
-
- def register_functions(self):
- AuthenticatedApi.register_functions(self)
- self.register_function(self.typeError)
- self.register_function(self.badRequestHash)
-
- def typeError(self):
- raise TypeError()
-
- def badRequestHash(self):
- raise BadRequestHash("somehashvalue")
+++ /dev/null
-SFA_SRC_DIR=/home/smbaker/projects/sfa/trunk
-
-mkdir -p /usr/local/testapi/bin
-mkdir -p /usr/local/testapi/bin/sfa/trust
-mkdir -p /usr/local/testapi/bin/sfa/util
-mkdir -p /usr/local/testapi/var/trusted_roots
-mkdir -p /repository/testapi
-
-# source code for the API
-cp BaseApi.py /usr/local/testapi/bin/
-cp AuthenticatedApi.py /usr/local/testapi/bin/
-cp TestApi.py /usr/local/testapi/bin/API.py
-cp ModPython.py /usr/local/testapi/bin/
-cp ApiExceptionCodes.py /usr/local/testapi/bin/
-
-# trusted root certificates that match gackstestuser.*
-cp trusted_roots/*.gid /usr/local/testapi/var/trusted_roots/
-
-# apache config file to enable the api
-cp testapi.conf /etc/httpd/conf.d/
-
-# copy over sfa stuff that we need
-echo > /usr/local/testapi/bin/sfa/__init__.py
-echo > /usr/local/testapi/bin/sfa/trust/__init__.py
-echo > /usr/local/testapi/bin/sfa/util/__init__.py
-cp $SFA_SRC_DIR/sfa/trust/gid.py /usr/local/testapi/bin/sfa/trust/
-cp $SFA_SRC_DIR/sfa/trust/certificate.py /usr/local/testapi/bin/sfa/trust/
-cp $SFA_SRC_DIR/sfa/trust/trustedroot.py /usr/local/testapi/bin/sfa/trust/
-cp $SFA_SRC_DIR/sfa/trust/credential.py /usr/local/testapi/bin/sfa/trust/
-cp $SFA_SRC_DIR/sfa/trust/rights.py /usr/local/testapi/bin/sfa/trust/
-cp $SFA_SRC_DIR/sfa/util/faults.py /usr/local/testapi/bin/sfa/util/
-
-# make everything owned by apache
-chown -R apache /usr/local/testapi
-chown apache /etc/httpd/conf.d/testapi.conf
-
-/etc/init.d/httpd restart
+++ /dev/null
-import sys
-import traceback
-
-from BaseClient import BaseClient
-from AuthenticatedClient import AuthenticatedClient
-
-BaseClient.EnableVerboseExceptions(True)
-
-HOST = "localhost"
-URL = "http://" + HOST + "/TESTAPI/"
-SURL = "https://" + HOST + "/TESTAPI/"
-
-print "*** testing some valid ops; these should print \"Hello, World\" ***"
-
-bc = BaseClient(URL)
-print "HTTP noop:", bc.noop("Hello, World")
-
-ac = AuthenticatedClient(URL, "gackstestuser.pkey", "gackstestuser.gid")
-print "HTTP gidNoop:", ac.gidNoop("Hello, World")
-
-bc = BaseClient(SURL)
-print "HTTPS noop:", bc.noop("Hello, World")
-
-ac = AuthenticatedClient(URL, "gackstestuser.pkey", "gackstestuser.gid")
-print "HTTPS gidNoop:", ac.gidNoop("Hello, World")
-
-print
-print "*** testing some exception handling: ***"
-
-bc = BaseClient(URL)
-print "HTTP typeError:",
-try:
- result = bc.server.typeError()
- print result
-except Exception, e:
- print ''.join(traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))
-
-print "HTTP badrequesthash:",
-try:
- result = bc.server.badRequestHash()
- print result
-except:
- print ''.join(traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))
-
+++ /dev/null
-export PYTHONPATH=/home/smbaker/projects/sfa/trunk
-
-python ./test.py
+++ /dev/null
-<Location /TESTAPI/>
- SetHandler mod_python
- PythonPath "sys.path + ['/usr/local/testapi/bin/']"
- PythonHandler ModPython
-</Location>
\ No newline at end of file