def list_resources(self, client_cert, credentials, geni_available): """Documentation see [geniv3rpc] GENIv3DelegateBase.""" if self._verify_users: client_urn, client_uuid, client_email =\ self.auth(client_cert, credentials, None, ("listslices",)) logger.info("Client urn=%s, uuid=%s, email=%s" % ( client_urn, client_uuid, client_email, )) logger.info("geni_available=%s", geni_available) sl = "http://www.geni.net/resources/rspec/3/ad.xsd" rspec = SERMv3AdvertisementFormatter(schema_location=sl) links = self.SEResources.get_links_dict_for_rspec(geni_available) nodes = self.SEResources.get_nodes_dict_for_rspec(geni_available) try: logger.debug("SE resources: se-links") for l in links: logger.debug("SE-LINK=%s" % l) rspec.link(l) logger.debug("SE resources: se-node") for n in nodes: logger.debug("SE-NODE=%s" % n) rspec.node(n) except Exception as e: raise geni_ex.GENIv3GeneralError(str(e)) logger.debug("SEAdvertisementFormatter=%s" % (rspec, )) self.__validate_rspec(rspec.get_rspec()) return "%s" % rspec
def list_resources(self, client_cert, credentials, geni_available, inner_call=False): """Overwrite by AM developer. Shall return an RSpec version 3 (advertisement) or raise an GENIv3...Error. If {geni_available} is set, only return availabe resources. For full description see http://groups.geni.net/geni/wiki/ GAPI_AM_API_V3#ListResources""" raise exceptions.GENIv3GeneralError("Method not implemented yet")
def shutdown(self, slice_urn, client_cert, credentials): """Overwrite by AM developer. Shall return True or False or raise an GENIv3...Error. For full description see http://groups.geni.net/geni/wiki/ GAPI_AM_API_V3#Shutdown""" raise exceptions.GENIv3GeneralError("Method not implemented yet")
def find_interdomain_paths_from_stps_and_dpids(stp, dpid_constraints): # If STPs involved in the request use heterogeneous types for a given # connection (e.g. NSI and GRE), warn user and raise exception stps_gre = TNUtils.determine_stp_gre( [stp.get("src_name"), stp.get("dst_name")]) if any(stps_gre) and not all(stps_gre): e = "Mapper SDN-SE-TN: attempting to connect 2 STPs" e += " of different type (e.g. GRE and NSI)" raise geni_ex.GENIv3GeneralError(e) pathfinder_options = {} src_auth = URNUtils.get_felix_authority_from_ogf_urn( stp.get("src_name")) dst_auth = URNUtils.get_felix_authority_from_ogf_urn( stp.get("dst_name")) # Perform a loose match, based on authorities of DPIDs # (not on exact DPIDs; as those should be automatically added) pathfinder_options["of_switch_cids_check_by_auth"] = True pathfinder_options["link_type"] = stp.get("link_type") for dpid_constraint in dpid_constraints: dpid_constraint_auth = set( URNUtils.get_felix_authority_from_urn(x) for x in dpid_constraint["ids"]) # If authority of contraints (list of DPIDs) matches with those of STPs, continue if dpid_constraint_auth == set([src_auth]): pathfinder_options["src_of_switch_cids"] = dpid_constraint[ "ids"] elif dpid_constraint_auth == set([dst_auth]): pathfinder_options["dst_of_switch_cids"] = dpid_constraint[ "ids"] paths = TNUtils.find_path_stps(stp.get("src_name"), stp.get("dst_name"), \ stp.get("link_type"), pathfinder_options) return paths
def perform_operational_action(self, urns, client_cert, credentials, action, best_effort): """Overwrite by AM developer. Shall return a list of slivers of the following format or raise an GENIv3...Error: [{'geni_sliver_urn' : String, 'geni_allocation_status' : one of the ALLOCATION_STATE_xxx, 'geni_operational_status' : one of the OPERATIONAL_STATE_xxx, 'exceptionspires' : Python-Date, 'geni_error' : optional String}, ...] {urns} contains a list of slice or sliver identifiers (e.g. ['urn:publicid:IDN+ofelia:eict:gcf+slice+myslice']). {action} an arbitraty string, but the following should be possible: "geni_start", "geni_stop", "geni_restart" {best_effort} determines if the method shall fail in case that not all of the urns can be changed (best_effort=False) If the transactional behaviour of {best_effort}=False can not be provided, throw a GENIv3OperationUnsupportedError. For more information on possible {urns} see http://groups.geni.net/ geni/wiki/GAPI_AM_API_V3/CommonConcepts#urns For full description see http://groups.geni.net/geni/wiki/ GAPI_AM_API_V3#PerformOperationalAction""" raise exceptions.GENIv3GeneralError("Method not implemented yet")
def provision(self, urns, client_cert, credentials, best_effort, end_time, geni_users): """Overwrite by AM developer. Shall return the two following values or raise an GENIv3...Error. - a RSpec version 3 (manifest) of slivers - a list of slivers of the format: [{'geni_sliver_urn' : String, 'geni_allocation_status' : one of the ALLOCATION_STATE_xxx, 'geni_operational_status' : one of the OPERATIONAL_STATE_xxx, 'exceptionspires' : Python-Date, 'geni_error' : optional String}, ...] Please return like so: "return respecs, slivers" {urns} contains a list of slice/resource identifiers (e.g. ['urn:publicid:IDN+ofelia:eict:gcf+slice+myslice']). {best_effort} determines if the method shall fail in case that not all of the urns can be provisioned (best_effort=False) {end_time} Optional. A python datetime object which determines the desired expiry date of this provision (see http://groups.geni.net/ geni/wiki/GAPI_AM_API_V3/CommonConcepts#geni_end_time). {geni_users} is a list of the format: [ { 'urn' : ..., 'keys' : [sshkey, ...]}, ...] If the transactional behaviour of {best_effort}=False can not be provided, throw a GENIv3OperationUnsupportedError. For more information on possible {urns} see http://groups.geni.net/ geni/wiki/GAPI_AM_API_V3/CommonConcepts#urns For full description see http://groups.geni.net/geni/wiki/ GAPI_AM_API_V3#Provision""" raise exceptions.GENIv3GeneralError("Method not implemented yet")
def list_resources(self, client_cert, credentials, geni_available, inner_call=False): """ Shows a list with the slivers managed or seen by the resource manager. @param client_cert client certificate (X509) @param credentials client credential(s), provided by the ClearingHouse and generated after the certificates @param geni_available flag to describe which slivers are expected to be shown * geni_available = True : only available (non-allocated, non-provisioned) will be shown * geni_available = False : every slivers will be shown @return rspec RSpec document containing a list of the slivers, formatted in accordance to GENI schemas """ logger.info("geni_available=%s", geni_available) logger.info("inner_call=%s", inner_call) sl = "http://www.geni.net/resources/rspec/3/ad.xsd" rspec = ROAdvertisementFormatter(schema_location=sl) try: rspec = ROUtils.generate_list_resources(rspec, \ geni_available, self._interdomain_available_to_user, inner_call) except Exception as e: raise geni_ex.GENIv3GeneralError(str(e)) logger.debug("ROAdvertisementFormatter=%s" % (rspec, )) CommonUtils.validate_rspec(rspec.get_rspec()) return "%s" % rspec
def describe(self, urns, client_cert, credentials): """Overwrite by AM developer. Shall return an RSpec version 3 (manifest) or raise an GENIv3...Error. {urns} contains a list of slice identifiers (e.g. ['urn:publicid:IDN+ofelia:eict:gcf+slice+myslice']). For more information on possible {urns} see http://groups.geni.net/geni/wiki/GAPI_AM_API_V3/CommonConcepts#urns For full description see http://groups.geni.net/geni/wiki/GAPI_AM_API_V3#Describe""" raise exceptions.GENIv3GeneralError("Method not implemented yet")
def delete(self, urns, client_cert, credentials, best_effort): ### FIX the response """Documentation see [geniv3rpc] GENIv3DelegateBase.""" result = [] slice_urn = urns[0] # try: for urn in urns: if self._verify_users: logger.debug("delete: authenticate the user for %s" % (urn)) client_urn, client_uuid, client_email =\ self.auth(client_cert, credentials, urn, ("deletesliver",)) logger.info("Client urn=%s, uuid=%s, email=%s" % ( client_urn, client_uuid, client_email, )) try: links_db, nodes, links = self.SESlices.get_link_db(urn) except Exception as e: raise geni_ex.GENIv3GeneralError("Slice does not exist.") reservation_ports = self.SESlices._allocate_ports_in_slice( nodes)["ports"] portsVlansPairs = getPortsVlansPairs(links_db) try: for portVlanItem in portsVlansPairs: (in_port, out_port, in_vlan, out_vlan) = portVlanItem se_provision.deleteSwitchingRule(in_port, out_port, in_vlan, out_vlan) logger.debug( "unprovision SE-Slice-Urn=%s, in_port=%s , out_port=%s, in_vlan=%s, out_port=%s" % (urn, in_port, out_port, in_vlan, out_vlan)) except: logger.warning("Problem in communication with SE") # expires_date = datetime.strptime(links_db['geni_expires'], RFC3339_FORMAT_STRING) expires_date = links_db['geni_expires'] for sliver in links_db["geni_sliver_urn"]: result.append({ "geni_sliver_urn": sliver, "geni_expires": expires_date, "geni_allocation_status": "geni_unallocated", "geni_operational_status": "geni_notready" }) # Mark resources as free self.SEResources.free_resource_reservation(reservation_ports) # Remove reservation self.SESlices.remove_link_db(urn) logger.info("delete successfully completed: %s", slice_urn) return result
def __validate_credentials(self, credentials): if self._verify_users: try: # Obtain the name of the method calling this one method_name = inspect.stack()[1][3] # Permissiosn for the calling method will be properly verified against creds self.__credential_manager.validate_for(method_name, credentials) except Exception as e: raise geni_ex.GENIv3GeneralError(str(e))
def find_path_stps(src_stp, dst_stp, link_type, options): # If STPs involved in the request use consist of heterogeneous # types (e.g. NSI and GRE), warn user and raise exception stps_gre = TNUtils.determine_stp_gre([src_stp, dst_stp]) if any(stps_gre) and not all(stps_gre): e = "Mapper SDN-SE-TN: attempting to connect 2 STPs" e += " of different type (e.g. GRE and NSI)" raise geni_ex.GENIv3GeneralError(e) if "link_type" not in options: options["link_type"] = link_type path_finder_tn_sdn = PathFinderTNtoSDN(src_stp, dst_stp, **options) paths = path_finder_tn_sdn.find_paths() if len(paths) == 0: e = "Mapper SDN-SE-TN: cannot map inter-domain" e += " links for STPs provided. Possible causes:" e += " STPs cannot be connected or are located" e += " in the same island" raise geni_ex.GENIv3GeneralError(e) logger.debug("Found proper inter-domain paths=%s" % (paths, )) return paths
def shutdown(self, slice_urn, client_cert, credentials): """Documentation see [geniv3rpc] GENIv3DelegateBase.""" if self._verify_users: logger.debug("shutdown: authenticate the user...") client_urn, client_uuid, client_email =\ self.auth(client_cert, credentials, slice_urn, ("shutdown",)) logger.info("Client urn=%s, uuid=%s, email=%s" % ( client_urn, client_uuid, client_email,)) logger.info("slice_urn=%s" % (slice_urn,)) raise geni_ex.GENIv3GeneralError("Not implemented yet!")
def validate_rspec(rspec): """ Given an RSpec (XML structure), this method validates the structure of the document, according to the GENI resource schemas. @param rspec RSpec defining resources @throws GENIv3GeneralError when RSpec format is invalid """ (result, error) = validate(rspec) if result is not True: m = "RSpec validation failure: %s" % (error, ) raise geni_ex.GENIv3GeneralError(m) logger.info("Validation success!")
def status(self, urns, client_cert, credentials): """Overwrite by AM developer. Shall return the two following values or raise an GENIv3...Error. - a slice urn - a list of slivers of the format: [{'geni_sliver_urn' : String, 'geni_allocation_status' : one of the ALLOCATION_STATE_xxx, 'geni_operational_status' : one of the OPERATIONAL_STATE_xxx, 'exceptionspires' : Python-Date, 'geni_error' : optional String}, ...] Please return like so: "return slice_urn, slivers" {urns} contains a list of slice/resource identifiers (e.g. ['urn:publicid:IDN+ofelia:eict:gcf+slice+myslice']). For more information on possible {urns} see http://groups.geni.net/geni/wiki/GAPI_AM_API_V3/CommonConcepts#urns For full description see http://groups.geni.net/geni/wiki/GAPI_AM_API_V3#Status""" raise exceptions.GENIv3GeneralError("Method not implemented yet")
def allocate(self, slice_urn, client_cert, credentials, rspec, end_time=None): """Overwrite by AM developer. Shall return the two following values or raise an GENIv3...Error. - a RSpec version 3 (manifest) of newly allocated slivers - a list of slivers of the format: [{'geni_sliver_urn' : String, 'exceptionspires' : Python-Date, 'geni_allocation_status' : one of the ALLOCATION_STATE_xxx}, ...] Please return like so: "return respecs, slivers" {slice_urn} contains a slice identifier (e.g. 'urn:publicid:IDN+ofelia:eict:gcf+slice+myslice'). {end_time} Optional. A python datetime object which determines the desired expiry date of this allocation (see http://groups.geni.net/geni/wiki/GAPI_AM_API_V3/CommonConcepts#geni_end_time). >>> This is the first part of what CreateSliver used to do in previous versions of the AM API. The second part is now done by Provision, and the final part is done by PerformOperationalAction. For full description see http://groups.geni.net/geni/wiki/GAPI_AM_API_V3#Allocate""" raise exceptions.GENIv3GeneralError("Method not implemented yet")
def allocate(self, slice_urn, client_cert, credentials, rspec, end_time=None): """Documentation see [geniv3rpc] GENIv3DelegateBase.""" # TODO: Check if sliver_urn is valid for RO result = [] #Default end time = 30 days default_end_time = datetime.now() + timedelta(days=30) if end_time == None: end_time = default_end_time if self._verify_users: logger.debug("allocate: authenticate the user...") client_urn, client_uuid, client_email =\ self.auth(client_cert, credentials, slice_urn, ("createsliver",)) logger.info("Client urn=%s, uuid=%s, email=%s" % ( client_urn, client_uuid, client_email, )) logger.info("slice_urn=%s, end_time=%s, rspec=%s" % ( slice_urn, end_time, rspec, )) req_rspec = SERMv3RequestParser(from_string=rspec) self.__validate_rspec(req_rspec.get_rspec()) se_manifest, se_slivers, se_db_slivers = SERMv3ManifestFormatter( ), [], [] links = req_rspec.links() nodes = req_rspec.nodes() # Workaround for "1:n" case: Get Vlan pairs from link->felix:vlan param sliceVlansPairs = req_rspec.getVlanPairs() # check if the requested resources (ports, vlans) are available reservation_ports = self.SESlices._allocate_ports_in_slice(nodes) availability_result = self.SEResources.check_available_resources( reservation_ports['ports']) # print "WWWW: ", self.SEResources.get_port_mapping() if availability_result != False: # Mark resources as reserved self.SEResources.set_resource_reservation( reservation_ports['ports']) if end_time != None: alarm_time = end_time SESchedulerService.get_scheduler().add_job( se_job_release_resources, "date", run_date=alarm_time, args=[ datetime.now(), reservation_ports['ports'], slice_urn ]) self.SESlices._create_manifest_from_req_n_and_l( se_manifest, nodes, links, sliceVlansPairs) logger.debug("SE-ManifestFormatter=%s" % (se_manifest, )) s = self.SESlices._allocate_ports_in_slice(nodes) self.SESlices.set_link_db(slice_urn, end_time, links, nodes, sliceVlansPairs) links_db, nodes, links = self.SESlices.get_link_db(slice_urn) for sliver in links_db["geni_sliver_urn"]: result.append({ "geni_sliver_urn": sliver, "geni_expires": links_db['geni_expires'], "geni_allocation_status": links_db["geni_allocation_status"], "geni_operational_status": links_db["geni_operational_status"] }) se_slivers = result logger.info("allocate successfully completed: %s", slice_urn) logger.debug("requested SE-Sliver(%d)=%s" % ( len(se_slivers), se_slivers, )) return ("%s" % se_manifest, se_slivers) else: raise geni_ex.GENIv3GeneralError( "Allocation Failed. Requested resources are not available.")
def __insert_allocated_reraise_exc(self, rtype, e, ro_db_slivers): logger.error("AllocationError: %s" % (e.details())) # Save here the already allocated resources! self.__insert_slice_info(rtype, e.slice_urn, e.db_ids, ro_db_slivers) # Raise an exception to break the code! raise geni_ex.GENIv3GeneralError(str(e))
def shutdown(self, slice_urn, client_cert, credentials): """Documentation see [geniv3rpc] GENIv3DelegateBase.""" logger.info("slice_urn=%s" % (slice_urn, )) raise geni_ex.GENIv3GeneralError("Not implemented yet!")
def __validate_rspec(self, generic_rspec): (result, error) = validate(generic_rspec) if result is not True: raise geni_ex.GENIv3GeneralError("RSpec validation failure: %s" % (error, )) logger.info("Validation success!")
def perform_operational_action(self, urns, client_cert, credentials, action, best_effort): result = [] status = "" for urn in urns: if self._verify_users: ### TODO: Fix authentication logger.debug("status: authenticate the user for %s" % (urn)) client_urn, client_uuid, client_email =\ self.auth(client_cert, credentials, urn, ("sliverstatus",)) logger.info("Client urn=%s, uuid=%s, email=%s" % ( client_urn, client_uuid, client_email, )) links_db, nodes, links = self.SESlices.get_link_db(urn) expires_date = links_db['geni_expires'] # reservation_ports = self.SESlices._allocate_ports_in_slice(nodes)["ports"] portsVlansPairs = getPortsVlansPairs(links_db) error_communication_msg = "Error in communication with SE. Details:" if action == "geni_start": for portVlanItem in portsVlansPairs: (in_port, out_port, in_vlan, out_vlan) = portVlanItem try: se_provision.addSwitchingRule(in_port, out_port, in_vlan, out_vlan) except Exception as e: # Note: this exception may block the workflow, even in # the case of an apparent lack of error raise geni_ex.GENIv3GeneralError( "%s: %s" % (error_communication_msg, e)) logger.debug("Cross-connection added: %s[%s]<->%s[%s]" % (in_port, in_vlan, out_port, out_vlan)) # Retrieve allocation status and modify after the method's operation links_db, _, _ = self.__update_fetch_allocation_status_slivers( urn, "geni_provisioned") links_db, _, _ = self.__update_fetch_operational_status_slivers( urn, "geni_ready") elif action == "geni_stop": for portVlanItem in portsVlansPairs: (in_port, out_port, in_vlan, out_vlan) = portVlanItem try: se_provision.deleteSwitchingRule( in_port, out_port, in_vlan, out_vlan) except Exception as e: # Note: this exception may block the workflow, even in # the case of an apparent lack of error raise geni_ex.GENIv3GeneralError( "%s: %s" % (error_communication_msg, e)) logger.debug("Cross-connection deleted: %s[%s]<->%s[%s]" % (in_port, in_vlan, out_port, out_vlan)) # Retrieve allocation status and modify after the method's operation links_db, _, _ = self.__update_fetch_allocation_status_slivers( urn, "geni_provisioned") links_db, _, _ = self.__update_fetch_operational_status_slivers( urn, "geni_notready") elif action == "geni_restart": for portVlanItem in portsVlansPairs: (in_port, out_port, in_vlan, out_vlan) = portVlanItem try: se_provision.deleteSwitchingRule( in_port, out_port, in_vlan, out_vlan) se_provision.addSwitchingRule(in_port, out_port, in_vlan, out_vlan) except Exception as e: # Note: this exception may block the workflow, even in # the case of an apparent lack of error raise geni_ex.GENIv3GeneralError( "%s: %s" % (error_communication_msg, e)) # Retrieve allocation status and modify after the method's operation links_db, _, _ = self.__update_fetch_allocation_status_slivers( urn, "geni_provisioned") links_db, _, _ = self.__update_fetch_operational_status_slivers( urn, "geni_ready") for sliver in links_db["geni_sliver_urn"]: result.append({ "geni_sliver_urn": sliver, "geni_expires": expires_date, "geni_allocation_status": links_db["geni_allocation_status"], "geni_operational_status": links_db["geni_operational_status"], }) return result