X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sfa%2Fmanagers%2Faggregate_manager_pl.py;h=0dd236ce5ae6f9a49ad344d247d80ff625e81720;hb=a13cf328d09aad13f97a4b0ae1eae864ba40ef6d;hp=437dd1515cdfecc998c4a0614252f9740445ee76;hpb=f2a4ff047199d94add5e2240b952851e5a04445a;p=sfa.git diff --git a/sfa/managers/aggregate_manager_pl.py b/sfa/managers/aggregate_manager_pl.py index 437dd151..0dd236ce 100644 --- a/sfa/managers/aggregate_manager_pl.py +++ b/sfa/managers/aggregate_manager_pl.py @@ -1,3 +1,5 @@ + + import datetime import time import traceback @@ -22,19 +24,25 @@ from sfa.plc.api import SfaAPI from sfa.plc.aggregate import Aggregate from sfa.plc.slices import * from sfa.util.version import version_core -from sfa.rspecs.rspec_version import RSpecVersion +from sfa.rspecs.rspec_version import RSpecVersion +from sfa.rspecs.sfa_rspec import sfa_rspec_version +from sfa.rspecs.pg_rspec import pg_rspec_ad_version, pg_rspec_request_version +from sfa.rspecs.rspec_parser import parse_rspec from sfa.util.sfatime import utcparse from sfa.util.callids import Callids def GetVersion(api): xrn=Xrn(api.hrn) - return version_core({'interface':'aggregate', - 'testbed':'myplc', - 'hrn':xrn.get_hrn(), - 'input_rspec' : ['PG 2', 'SFA 1'], - 'output_rspec' : ["SFA 1"], - 'ad_rspec' : ["PG 2", "SFA 1"], - }) + request_rspec_versions = [dict(pg_rspec_request_version), dict(sfa_rspec_version)] + ad_rspec_versions = [dict(pg_rspec_ad_version), dict(sfa_rspec_version)] + 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 __get_registry_objects(slice_xrn, creds, users): """ @@ -71,6 +79,7 @@ def __get_registry_objects(slice_xrn, creds, users): slice = {} + # get_expiration always returns a normalized datetime - no need to utcparse extime = Credential(string=creds[0]).get_expiration() # If the expiration time is > 60 days from now, set the expiration time to 60 days from now if extime > datetime.datetime.utcnow() + datetime.timedelta(days=60): @@ -110,7 +119,7 @@ def SliverStatus(api, slice_xrn, creds, call_id): slices = api.plshell.GetSlices(api.plauth, [slicename], ['node_ids','person_ids','name','expires']) if len(slices) == 0: - raise Exception("Slice %s not found (used %s as slicename internally)" % slice_xrn, slicename) + raise Exception("Slice %s not found (used %s as slicename internally)" % (slice_xrn, slicename)) slice = slices[0] # report about the local nodes only @@ -154,7 +163,7 @@ def SliverStatus(api, slice_xrn, creds, call_id): # XX remove me return result -def CreateSliver(api, slice_xrn, creds, rspec, users, call_id): +def CreateSliver(api, slice_xrn, creds, rspec_string, users, call_id): """ Create the sliver[s] (slice) at this aggregate. Verify HRN and initialize the slice record in PLC if necessary. @@ -165,6 +174,7 @@ def CreateSliver(api, slice_xrn, creds, rspec, users, call_id): (hrn, type) = urn_to_hrn(slice_xrn) peer = None + aggregate = Aggregate(api) slices = Slices(api) peer = slices.get_peer(hrn) sfa_peer = slices.get_sfa_peer(hrn) @@ -173,40 +183,67 @@ def CreateSliver(api, slice_xrn, creds, rspec, users, call_id): (site_id, remote_site_id) = slices.verify_site(registry, credential, hrn, peer, sfa_peer, reg_objects) - slice_record = slices.verify_slice(registry, credential, hrn, site_id, + slice = slices.verify_slice(registry, credential, hrn, site_id, remote_site_id, peer, sfa_peer, reg_objects) - network = Network(api) - - slice = network.get_slice(api, hrn) - slice.peer_id = slice_record['peer_slice_id'] - current = __get_hostnames(slice.get_nodes()) - - network.addRSpec(rspec, api.config.SFA_AGGREGATE_RSPEC_SCHEMA) - request = __get_hostnames(network.nodesWithSlivers()) - + nodes = api.plshell.GetNodes(api.plauth, slice['node_ids'], ['hostname']) + current_slivers = [node['hostname'] for node in nodes] + rspec = parse_rspec(rspec_string) + requested_slivers = [str(host) for host in rspec.get_nodes_with_slivers()] # remove nodes not in rspec - deleted_nodes = list(set(current).difference(request)) + deleted_nodes = list(set(current_slivers).difference(requested_slivers)) # add nodes from rspec - added_nodes = list(set(request).difference(current)) - + added_nodes = list(set(requested_slivers).difference(current_slivers)) + + # get sliver attributes + requested_slice_attributes = rspec.get_slice_attributes() + removed_slice_attributes = [] + existing_slice_attributes = [] + for slice_tag in api.plshell.GetSliceTags(api.plauth, {'slice_id': slice['slice_id']}): + attribute_found=False + for requested_attribute in requested_slice_attributes: + if requested_attribute['name'] == slice_tag['tagname'] and \ + requested_attribute['value'] == slice_tag['value']: + attribute_found=True + + if not attribute_found: + removed_slice_attributes.append(slice_tag) + else: + existing_slice_attributes.append(slice_tag) + + #api.logger.debug("requested slice attributes: %s" % str(requested_slice_attributes)) + #api.logger.debug("removed slice attributes: %s" % str(removed_slice_attributes)) + #api.logger.debug("existing slice attributes: %s" % str(existing_slice_attributes)) try: if peer: - api.plshell.UnBindObjectFromPeer(api.plauth, 'slice', slice.id, peer) - - api.plshell.AddSliceToNodes(api.plauth, slice.name, added_nodes) - api.plshell.DeleteSliceFromNodes(api.plauth, slice.name, deleted_nodes) + api.plshell.UnBindObjectFromPeer(api.plauth, 'slice', slice['slice_id'], peer) - network.updateSliceTags() + api.plshell.AddSliceToNodes(api.plauth, slice['name'], added_nodes) + api.plshell.DeleteSliceFromNodes(api.plauth, slice['name'], deleted_nodes) + # remove stale attributes + for attribute in removed_slice_attributes: + try: + api.plshell.DeleteSliceTag(api.plauth, attribute['slice_tag_id']) + except Exception, e: + api.logger.warn('Failed to remove sliver attribute. name: %s, value: %s, node_id: %s\nCause:%s'\ + % (name, value, node_id, str(e))) + + # add requested_attributes + for attribute in requested_slice_attributes: + try: + name, value, node_id = attribute['name'], attribute['value'], attribute.get('node_id', None) + api.plshell.AddSliceTag(api.plauth, slice['name'], name, value, node_id) + except Exception, e: + api.logger.warn('Failed to add sliver attribute. name: %s, value: %s, node_id: %s\nCause:%s'\ + % (name, value, node_id, str(e))) finally: if peer: api.plshell.BindObjectToPeer(api.plauth, 'slice', slice.id, peer, slice.peer_id) - # xxx - check this holds enough data for the client to understand what's happened - return network.toxml() + return aggregate.get_rspec(slice_xrn=slice_xrn, version=rspec.version) def RenewSliver(api, xrn, creds, expiration_time, call_id): @@ -279,8 +316,8 @@ def DeleteSliver(api, xrn, creds, call_id): return 1 # xxx Thierry : caching at the aggregate level sounds wrong... -caching=True -#caching=False +#caching=True +caching=False def ListSlices(api, creds, call_id): if Callids().already_handled(call_id): return [] # look in cache first @@ -307,9 +344,13 @@ def ListResources(api, creds, options,call_id): (hrn, type) = urn_to_hrn(xrn) # get the rspec's return format from options - rspec_version = RSpecVersion(options.get('rspec_version', 'SFA 1')) - version_string = "rspec_%s_%s" % (rspec_version.format, rspec_version.version) - + rspec_version = RSpecVersion(options.get('rspec_version')) + version_string = "rspec_%s" % (rspec_version.get_version_name()) + + #panos adding the info option to the caching key (can be improved) + if options.get('info'): + version_string = version_string + "_"+options.get('info', 'default') + # look in cache first if caching and api.cache and not xrn: rspec = api.cache.get(version_string) @@ -317,16 +358,15 @@ def ListResources(api, creds, options,call_id): api.logger.info("aggregate.ListResources: returning cached value for hrn %s"%hrn) return rspec - aggregate = Aggregate(api) + #aggregate = Aggregate(api) + #panos: passing user-defined options + #print "manager options = ",options + aggregate = Aggregate(api, options) + + rspec = aggregate.get_rspec(slice_xrn=xrn, version=rspec_version) - if xrn: - # get this rspec for the specified slice - rspec = aggregate.get_rspec(slice_xrn=hrn, version=rspec_version) - else: - # generate rspec in both pg and sfa formats - rspec = aggregate.get_rspec(version=rspec_version) # cache the result - if caching and api.cache: + if caching and api.cache and not xrn: api.cache.add(version_string, rspec) return rspec