X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sfa%2Fmanagers%2Faggregate_manager_max.py;h=64ddda9f8f361be7ac98ca5936031b43b20408d3;hb=3ede6dd1dffc8f7fe7e753da52fde28e089d9c5c;hp=5c128754352f8d3789f43525882c895828023e37;hpb=3d7237fa0b5f2b4a60cb97c7fb3b6aecfd94558a;p=sfa.git diff --git a/sfa/managers/aggregate_manager_max.py b/sfa/managers/aggregate_manager_max.py index 5c128754..64ddda9f 100644 --- a/sfa/managers/aggregate_manager_max.py +++ b/sfa/managers/aggregate_manager_max.py @@ -1,5 +1,3 @@ -#!/usr/bin/python - from sfa.util.rspec import RSpec import sys import pdb @@ -11,7 +9,12 @@ 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 * import xml.dom.minidom @@ -118,6 +121,41 @@ def collapse_alloc_dict(d): 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 @@ -131,6 +169,44 @@ def alloc_links(api, hrn, links_to_add, links_to_drop): 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("") + if indx1 > -1 and indx2 > indx1: + rspec = rspec[indx1+len(""):indx2-1] + rspec_path = save_rspec_to_file(rspec) + (ret, output) = call_am_apiclient("CreateSliceNetworkClient", [rspec_path,], 3) + # parse output ? + rspec = " Done! " return True def alloc_nodes(api,hrn, requested_ifs): @@ -245,24 +321,38 @@ def create_slice_max_aggregate(api, hrn, nodes): 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 @@ -319,13 +409,55 @@ def rspec_to_allocations(rspec): # 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 = " No resource found " + 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 = " "; + 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 + " " + + 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()