-#!/usr/bin/python
-
+from sfa.util.rspec import RSpec
import sys
import pdb
-import xml.dom.minidom
-
-from sfa.util.rspec import RSpec
-from sfa.util.xrn import urn_to_hrn, hrn_to_urn, get_authority
-from sfa.util.plxrn import hrn_to_pl_slicename
-from sfa.util.plxrn import hrn_to_pl_slicename
+from sfa.util.namespace import *
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.util.debug import log
from sfa.server.aggregate import Aggregates
+from sfa.util.xrn import urn_to_hrn, hrn_to_urn, get_authority
+from sfa.util.plxrn import hrn_to_pl_slicename
+from sfa.util.plxrn import hrn_to_pl_slicename
from sfa.server.registry import Registries
+from sfa.util.rspec import RSpec
+from sfa.util.sfalogging import sfa_logger
from sfa.util.faults import *
-from sfa.util.callids import Callids
+import xml.dom.minidom
SFA_MAX_CONF_FILE = '/etc/sfa/max_allocations'
SFA_MAX_DEFAULT_RSPEC = '/etc/sfa/max_physical.xml'
ret = []
for k in d.keys():
ret.extend(d[k])
+from sfa.util.config import Config
+from sfa.managers.aggregate_manager_pl import GetVersion
+import os
+import time
+
+RSPEC_TMP_FILE_PREFIX = "/tmp/max_rspec"
+
+# execute shell command and return both exit code and text output
+def shell_execute(cmd, timeout):
+ pipe = os.popen('{ ' + cmd + '; } 2>&1', 'r')
+ pipe = os.popen(cmd + ' 2>&1', 'r')
+ text = ''
+ while timeout:
+ line = pipe.read()
+ text += line
+ time.sleep(1)
+ timeout = timeout-1
+ code = pipe.close()
+ if code is None: code = 0
+ if text[-1:] == '\n': text = text[:-1]
+ return code, text
+
+"""
+ call AM API client with command like in the following example:
+ cd aggregate_client; java -classpath AggregateWS-client-api.jar:lib/* \
+ net.geni.aggregate.client.examples.CreateSliceNetworkClient \
+ ./repo https://geni:8443/axis2/services/AggregateGENI \
+ ... params ...
+"""
+
+def call_am_apiclient(client_app, params, timeout):
+ (client_path, am_url) = Config().get_max_aggrMgr_info()
+ sys_cmd = "cd " + client_path + "; java -classpath AggregateWS-client-api.jar:lib/* net.geni.aggregate.client.examples." + client_app + " ./repo " + am_url + " " + ' '.join(params)
+ ret = shell_execute(sys_cmd, timeout)
+ sfa_logger().debug("shell_execute cmd: %s returns %s" % (sys_cmd, ret))
return ret
except Exception:
# Probably a duplicate tag. XXX July 21
pass
+# save request RSpec xml content to a tmp file
+def save_rspec_to_file(rspec):
+ path = RSPEC_TMP_FILE_PREFIX + "_" + time.strftime('%Y%m%dT%H:%M:%S', time.gmtime(time.time())) +".xml"
+ file = open(path, "w")
+ file.write(rspec)
+ file.close()
+ return path
+
+# get stripped down slice id/name plc:maxpl:xi_slice1 --> xi_slice1
+def get_short_slice_id(cred, hrn):
+ if hrn == None:
+ return None
+ slice_id = hrn[hrn.rfind('+')+1:]
+ if slice_id == None:
+ slice_id = hrn[hrn.rfind(':')+1:]
+ if slice_id == None:
+ return hrn
+ pass
+ return str(slice_id)
+
+# extract xml
+def get_xml_by_tag(text, tag):
+ indx1 = text.find('<'+tag)
+ indx2 = text.find('/'+tag+'>')
+ xml = None
+ if indx1!=-1 and indx2>indx1:
+ xml = text[indx1:indx2+len(tag)+2]
+ return xml
+
+def create_slice(api, xrn, cred, rspec, users):
+ indx1 = rspec.find("<RSpec")
+ indx2 = rspec.find("</RSpec>")
+ if indx1 > -1 and indx2 > indx1:
+ rspec = rspec[indx1+len("<RSpec type=\"SFA\">"):indx2-1]
+ rspec_path = save_rspec_to_file(rspec)
+ (ret, output) = call_am_apiclient("CreateSliceNetworkClient", [rspec_path,], 3)
+ # parse output ?
+ rspec = "<RSpec type=\"SFA\"> Done! </RSpec>"
return True
def alloc_nodes(api,hrn, requested_ifs):
registries = Registries(api)
registry = registries[api.hrn]
credential = api.getCredential()
- urn = hrn_to_urn(hrn, 'slice')
- records = registry.Resolve(urn, credential)
+ records = registry.resolve(credential, hrn)
for record in records:
if record.get_type() in ['slice']:
slice = record.as_dict()
sites = api.plshell.GetSites(api.plauth, [login_base])
if not sites:
authority = get_authority(hrn)
- authority_urn = hrn_to_urn(authority, 'authority')
- site_records = registry.Resolve(authority_urn, credential)
+ site_records = registry.resolve(credential, authority)
site_record = {}
if not site_records:
raise RecordNotFound(authority)
researchers = record.get('researcher', [])
for researcher in researchers:
person_record = {}
- researcher_urn = hrn_to_urn(researcher, 'user')
- person_records = registry.Resolve(researcher_urn, credential)
+ person_records = registry.resolve(credential, researcher)
for record in person_records:
if record.get_type() in ['user']:
person_record = record
api.plshell.AddSliceToNodes(api.plauth, slicename, added_nodes)
api.plshell.DeleteSliceFromNodes(api.plauth, slicename, deleted_nodes)
+def delete_slice(api, xrn, cred):
+ slice_id = get_short_slice_id(cred, xrn)
+ (ret, output) = call_am_apiclient("DeleteSliceNetworkClient", [slice_id,], 3)
+ # parse output ?
return 1
-def ListResources(api, creds, options, call_id):
- if Callids().already_handled(call_id): return ""
+def get_rspec(api, creds, options):
# get slice's hrn from options
- xrn = options.get('geni_slice_urn', '')
+ xrn = options.get('geni_slice_urn', None)
hrn, type = urn_to_hrn(xrn)
# 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])
+def get_rspec(api, cred, options):
+ #geni_slice_urn: urn:publicid:IDN+plc:maxpl+slice+xi_rspec_test1
+ urn = options.get('geni_slice_urn')
+ slice_id = get_short_slice_id(cred, urn)
+ if slice_id == None:
+ (ret, output) = call_am_apiclient("GetResourceTopology", ['all', '\"\"'], 5)
else:
ret_rspec = open(SFA_MAX_CANNED_RSPEC).read()
return (ret_rspec)
-def CreateSliver(api, xrn, creds, rspec_xml, users, call_id):
- if Callids().already_handled(call_id): return ""
-
+def create_slice(api, xrn, creds, rspec_xml, users):
global topology
hrn = urn_to_hrn(xrn)[0]
topology = get_interface_map()
unlock_state_file()
- # xxx - should return altered rspec
- # with enough data for the client to understand what's happened
- return rspec_xml
+ return True
def rspec_to_allocations(rspec):
ifs = []
# Bad RSpec
pass
return ifs
+ # xxx - fixme
+ (ret, output) = call_am_apiclient("GetResourceTopology", ['all', slice_id,], 5)
+ # parse output into rspec XML
+ if output.find("No resouce found") > 0:
+ rspec = "<RSpec type=\"SFA\"> <Fault>No resource found</Fault> </RSpec>"
+ else:
+ comp_rspec = get_xml_by_tag(output, 'computeResource')
+ sfa_logger().debug("#### computeResource %s" % comp_rspec)
+ topo_rspec = get_xml_by_tag(output, 'topology')
+ sfa_logger().debug("#### topology %s" % topo_rspec)
+ rspec = "<RSpec type=\"SFA\"> <network name=\"" + Config().get_interface_hrn() + "\">";
+ if comp_rspec != None:
+ rspec = rspec + get_xml_by_tag(output, 'computeResource')
+ if topo_rspec != None:
+ rspec = rspec + get_xml_by_tag(output, 'topology')
+ rspec = rspec + "</network> </RSpec>"
+
+ return (rspec)
+
+def start_slice(api, xrn, cred):
+ # service not supported
+ return None
+
+def stop_slice(api, xrn, cred):
+ # service not supported
+ return None
+
+def reset_slices(api, xrn):
+ # service not supported
+ 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():
t = get_interface_map()
+ api = SfaAPI()
r = RSpec()
rspec_xml = open(sys.argv[1]).read()
- #ListResources(None,'foo')
- CreateSliver(None, "plc.princeton.sap0", rspec_xml, 'call-id-sap0')
+ #get_rspec(None,'foo')
+ create_slice(None, "plc.princeton.sap0", rspec_xml)
+ create_slice(api, "plc.maxpl.test000", None, rspec_xml, None)
+
if __name__ == "__main__":
main()