88
99from netfoundry .exceptions import NetworkBoundaryViolation , UnknownResourceType
1010
11- from .utility import (DC_PROVIDERS , MUTABLE_NET_RESOURCES , NET_RESOURCES , RESOURCES , STATUS_CODES , VALID_SEPARATORS , VALID_SERVICE_PROTOCOLS , create_generic_resource , docstring_parameters , find_generic_resources ,
12- get_generic_resource_by_url , http , is_uuidv4 , normalize_caseless , plural , singular )
11+ from .utility import (DC_PROVIDERS , MUTABLE_NET_RESOURCES , NET_RESOURCES , RESOURCES , STATUS_CODES , VALID_SEPARATORS , VALID_SERVICE_PROTOCOLS , create_generic_resource , docstring_parameters , find_generic_resources , get_generic_resource_by_type_and_id ,
12+ get_generic_resource_by_url , http , is_uuidv4 , normalize_caseless , plural , singular , wait_for_execution )
1313
1414
1515class Network :
@@ -269,9 +269,14 @@ def validate_entity_roles(self, entities: list, type: str):
269269
270270 @docstring_parameters (providers = str (DC_PROVIDERS ))
271271 def find_regions (self , ** kwargs ):
272- """Find regions for hosted router placement.
272+ """
273+ Find regions for router placement.
274+
275+ Optionally filter by provider, and optionally get exactly one region by sending both a single element for providers and a location_code
273276
274- :param provider: optionally filter by data-center region provider, choices: {providers}
277+ :param providers: optional list of providers from DC_PROVIDERS
278+ :param provider: optional string matching one provider from DC_PROVIDERS
279+ :param location_code: optional string that uniquely identifies a region for some provider
275280 """
276281 return self .Networks .find_regions (** kwargs )
277282 get_edge_router_data_centers = find_regions
@@ -309,7 +314,7 @@ def share_endpoint(self, recipient, endpoint_id):
309314 if not response_code == STATUS_CODES .codes ['ACCEPTED' ]:
310315 raise RuntimeError (f"got unexpected HTTP code { STATUS_CODES ._codes [response_code ][0 ].upper ()} ({ response_code } ) and response { response .text } " )
311316
312- def get_resource_by_id (self , type : str , id : str , accept : str = None , use_cache : bool = True ):
317+ def get_resource_by_id (self , type : str , id : str , accept : str = None , use_cache : bool = True ):
313318 """Return an object describing a resource entity.
314319
315320 :param type: required string of the singular of an entity type e.g. network, endpoint, service, edge-router, edge-router-policy, posture-check
@@ -552,7 +557,6 @@ def create_resource(self, type: str, post: dict, wait: int = 30, sleep: int = 2,
552557 :param post: required dictionary with all properties required by the particular resource type's model
553558 """
554559 type = plural (type )
555- headers = {"authorization" : "Bearer " + self .token }
556560 body = post
557561 body ['networkId' ] = self .id
558562 if body .get ('name' ):
@@ -569,9 +573,6 @@ def create_endpoint(self, name: str, attributes: list = [], session_identity: st
569573 :param: session_identity is optional string UUID of the identity in the NF organization for
570574 which a concurrent web console session is required to activate this endpoint
571575 """
572- headers = {
573- "authorization" : "Bearer " + self .token
574- }
575576 for role in attributes :
576577 if not role [0 :1 ] == '#' :
577578 raise RuntimeError ("hashtag role attributes on an endpoint must begin with #" )
@@ -587,11 +588,13 @@ def create_endpoint(self, name: str, attributes: list = [], session_identity: st
587588
588589 url = self .audience + 'core/v2/endpoints'
589590 resource = create_generic_resource (setup = self , url = url , body = body , wait = wait , sleep = sleep )
591+ # get it again without cache to ensure the JWT is defined
592+ resource , status = get_generic_resource_by_type_and_id (setup = self , resource_type = 'endpoints' , resource_id = resource ['id' ], use_cache = False )
590593 self .logger .debug (f"created endpoint { resource ['name' ]} " )
591594 return (resource )
592595
593596 @docstring_parameters (providers = str (DC_PROVIDERS ))
594- def create_edge_router (self , name : str , attributes : list = list (), link_listener : bool = False , data_center_id : str = None ,
597+ def create_edge_router (self , name : str , attributes : list = list (), link_listener : bool = False ,
595598 tunneler_enabled : bool = False , wait : int = 900 , sleep : int = 10 , progress : bool = False ,
596599 provider : str = None , location_code : str = None ):
597600 """Create an edge router.
@@ -603,15 +606,11 @@ def create_edge_router(self, name: str, attributes: list = list(), link_listener
603606 :param name: a meaningful, unique name
604607 :param attributes: a list of hashtag role attributes
605608 :param link_listener: true if router should listen for other routers' transit links on 80/tcp, always true if hosted by NetFoundry
606- :param data_center_id: (DEPRECATED by provider, location_code) the UUIDv4 of a NetFoundry data center location that can host edge routers
607609 :param provider: datacenter provider, choices: {providers}
608610 :param location_code: provider-specific string identifying the datacenter location e.g. us-west-1
609611 :param tunneler_enabled: true if the built-in tunneler features should be enabled for hosting or interception or both
610612 :param wait: seconds to wait for async create to succeed
611613 """
612- headers = {
613- "authorization" : "Bearer " + self .token
614- }
615614 for role in attributes :
616615 if not role [0 :1 ] == '#' :
617616 raise RuntimeError ("hashtag role attributes on an endpoint must begin with #" )
@@ -688,7 +687,6 @@ def create_service_simple(self, name: str, client_host_name: str, client_port: i
688687 :param: endpoints is optional list of strings of hosting endpoints. Selects endpoint-hosting strategy.
689688 :param: encryption_required is optional Boolean. Default is to enable edge-to-edge encryption.
690689 """
691- headers = {"authorization" : "Bearer " + self .token }
692690 for role in attributes :
693691 if not role [0 :1 ] == '#' :
694692 raise Exception (f'invalid role "{ role } ". Must begin with "#"' )
@@ -764,7 +762,7 @@ def create_service_simple(self, name: str, client_host_name: str, client_port: i
764762 else :
765763 # else assume is a name and resolve to ID
766764 try :
767- name_lookup = self .get_resources (type = "endpoints" , name = endpoint )[0 ]
765+ name_lookup = self .get_resources (type = "endpoints" , name = endpoint , use_cache = False )[0 ]
768766 endpoint_name = name_lookup ['name' ]
769767 except Exception as e :
770768 raise RuntimeError (f'failed to find exactly one hosting endpoint named "{ endpoint } ", caught { e } ' )
@@ -797,9 +795,6 @@ def create_service_policy(self, name: str, services: list, endpoints: list, type
797795 bind_endpoints = self .validate_entity_roles (endpoints , type = "endpoints" )
798796 valid_services = self .validate_entity_roles (services , type = "services" )
799797 valid_postures = self .validate_entity_roles (posture_checks , type = "posture-checks" )
800- headers = {
801- "authorization" : "Bearer " + self .token
802- }
803798 body = {
804799 "networkId" : self .id ,
805800 "name" : name .strip ('"' ),
@@ -830,9 +825,6 @@ def create_service_edge_router_policy(self, name: str, services: list, edge_rout
830825 """
831826 valid_services = self .validate_entity_roles (services , type = "services" )
832827 valid_routers = self .validate_entity_roles (edge_routers , type = "edge-routers" )
833- headers = {
834- "authorization" : "Bearer " + self .token
835- }
836828 body = {
837829 "networkId" : self .id ,
838830 "name" : name .strip ('"' ),
@@ -1119,17 +1111,14 @@ def create_service_advanced(self, name: str, endpoints: list, client_hosts: list
11191111 bind_endpoints .append ('@' + endpoint_name ) # is an existing endpoint's name resolved from UUID
11201112 else :
11211113 try :
1122- name_lookup = self .get_resources (type = "endpoints" , name = endpoint )[0 ]
1114+ name_lookup = self .get_resources (type = "endpoints" , name = endpoint , use_cache = False )[0 ]
11231115 endpoint_name = name_lookup ['name' ]
11241116 except Exception as e :
11251117 raise Exception ('ERROR: Failed to find exactly one hosting endpoint named "{}". Caught exception: {}' .format (endpoint , e ))
11261118 # append to list after successfully resolving name to ID
11271119 else :
11281120 bind_endpoints .append ('@' + endpoint_name ) # is an existing endpoint's name
11291121
1130- headers = {
1131- "authorization" : "Bearer " + self .token
1132- }
11331122 body = {
11341123 "networkId" : self .id ,
11351124 "name" : name ,
@@ -1167,9 +1156,6 @@ def create_app_wan(self, name: str, endpoint_attributes: list = [], service_attr
11671156 :param service_attributes: a list of service hashtag role attributes and service names
11681157 :param posture_check_attributes: a list of posture hashtag role attributes and posture names
11691158 """
1170- headers = {
1171- "authorization" : "Bearer " + self .token
1172- }
11731159 for role in endpoint_attributes + service_attributes + posture_check_attributes :
11741160 if not re .match ('^[#@]' , role ):
11751161 raise RuntimeError ("ERROR: role attributes on an AppWAN must begin with # or @" )
@@ -1550,10 +1536,10 @@ def delete_resource(self, type: str, id: str = None, wait: int = 0, sleep: int =
15501536 if wait :
15511537 if resource .get ('_links' ) and resource ['_links' ].get ('execution' ):
15521538 execution_url = resource ['_links' ].get ('execution' )['href' ]
1553- self . wait_for_statuses ( expected_statuses = RESOURCES [ "executions" ]. status_symbols [ 'complete' ], type = "executions" , id = process_id , wait = wait , sleep = sleep )
1539+ wait_for_execution ( setup = self , url = execution_url , wait = wait , sleep = sleep )
15541540 return (True )
15551541 else :
1556- self .logger .warning ("unable to wait for async complete because response did not provide a process execution id " )
1542+ self .logger .error ("unable to wait for async complete because response did not provide an execution link " )
15571543 return (False )
15581544 else :
15591545 return (True )
@@ -1649,7 +1635,6 @@ def find_regions(self, providers: list = [], provider: str = None, location_code
16491635 else :
16501636 raise RuntimeError (f"unknown cloud provider '{ provider } '. Need one of { str (DC_PROVIDERS )} " )
16511637
1652-
16531638 url = self .audience + NET_RESOURCES ['regions' ].find_url
16541639
16551640 if len (unique_providers ) == 1 and location_code :
0 commit comments