X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=sfa%2Fmanagers%2Faggregate_manager_max.py;h=9565b9def37e535782a00a7c398f1327dc73f042;hb=dc0973b11175e64d30e2c76500d6c01ee822e8da;hp=36afd11c8cd559bdbd0077c67e9e8c83eeee7cf3;hpb=3eea82897aba845da0d12c1ba56012e599f58853;p=sfa.git diff --git a/sfa/managers/aggregate_manager_max.py b/sfa/managers/aggregate_manager_max.py index 36afd11c..9565b9de 100644 --- a/sfa/managers/aggregate_manager_max.py +++ b/sfa/managers/aggregate_manager_max.py @@ -1,13 +1,26 @@ -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 +import os +import time +import re + +from sfa.util.faults import * from sfa.util.sfalogging import logger from sfa.util.config import Config -from sfa.managers.aggregate_manager_pl import GetVersion, __get_registry_objects +from sfa.util.sfatime import utcparse +from sfa.util.callids import Callids +from sfa.util.version import version_core +from sfa.util.xrn import urn_to_hrn, hrn_to_urn, get_authority, Xrn +from sfa.util.plxrn import hrn_to_pl_slicename + +from sfa.server.sfaapi import SfaApi +from sfa.server.registry import Registries +from sfa.rspecs.rspec_version import RSpecVersion +from sfa.rspecs.sfa_rspec import sfa_rspec_version +from sfa.rspecs.rspec_parser import parse_rspec + +from sfa.managers.aggregate_manager import _get_registry_objects, ListSlices + from sfa.plc.slices import Slices -import os -import time + RSPEC_TMP_FILE_PREFIX = "/tmp/max_rspec" @@ -39,6 +52,8 @@ def call_am_apiclient(client_app, params, timeout): 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) logger.debug("shell_execute cmd: %s returns %s" % (sys_cmd, ret)) + return 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" @@ -47,17 +62,19 @@ def save_rspec_to_file(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) +# get stripped down slice id/name plc.maxpl.xislice1 --> maxpl_xislice1 +def get_plc_slice_id(cred, xrn): + (hrn, type) = urn_to_hrn(xrn) + slice_id = hrn.find(':') + sep = '.' + if hrn.find(':') != -1: + sep=':' + elif hrn.find('+') != -1: + sep='+' + else: + sep='.' + slice_id = hrn.split(sep)[-2] + '_' + hrn.split(sep)[-1] + return slice_id # extract xml def get_xml_by_tag(text, tag): @@ -68,16 +85,75 @@ def get_xml_by_tag(text, tag): xml = text[indx1:indx2+len(tag)+2] return xml -def prepare_slice(api, xrn, users): - reg_objects = __get_registry_objects(slice_xrn, creds, users) +def prepare_slice(api, slice_xrn, creds, 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) + slice_record=None + if users: + slice_record = users[0].get('slice_record', {}) 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) + # ensure site record exists + site = slices.verify_site(hrn, slice_record, peer, sfa_peer) + # ensure slice record exists + slice = slices.verify_slice(hrn, slice_record, peer, sfa_peer) + # ensure person records exists + persons = slices.verify_persons(hrn, slice, users, peer, sfa_peer) + +def parse_resources(text, slice_xrn): + resources = [] + urn = hrn_to_urn(slice_xrn, 'sliver') + plc_slice = re.search("Slice Status => ([^\n]+)", text) + if plc_slice.group(1) != 'NONE': + res = {} + res['geni_urn'] = urn + '_plc_slice' + res['geni_error'] = '' + res['geni_status'] = 'unknown' + if plc_slice.group(1) == 'CREATED': + res['geni_status'] = 'ready' + resources.append(res) + vlans = re.findall("GRI => ([^\n]+)\n\t Status => ([^\n]+)", text) + for vlan in vlans: + res = {} + res['geni_error'] = '' + res['geni_urn'] = urn + '_vlan_' + vlan[0] + if vlan[1] == 'ACTIVE': + res['geni_status'] = 'ready' + elif vlan[1] == 'FAILED': + res['geni_status'] = 'failed' + else: + res['geni_status'] = 'configuring' + resources.append(res) + return resources + +def slice_status(api, slice_xrn, creds): + urn = hrn_to_urn(slice_xrn, 'slice') + result = {} + top_level_status = 'unknown' + slice_id = get_plc_slice_id(creds, urn) + (ret, output) = call_am_apiclient("QuerySliceNetworkClient", [slice_id,], 5) + # parse output into rspec XML + if output.find("Unkown Rspec:") > 0: + top_level_staus = 'failed' + result['geni_resources'] = '' + else: + has_failure = 0 + all_active = 0 + if output.find("Status => FAILED") > 0: + top_level_staus = 'failed' + elif ( output.find("Status => ACCEPTED") > 0 or output.find("Status => PENDING") > 0 + or output.find("Status => INSETUP") > 0 or output.find("Status => INCREATE") > 0 + ): + top_level_status = 'configuring' + else: + top_level_status = 'ready' + result['geni_resources'] = parse_resources(output, slice_xrn) + result['geni_urn'] = urn + result['geni_status'] = top_level_status + return result def create_slice(api, xrn, cred, rspec, users): indx1 = rspec.find(" -1 and indx2 > indx1: rspec = rspec[indx1+len(""):indx2-1] rspec_path = save_rspec_to_file(rspec) - prepare_slice(api, xrn, users) + prepare_slice(api, xrn, cred, users) + slice_id = get_plc_slice_id(cred, xrn) + sys_cmd = "sed -i \"s/rspec id=\\\"[^\\\"]*/rspec id=\\\"" +slice_id+ "/g\" " + rspec_path + ";sed -i \"s/:rspec=[^:'<\\\" ]*/:rspec=" +slice_id+ "/g\" " + rspec_path + ret = shell_execute(sys_cmd, 1) + sys_cmd = "sed -i \"s/rspec id=\\\"[^\\\"]*/rspec id=\\\"" + rspec_path + "/g\"" + ret = shell_execute(sys_cmd, 1) (ret, output) = call_am_apiclient("CreateSliceNetworkClient", [rspec_path,], 3) # parse output ? rspec = " Done! " + return True + def delete_slice(api, xrn, cred): - slice_id = get_short_slice_id(cred, xrn) + slice_id = get_plc_slice_id(cred, xrn) (ret, output) = call_am_apiclient("DeleteSliceNetworkClient", [slice_id,], 3) # parse output ? -def get_rspec(api, cred, options): + return 1 + + +def get_rspec(api, cred, slice_urn): + logger.debug("#### called max-get_rspec") #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: + if slice_urn == None: (ret, output) = call_am_apiclient("GetResourceTopology", ['all', '\"\"'], 5) + else: + slice_id = get_plc_slice_id(cred, slice_urn) (ret, output) = call_am_apiclient("GetResourceTopology", ['all', slice_id,], 5) # parse output into rspec XML if output.find("No resouce found") > 0: @@ -114,7 +201,6 @@ def get_rspec(api, cred, options): if topo_rspec != None: rspec = rspec + get_xml_by_tag(output, 'topology') rspec = rspec + " " - return (rspec) def start_slice(api, xrn, cred): @@ -130,13 +216,55 @@ def reset_slices(api, xrn): 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. + GENI AM API Methods """ + +def GetVersion(api): + xrn=Xrn(api.hrn) + request_rspec_versions = [dict(sfa_rspec_version)] + ad_rspec_versions = [dict(sfa_rspec_version)] + #TODO: MAX-AM specific + version_more = {'interface':'aggregate', + 'testbed':'myplc', + 'hrn':xrn.get_hrn(), + 'request_rspec_versions': request_rspec_versions, + 'ad_rspec_versions': ad_rspec_versions, + 'default_ad_rspec': dict(sfa_rspec_version) + } + return version_core(version_more) + +def SliverStatus(api, slice_xrn, creds, call_id): + if Callids().already_handled(call_id): return {} + return slice_status(api, slice_xrn, creds) + +def CreateSliver(api, slice_xrn, creds, rspec_string, users, call_id): + if Callids().already_handled(call_id): return "" + #TODO: create real CreateSliver response rspec + ret = create_slice(api, slice_xrn, creds, rspec_string, users) + if ret: + return get_rspec(api, creds, slice_xrn) + else: + return " Error! " + +def DeleteSliver(api, xrn, creds, call_id): + if Callids().already_handled(call_id): return "" + return delete_slice(api, xrn, creds) + +# no caching +def ListResources(api, creds, options,call_id): + if Callids().already_handled(call_id): return "" + # version_string = "rspec_%s" % (rspec_version.get_version_name()) + slice_urn = options.get('geni_slice_urn') + return get_rspec(api, creds, slice_urn) + def fetch_context(slice_hrn, user_hrn, contexts): + """ + 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. + """ base_context = {'sfa':{'user':{'hrn':user_hrn}}} return base_context - api = SfaAPI() + api = SfaApi() create_slice(api, "plc.maxpl.test000", None, rspec_xml, None)