Skip to content

Commit ee9310b

Browse files
committed
no cache when getting things that need to be evergreen, like statuses
1 parent ddbc9fd commit ee9310b

2 files changed

Lines changed: 50 additions & 47 deletions

File tree

netfoundry/network.py

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ def __init__(self, NetworkGroup: object, network_id: str = None, network_name: s
3131
self.audience = NetworkGroup.audience
3232
self.network_group_id = NetworkGroup.id
3333

34+
self.Networks = Networks(NetworkGroup)
35+
3436
if (not network_id and not network_name) and network:
3537
if is_uuidv4(network):
3638
network_id = network
@@ -317,7 +319,7 @@ def share_endpoint(self, recipient, endpoint_id):
317319
if not response_code == STATUS_CODES.codes['ACCEPTED']:
318320
raise RuntimeError(f"got unexpected HTTP code {STATUS_CODES._codes[response_code][0].upper()} ({response_code}) and response {response.text}")
319321

320-
def get_resource_by_id(self, type: str, id: str, accept: str = None):
322+
def get_resource_by_id(self, type: str, id: str, accept: str = None, use_cache: bool=True):
321323
"""Return an object describing a resource entity.
322324
323325
:param type: required string of the singular of an entity type e.g. network, endpoint, service, edge-router, edge-router-policy, posture-check
@@ -341,13 +343,13 @@ def get_resource_by_id(self, type: str, id: str, accept: str = None):
341343
raise RuntimeError(f"unknown resource type '{plural(type)}'. Choices: {', '.join(NET_RESOURCES.keys())}")
342344

343345
url = self.audience+'core/v2/'+plural(type)+'/'+id
344-
resource, status_symbol = get_generic_resource_by_url(setup=self, url=url, headers=headers)
346+
resource, status_symbol = get_generic_resource_by_url(setup=self, url=url, headers=headers, use_cache=use_cache)
345347
if not resource['networkId'] == self.id:
346348
raise NetworkBoundaryViolation("resource ID is from another network")
347349
return(resource)
348350
get_resource = get_resource_by_id
349351

350-
def find_resources(self, type: str, accept: str = None, deleted: bool = False, params: dict = dict(), **kwargs):
352+
def find_resources(self, type: str, accept: str = None, deleted: bool = False, params: dict = dict(), use_cache: bool = True, **kwargs):
351353
"""Find resources by type.
352354
353355
:param str type: plural of an entity type in the network domain e.g. networks, endpoints, services, posture-checks, etc...
@@ -360,8 +362,6 @@ def find_resources(self, type: str, accept: str = None, deleted: bool = False, p
360362
# pluralize if singular
361363
if not type[-1] == "s":
362364
type = plural(type)
363-
if type == "data-centers":
364-
self.logger.warning("don't call network.get_resources() for data centers, always use network.get_edge_router_data_centers() to filter for locations that support this network's version")
365365

366366
for param in kwargs.keys():
367367
params[param] = kwargs[param]
@@ -376,7 +376,7 @@ def find_resources(self, type: str, accept: str = None, deleted: bool = False, p
376376
url = self.audience+'core/v2/'+plural(type)
377377
try:
378378
resources = list()
379-
for i in find_generic_resources(setup=self, url=url, embedded=NET_RESOURCES[plural(type)]._embedded, accept=accept, **params):
379+
for i in find_generic_resources(setup=self, url=url, embedded=NET_RESOURCES[plural(type)]._embedded, accept=accept, use_cache=use_cache, **params):
380380
resources.extend(i)
381381
except Exception as e:
382382
raise RuntimeError(f"failed to get {plural(type)} from url: '{url}', caught {e}")
@@ -424,7 +424,7 @@ def patch_resource(self, patch: dict, type: str = None, id: str = None, wait: in
424424

425425
if not MUTABLE_NET_RESOURCES.get(type): # prune properties that can't be patched
426426
raise RuntimeError(f"got unexpected type '{type}' for patch request to {self_link}")
427-
before_resource, status_symbol = get_generic_resource_by_url(setup=self, url=self_link)
427+
before_resource, status_symbol = get_generic_resource_by_url(setup=self, url=self_link, use_cache=False)
428428
self.logger.debug(f"found existing resource before patching with properties: '{before_resource}'")
429429
# compare the patch to the discovered, current state, adding new or updated keys to pruned_patch
430430
pruned_patch = dict()
@@ -568,7 +568,7 @@ def create_resource(self, type: str, post: dict, wait: int = 30, sleep: int = 2,
568568
if body.get('name'):
569569
body['name'] = body['name'].strip('"')
570570
url = self.audience+'core/v2/'+type
571-
resource = create_generic_resource(url=url, body=body, headers=headers, proxies=self.proxies, verify=self.verify, wait=wait, sleep=sleep)
571+
resource = create_generic_resource(setup=self, url=url, body=body, wait=wait, sleep=sleep)
572572
return(resource)
573573

574574
def create_endpoint(self, name: str, attributes: list = [], session_identity: str = None, wait: int = 30, sleep: int = 2, progress: bool = False):
@@ -596,7 +596,7 @@ def create_endpoint(self, name: str, attributes: list = [], session_identity: st
596596
body['sessionIdentityId'] = session_identity
597597

598598
url = self.audience+'core/v2/endpoints'
599-
resource = create_generic_resource(url=url, body=body, headers=headers, proxies=self.proxies, verify=self.verify, wait=wait, sleep=sleep)
599+
resource = create_generic_resource(setup=self, url=url, body=body, wait=wait, sleep=sleep)
600600
self.logger.debug(f"created endpoint {resource['name']}")
601601
return(resource)
602602

@@ -651,20 +651,17 @@ def create_edge_router(self, name: str, attributes: list = list(), link_listener
651651
raise RuntimeError("need both provider and location_code to create a hosted router.")
652652

653653
url = self.audience+'core/v2/edge-routers'
654-
resource = create_generic_resource(url=url, body=body, headers=headers, proxies=self.proxies, verify=self.verify, wait=wait, sleep=sleep)
654+
resource = create_generic_resource(setup=self, url=url, body=body, wait=wait, sleep=sleep)
655655
return(resource)
656656

657-
def create_edge_router_policy(self, name: str, endpoint_attributes: list = [], edge_router_attributes: list = [], wait: int = 30):
657+
def create_edge_router_policy(self, name: str, endpoint_attributes: list = [], edge_router_attributes: list = [], wait: int = 30, sleep: int = 3):
658658
"""Create an edge router Policy.
659659
660660
:param name: a meaningful, unique name
661661
:param endpoint_attributes: a list of endpoint hashtag role attributes and endpoint name mentions
662662
:param edge_router_attributes: a list of router hashtag role attributes and router name mentions
663663
:param wait: seconds to wait for provisioning to finish before raising an exception
664664
"""
665-
headers = {
666-
"authorization": "Bearer " + self.token
667-
}
668665
for role in endpoint_attributes+edge_router_attributes:
669666
if not re.match('^[#@]', role):
670667
raise RuntimeError("role attributes on a policy must begin with # or @")
@@ -675,7 +672,7 @@ def create_edge_router_policy(self, name: str, endpoint_attributes: list = [], e
675672
"edgeRouterAttributes": edge_router_attributes
676673
}
677674
url = self.audience+'core/v2/edge-router-policies'
678-
resource = create_generic_resource(url=url, body=body, headers=headers, proxies=self.proxies, verify=self.verify, wait=wait)
675+
resource = create_generic_resource(setup=self, url=url, body=body, wait=wait, sleep=sleep)
679676
return(resource)
680677

681678
@docstring_parameters(valid_service_protocols=VALID_SERVICE_PROTOCOLS)
@@ -793,7 +790,7 @@ def create_service_simple(self, name: str, client_host_name: str, client_port: i
793790
body['model']['bindEndpointAttributes'] = bind_endpoints
794791

795792
url = self.audience+'core/v2/services'
796-
resource = create_generic_resource(url=url, body=body, headers=headers, proxies=self.proxies, verify=self.verify, wait=wait, sleep=sleep)
793+
resource = create_generic_resource(setup=self, url=url, body=body, wait=wait, sleep=sleep)
797794
return(resource)
798795

799796
# the above method was renamed to follow the development of PSM-based services (platform service models)
@@ -833,7 +830,7 @@ def create_service_policy(self, name: str, services: list, endpoints: list, type
833830
return(body)
834831

835832
url = self.audience+'core/v2/service-policies'
836-
resource = create_generic_resource(url=url, body=body, headers=headers, proxies=self.proxies, verify=self.verify, wait=wait, sleep=sleep)
833+
resource = create_generic_resource(setup=self, url=url, body=body, wait=wait, sleep=sleep)
837834
return(resource)
838835

839836
def create_service_edge_router_policy(self, name: str, services: list, edge_routers: list, semantic: str = "AnyOf",
@@ -864,7 +861,7 @@ def create_service_edge_router_policy(self, name: str, services: list, edge_rout
864861
return(body)
865862

866863
url = self.audience+'core/v2/service-edge-router-policies'
867-
resource = create_generic_resource(url=url, body=body, headers=headers, proxies=self.proxies, verify=self.verify, wait=wait, sleep=sleep)
864+
resource = create_generic_resource(setup=self, url=url, body=body, wait=wait, sleep=sleep)
868865
return(resource)
869866

870867
def create_service_with_configs(self, name: str, intercept_config_data: dict, host_config_data: dict, attributes: list = [],
@@ -1171,14 +1168,14 @@ def create_service_advanced(self, name: str, endpoints: list, client_hosts: list
11711168
return(body)
11721169

11731170
url = self.audience+'core/v2/services'
1174-
resource = create_generic_resource(url=url, body=body, headers=headers, proxies=self.proxies, verify=self.verify, wait=wait, sleep=sleep)
1171+
resource = create_generic_resource(setup=self, url=url, body=body, wait=wait, sleep=sleep)
11751172
return(resource)
11761173

11771174
# the above method was renamed to follow the development of PSM-based services (platform service models)
11781175
create_endpoint_service = create_service_advanced
11791176

11801177
def create_app_wan(self, name: str, endpoint_attributes: list = [], service_attributes: list = [], posture_check_attributes: list = [],
1181-
wait: int = 10):
1178+
wait: int = 10, sleep: int = 3):
11821179
"""Create an AppWAN.
11831180
11841181
:param name: a meaningful, unique name
@@ -1200,7 +1197,7 @@ def create_app_wan(self, name: str, endpoint_attributes: list = [], service_attr
12001197
"postureCheckAttributes": posture_check_attributes
12011198
}
12021199
url = self.audience+'core/v2/app-wans'
1203-
resource = create_generic_resource(url=url, body=body, headers=headers, proxies=self.proxies, verify=self.verify, wait=wait)
1200+
resource = create_generic_resource(setup=self, url=url, body=body, wait=wait, sleep=sleep)
12041201
return(resource)
12051202

12061203
def get_network_by_name(self, name: str):
@@ -1302,7 +1299,7 @@ def wait_for_property_defined(self, property_name: str, property_type: object =
13021299
while time.time() < now+wait:
13031300

13041301
try:
1305-
entity = self.get_resource_by_id(type=entity_type, id=id)
1302+
entity = self.get_resource_by_id(type=entity_type, id=id, use_cache=False)
13061303
except Exception as e:
13071304
raise RuntimeError(f"problem getting resource by id to get status, caught {e}")
13081305

@@ -1347,7 +1344,7 @@ def wait_for_entity_name_exists(self, entity_name: str, entity_type: str, wait:
13471344
found_entities = []
13481345
while time.time() < now+wait:
13491346
try:
1350-
found_entities = self.find_resources(type=plural(entity_type), name=entity_name)
1347+
found_entities = self.find_resources(type=plural(entity_type), name=entity_name, use_cache=False)
13511348
except Exception as e:
13521349
raise RuntimeError(f"error finding resources, caught {e}")
13531350

@@ -1475,8 +1472,7 @@ def get_resource_status(self, type: str, id: str = None):
14751472
else:
14761473
entity_url += f"{plural(type)}/{id}"
14771474

1478-
headers = {"authorization": "Bearer " + self.token}
1479-
resource, status_symbol = get_generic_resource_by_url(setup=self, url=entity_url)
1475+
resource, status_symbol = get_generic_resource_by_url(setup=self, url=entity_url, use_cache=False)
14801476

14811477
if resource.get(RESOURCES[plural(type)].status):
14821478
status = resource[RESOURCES[plural(type)].status]
@@ -1588,16 +1584,16 @@ class Networks:
15881584
networks.
15891585
"""
15901586

1591-
def __init__(self, Organization: object) -> None:
1587+
def __init__(self, setup: object) -> None:
15921588
"""
1593-
:organization: an instance of netfoundry.Organization provides a session and configuration
1589+
:organization: an instance of an object such as netfoundry.Organization provides a session and configuration
15941590
"""
1595-
self.token = Organization.token
1596-
self.proxies = Organization.proxies
1597-
self.verify = Organization.verify
1598-
self.audience = Organization.audience
1599-
self.environment = Organization.environment
1600-
self.logger = Organization.logger
1591+
self.token = setup.token
1592+
self.proxies = setup.proxies
1593+
self.verify = setup.verify
1594+
self.audience = setup.audience
1595+
self.environment = setup.environment
1596+
self.logger = setup.logger
16011597

16021598
def find_network_domain_resources(self, resource_type: str, **kwargs):
16031599
"""

netfoundry/utility.py

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -257,9 +257,9 @@ def get_user_config_dir():
257257
return user_config_path(appname='netfoundry')
258258

259259

260-
def get_generic_resource_by_type_and_id(setup: object, resource_type: str, resource_id: str, accept: str = None, **kwargs):
260+
def get_generic_resource_by_type_and_id(setup: object, resource_type: str, resource_id: str, accept: str = None, use_cache: bool = True, **kwargs):
261261
url = f"{setup.audience}{RESOURCES[resource_type].find_url}/{resource_id}"
262-
resource, status_symbol = get_generic_resource_by_url(setup=setup, url=url, accept=accept, **kwargs)
262+
resource, status_symbol = get_generic_resource_by_url(setup=setup, url=url, accept=accept, use_cache=use_cache, **kwargs)
263263
return resource, status_symbol
264264

265265

@@ -283,7 +283,7 @@ def wait_for_execution(setup: object, url: str, wait: int = 300, sleep: int = 3)
283283
status = 'NEW'
284284
# time.sleep(sleep) # allow minimal time for the resource status to become available
285285
while time.time() < now+wait and status not in expected_statuses:
286-
execution, status_symbol = get_generic_resource_by_url(setup=setup, url=url)
286+
execution, status_symbol = get_generic_resource_by_url(setup=setup, url=url, use_cache=False)
287287
if execution.get('status'): # attribute is not None if HTTP OK
288288
status = execution['status']
289289
setup.logger.debug(f"{execution['name']} has status {execution['status']}")
@@ -333,7 +333,7 @@ def create_generic_resource(setup: object, url: str, body: dict, headers: dict =
333333
return resource
334334

335335

336-
def get_generic_resource_by_url(setup: object, url: str, headers: dict = dict(), accept: str = None, **kwargs):
336+
def get_generic_resource_by_url(setup: object, url: str, headers: dict = dict(), accept: str = None, use_cache: bool = True, **kwargs):
337337
"""
338338
Get, deserialize, and return a single resource.
339339
@@ -363,7 +363,11 @@ def get_generic_resource_by_url(setup: object, url: str, headers: dict = dict(),
363363
params['beta'] = str()
364364
else:
365365
setup.logger.debug(f"no handlers specified for url '{url}'")
366-
response = http_cache.get(
366+
if use_cache:
367+
http_session = http_cache
368+
else:
369+
http_session = http
370+
response = http_session.get(
367371
url,
368372
headers=headers,
369373
params=params,
@@ -401,7 +405,7 @@ def get_generic_resource_by_url(setup: object, url: str, headers: dict = dict(),
401405
get_generic_resource = get_generic_resource_by_type_and_id
402406

403407

404-
def find_generic_resources(setup: object, url: str, headers: dict = dict(), embedded: str = None, accept: str = None, **kwargs):
408+
def find_generic_resources(setup: object, url: str, headers: dict = dict(), embedded: str = None, accept: str = None, use_cache: bool = True, **kwargs):
405409
"""
406410
Generate each page of a type of resource.
407411
@@ -418,8 +422,8 @@ def find_generic_resources(setup: object, url: str, headers: dict = dict(), embe
418422
# validate and store the resource type
419423
resource_type = get_resource_type_by_url(url)
420424
setup.logger.debug(f"detected URL for resource type {resource_type.name}")
421-
if not resource_type.name == "download-urls":
422-
headers['Authorization'] = f"Bearer {setup.token}"
425+
# if not resource_type.name == "download-urls":
426+
headers['Authorization'] = f"Bearer {setup.token}"
423427
if HOSTABLE_NET_RESOURCES.get(resource_type.name):
424428
params['embed'] = "host"
425429
elif resource_type.name in ["process-executions"]:
@@ -436,15 +440,15 @@ def find_generic_resources(setup: object, url: str, headers: dict = dict(), embe
436440
# normalize output with a default sort param
437441
if not params.get('sort'):
438442
params["sort"] = "name,asc"
439-
# workaround sort param bugs in MOP-18018, MOP-17863, MOP-18178
440-
if resource_type.name in ['identities', 'user-identities', 'api-account-identities', 'hosts', 'terminators']:
443+
# workaround sort param bugs in MOP-18018, MOP-17863, MOP-18178, MOP-18366
444+
if resource_type.name in ['identities', 'user-identities', 'api-account-identities', 'hosts', 'terminators', 'network-versions']:
441445
del params['sort']
442446

443447
# only get one page of the requested size, else default page size and all pages
444448
if params.get('size'):
445449
get_all_pages = False
446450
else:
447-
if resource_type.name in ['data-centers', 'roles']:
451+
if resource_type.name in ['roles']:
448452
params['size'] = 3000 # workaround last page bug in MOP-17993
449453
else:
450454
params['size'] = DEFAULT_PAGE_SIZE
@@ -463,8 +467,11 @@ def find_generic_resources(setup: object, url: str, headers: dict = dict(), embe
463467
embedded = accept + embedded[0].upper() + embedded[1:] # compose "createEndpointList" from "endpointList"
464468
else:
465469
setup.logger.warn("ignoring invalid value for header 'accept': '{:s}'".format(accept))
466-
467-
response = http_cache.get(
470+
if use_cache:
471+
http_session = http_cache
472+
else:
473+
http_session = http
474+
response = http_session.get(
468475
url,
469476
headers=headers,
470477
params=params,
@@ -915,7 +922,7 @@ def send(self, request, **kwargs):
915922

916923

917924
http = Session() # no cache
918-
HTTP_CACHE_EXPIRE = 111
925+
HTTP_CACHE_EXPIRE = 33
919926
http_cache = CachedSession(cache_name=f"{get_user_cache_dir()}/http_cache", backend='sqlite', expire_after=HTTP_CACHE_EXPIRE)
920927
# Mount it for both http and https usage
921928
adapter = TimeoutHTTPAdapter(timeout=DEFAULT_TIMEOUT, max_retries=RETRY_STRATEGY)

0 commit comments

Comments
 (0)