-#!/usr/bin/python
-
from sfa.util.rspec import RSpec
import sys
import pdb
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 *
import xml.dom.minidom
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):
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 get_rspec(api, hrn):
+def get_rspec(api, creds, options):
+ # get slice's hrn from options
+ 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 create_slice(api, hrn, rspec_xml):
+def create_slice(api, xrn, creds, rspec_xml, users):
global topology
+ hrn = urn_to_hrn(xrn)[0]
topology = get_interface_map()
# Check if everything in rspec is either allocated by hrn
# 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()
#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()