-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.rspec import RSpec
-from sfa.util.sfalogging import sfa_logger
-from sfa.util.config import Config
-from sfa.managers.aggregate_manager_pl import GetVersion, __get_registry_objects
-from sfa.plc.slices import Slices
-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))
-# 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 prepare_slice(api, xrn, users):
- reg_objects = __get_registry_objects(slice_xrn, creds, users)
- (hrn, type) = urn_to_hrn(slice_xrn)
- slices = Slices(api)
- peer = slices.get_peer(hrn)
- sfa_peer = slices.get_sfa_peer(hrn)
- registry = api.registries[api.hrn]
- credential = api.getCredential()
- (site_id, remote_site_id) = slices.verify_site(registry, credential, hrn, peer, sfa_peer, reg_objects)
- slices.verify_slice(registry, credential, hrn, site_id, remote_site_id, peer, sfa_peer, reg_objects)
-
-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)
- prepare_slice(api, xrn, users)
- (ret, output) = call_am_apiclient("CreateSliceNetworkClient", [rspec_path,], 3)
- # parse output ?
- rspec = "<RSpec type=\"SFA\"> Done! </RSpec>"
-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 ?
-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)
- (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
- api = SfaAPI()
- create_slice(api, "plc.maxpl.test000", None, rspec_xml, None)
-
+from sfa.plc.slices import Slices\r
+from sfa.server.registry import Registries\r
+from sfa.util.xrn import urn_to_hrn, hrn_to_urn, get_authority, Xrn\r
+from sfa.util.plxrn import hrn_to_pl_slicename\r
+from sfa.util.sfalogging import logger\r
+from sfa.util.faults import *\r
+from sfa.util.config import Config\r
+from sfa.util.sfatime import utcparse\r
+from sfa.util.callids import Callids\r
+from sfa.util.version import version_core\r
+from sfa.rspecs.rspec_version import RSpecVersion\r
+from sfa.rspecs.sfa_rspec import sfa_rspec_version\r
+from sfa.rspecs.rspec_parser import parse_rspec\r
+from sfa.managers.aggregate_manager_pl import __get_registry_objects, ListSlices\r
+import os\r
+import time\r
+import re\r
+\r
+RSPEC_TMP_FILE_PREFIX = "/tmp/max_rspec"\r
+\r
+# execute shell command and return both exit code and text output\r
+def shell_execute(cmd, timeout):\r
+ pipe = os.popen('{ ' + cmd + '; } 2>&1', 'r')\r
+ pipe = os.popen(cmd + ' 2>&1', 'r')\r
+ text = ''\r
+ while timeout:\r
+ line = pipe.read()\r
+ text += line\r
+ time.sleep(1)\r
+ timeout = timeout-1\r
+ code = pipe.close()\r
+ if code is None: code = 0\r
+ if text[-1:] == '\n': text = text[:-1]\r
+ return code, text\r
+\r
+"""\r
+ call AM API client with command like in the following example:\r
+ cd aggregate_client; java -classpath AggregateWS-client-api.jar:lib/* \\r
+ net.geni.aggregate.client.examples.CreateSliceNetworkClient \\r
+ ./repo https://geni:8443/axis2/services/AggregateGENI \\r
+ ... params ...\r
+"""\r
+\r
+def call_am_apiclient(client_app, params, timeout):\r
+ (client_path, am_url) = Config().get_max_aggrMgr_info()\r
+ sys_cmd = "cd " + client_path + "; java -classpath AggregateWS-client-api.jar:lib/* net.geni.aggregate.client.examples." + client_app + " ./repo " + am_url + " " + ' '.join(params)\r
+ ret = shell_execute(sys_cmd, timeout)\r
+ logger.debug("shell_execute cmd: %s returns %s" % (sys_cmd, ret))\r
+ return ret\r
+\r
+# save request RSpec xml content to a tmp file\r
+def save_rspec_to_file(rspec):\r
+ path = RSPEC_TMP_FILE_PREFIX + "_" + time.strftime('%Y%m%dT%H:%M:%S', time.gmtime(time.time())) +".xml"\r
+ file = open(path, "w")\r
+ file.write(rspec)\r
+ file.close()\r
+ return path\r
+\r
+# get stripped down slice id/name plc.maxpl.xislice1 --> maxpl_xislice1\r
+def get_plc_slice_id(cred, xrn):\r
+ (hrn, type) = urn_to_hrn(xrn)\r
+ slice_id = hrn.find(':')\r
+ sep = '.'\r
+ if hrn.find(':') != -1:\r
+ sep=':'\r
+ elif hrn.find('+') != -1:\r
+ sep='+'\r
+ else:\r
+ sep='.'\r
+ slice_id = hrn.split(sep)[-2] + '_' + hrn.split(sep)[-1]\r
+ return slice_id\r
+\r
+# extract xml \r
+def get_xml_by_tag(text, tag):\r
+ indx1 = text.find('<'+tag)\r
+ indx2 = text.find('/'+tag+'>')\r
+ xml = None\r
+ if indx1!=-1 and indx2>indx1:\r
+ xml = text[indx1:indx2+len(tag)+2]\r
+ return xml\r
+\r
+def prepare_slice(api, slice_xrn, creds, users):\r
+ reg_objects = __get_registry_objects(slice_xrn, creds, users)\r
+ (hrn, type) = urn_to_hrn(slice_xrn)\r
+ slices = Slices(api)\r
+ peer = slices.get_peer(hrn)\r
+ sfa_peer = slices.get_sfa_peer(hrn)\r
+ slice_record=None\r
+ if users:\r
+ slice_record = users[0].get('slice_record', {})\r
+ registry = api.registries[api.hrn]\r
+ credential = api.getCredential()\r
+ # ensure site record exists\r
+ site = slices.verify_site(hrn, slice_record, peer, sfa_peer)\r
+ # ensure slice record exists\r
+ slice = slices.verify_slice(hrn, slice_record, peer, sfa_peer)\r
+ # ensure person records exists\r
+ persons = slices.verify_persons(hrn, slice, users, peer, sfa_peer)\r
+\r
+def parse_resources(text, slice_xrn):\r
+ resources = []\r
+ urn = hrn_to_urn(slice_xrn, 'sliver')\r
+ plc_slice = re.search("Slice Status => ([^\n]+)", text)\r
+ if plc_slice.group(1) != 'NONE':\r
+ res = {}\r
+ res['geni_urn'] = urn + '_plc_slice'\r
+ res['geni_error'] = ''\r
+ res['geni_status'] = 'unknown'\r
+ if plc_slice.group(1) == 'CREATED':\r
+ res['geni_status'] = 'ready'\r
+ resources.append(res)\r
+ vlans = re.findall("GRI => ([^\n]+)\n\t Status => ([^\n]+)", text)\r
+ for vlan in vlans:\r
+ res = {}\r
+ res['geni_error'] = ''\r
+ res['geni_urn'] = urn + '_vlan_' + vlan[0]\r
+ if vlan[1] == 'ACTIVE':\r
+ res['geni_status'] = 'ready'\r
+ elif vlan[1] == 'FAILED':\r
+ res['geni_status'] = 'failed'\r
+ else:\r
+ res['geni_status'] = 'configuring'\r
+ resources.append(res)\r
+ return resources\r
+\r
+def slice_status(api, slice_xrn, creds):\r
+ urn = hrn_to_urn(slice_xrn, 'slice')\r
+ result = {}\r
+ top_level_status = 'unknown'\r
+ slice_id = get_plc_slice_id(creds, urn)\r
+ (ret, output) = call_am_apiclient("QuerySliceNetworkClient", [slice_id,], 5)\r
+ # parse output into rspec XML\r
+ if output.find("Unkown Rspec:") > 0:\r
+ top_level_staus = 'failed'\r
+ result['geni_resources'] = ''\r
+ else:\r
+ has_failure = 0\r
+ all_active = 0\r
+ if output.find("Status => FAILED") > 0:\r
+ top_level_staus = 'failed'\r
+ elif ( output.find("Status => ACCEPTED") > 0 or output.find("Status => PENDING") > 0\r
+ or output.find("Status => INSETUP") > 0 or output.find("Status => INCREATE") > 0\r
+ ):\r
+ top_level_status = 'configuring'\r
+ else:\r
+ top_level_status = 'ready'\r
+ result['geni_resources'] = parse_resources(output, slice_xrn)\r
+ result['geni_urn'] = urn\r
+ result['geni_status'] = top_level_status\r
+ return result\r
+\r
+def create_slice(api, xrn, cred, rspec, users):\r
+ indx1 = rspec.find("<RSpec")\r
+ indx2 = rspec.find("</RSpec>")\r
+ if indx1 > -1 and indx2 > indx1:\r
+ rspec = rspec[indx1+len("<RSpec type=\"SFA\">"):indx2-1]\r
+ rspec_path = save_rspec_to_file(rspec)\r
+ prepare_slice(api, xrn, cred, users)\r
+ slice_id = get_plc_slice_id(cred, xrn)\r
+ sys_cmd = "sed -i \"s/rspec id=\\\"[^\\\"]*/rspec id=\\\"" +slice_id+ "/g\" " + rspec_path + ";sed -i \"s/:rspec=[^:'<\\\" ]*/:rspec=" +slice_id+ "/g\" " + rspec_path\r
+ ret = shell_execute(sys_cmd, 1)\r
+ sys_cmd = "sed -i \"s/rspec id=\\\"[^\\\"]*/rspec id=\\\"" + rspec_path + "/g\""\r
+ ret = shell_execute(sys_cmd, 1)\r
+ (ret, output) = call_am_apiclient("CreateSliceNetworkClient", [rspec_path,], 3)\r
+ # parse output ?\r
+ rspec = "<RSpec type=\"SFA\"> Done! </RSpec>"\r
+ return True\r
+\r
+def delete_slice(api, xrn, cred):\r
+ slice_id = get_plc_slice_id(cred, xrn)\r
+ (ret, output) = call_am_apiclient("DeleteSliceNetworkClient", [slice_id,], 3)\r
+ # parse output ?\r
+ return 1\r
+\r
+\r
+def get_rspec(api, cred, slice_urn):\r
+ logger.debug("#### called max-get_rspec")\r
+ #geni_slice_urn: urn:publicid:IDN+plc:maxpl+slice+xi_rspec_test1\r
+ if slice_urn == None:\r
+ (ret, output) = call_am_apiclient("GetResourceTopology", ['all', '\"\"'], 5)\r
+ else:\r
+ slice_id = get_plc_slice_id(cred, slice_urn)\r
+ (ret, output) = call_am_apiclient("GetResourceTopology", ['all', slice_id,], 5)\r
+ # parse output into rspec XML\r
+ if output.find("No resouce found") > 0:\r
+ rspec = "<RSpec type=\"SFA\"> <Fault>No resource found</Fault> </RSpec>"\r
+ else:\r
+ comp_rspec = get_xml_by_tag(output, 'computeResource')\r
+ logger.debug("#### computeResource %s" % comp_rspec)\r
+ topo_rspec = get_xml_by_tag(output, 'topology')\r
+ logger.debug("#### topology %s" % topo_rspec)\r
+ rspec = "<RSpec type=\"SFA\"> <network name=\"" + Config().get_interface_hrn() + "\">";\r
+ if comp_rspec != None:\r
+ rspec = rspec + get_xml_by_tag(output, 'computeResource')\r
+ if topo_rspec != None:\r
+ rspec = rspec + get_xml_by_tag(output, 'topology')\r
+ rspec = rspec + "</network> </RSpec>"\r
+ return (rspec)\r
+\r
+def start_slice(api, xrn, cred):\r
+ # service not supported\r
+ return None\r
+\r
+def stop_slice(api, xrn, cred):\r
+ # service not supported\r
+ return None\r
+\r
+def reset_slices(api, xrn):\r
+ # service not supported\r
+ return None\r
+\r
+"""\r
+ GENI AM API Methods\r
+"""\r
+\r
+def GetVersion(api):\r
+ xrn=Xrn(api.hrn)\r
+ request_rspec_versions = [dict(sfa_rspec_version)]\r
+ ad_rspec_versions = [dict(sfa_rspec_version)]\r
+ #TODO: MAX-AM specific\r
+ version_more = {'interface':'aggregate',\r
+ 'testbed':'myplc',\r
+ 'hrn':xrn.get_hrn(),\r
+ 'request_rspec_versions': request_rspec_versions,\r
+ 'ad_rspec_versions': ad_rspec_versions,\r
+ 'default_ad_rspec': dict(sfa_rspec_version)\r
+ }\r
+ return version_core(version_more)\r
+\r
+def SliverStatus(api, slice_xrn, creds, call_id):\r
+ if Callids().already_handled(call_id): return {}\r
+ return slice_status(api, slice_xrn, creds)\r
+\r
+def CreateSliver(api, slice_xrn, creds, rspec_string, users, call_id):\r
+ if Callids().already_handled(call_id): return ""\r
+ #TODO: create real CreateSliver response rspec\r
+ ret = create_slice(api, slice_xrn, creds, rspec_string, users)\r
+ if ret:\r
+ return get_rspec(api, creds, slice_xrn)\r
+ else:\r
+ return "<?xml version=\"1.0\" ?> <RSpec type=\"SFA\"> Error! </RSpec>"\r
+\r
+def DeleteSliver(api, xrn, creds, call_id):\r
+ if Callids().already_handled(call_id): return ""\r
+ return delete_slice(api, xrn, creds)\r
+\r
+# no caching\r
+def ListResources(api, creds, options,call_id):\r
+ if Callids().already_handled(call_id): return ""\r
+ # version_string = "rspec_%s" % (rspec_version.get_version_name())\r
+ slice_urn = options.get('geni_slice_urn')\r
+ return get_rspec(api, creds, slice_urn)\r
+\r
+"""\r
+Returns the request context required by sfatables. At some point, this mechanism should be changed\r
+to refer to "contexts", which is the information that sfatables is requesting. But for now, we just\r
+return the basic information needed in a dict.\r
+"""\r
+def fetch_context(slice_hrn, user_hrn, contexts):\r
+ base_context = {'sfa':{'user':{'hrn':user_hrn}}}\r
+ return base_context\r
+ api = SfaAPI()\r
+ create_slice(api, "plc.maxpl.test000", None, rspec_xml, None)\r
+\r