Skip to content

Commit e07a144

Browse files
committed
return resource if patch no-wait
1 parent 8f0101f commit e07a144

File tree

2 files changed

+75
-57
lines changed

2 files changed

+75
-57
lines changed

netfoundry/ctl.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -806,7 +806,7 @@ def demo(cli):
806806
name=network_name,
807807
size=cli.config.demo.size,
808808
version=cli.config.demo.product_version,
809-
wait=1200)
809+
wait=0) # don't use wait > 0 until process-executions beta is launched, until then poll for status
810810
network, network_group = use_network(
811811
organization=organization,
812812
group=cli.config.general.network_group,

netfoundry/network.py

Lines changed: 74 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -459,66 +459,64 @@ def patch_resource(self, patch: dict, type: str = None, id: str = None, wait: in
459459

460460
if not MUTABLE_NET_RESOURCES.get(type): # prune properties that can't be patched
461461
raise RuntimeError(f"got unexpected type {type} for patch request to {self_link}")
462-
try:
463-
before_resource, status_symbol = get_generic_resource(url=self_link, headers=headers, proxies=self.proxies, verify=self.verify, accept='update')
464-
except Exception as e:
465-
raise RuntimeError(f"failed to get {type} for patching: '{e}'")
466-
else:
467-
# compare the patch to the discovered, current state, adding new or updated keys to pruned_patch
468-
pruned_patch = dict()
469-
for k in patch.keys():
470-
if k not in RESOURCES[plural(type)].no_update_props and before_resource.get(k):
471-
if isinstance(patch[k], list):
472-
if not set(before_resource[k]) == set(patch[k]):
473-
pruned_patch[k] = list(set(patch[k]))
474-
else:
475-
if not before_resource[k] == patch[k]:
476-
pruned_patch[k] = patch[k]
477-
478-
# attempt to update if there's at least one difference between the current resource and the submitted patch
479-
if len(pruned_patch.keys()) > 0:
480-
if not pruned_patch.get('name'):
481-
pruned_patch["name"] = before_resource["name"]
482-
# if entity is a service and "model" is patched then always include "modelType"
483-
if type == "services" and not pruned_patch.get('modelType') and pruned_patch.get('model'):
484-
pruned_patch["modelType"] = before_resource["modelType"]
485-
try:
486-
after_response = http.patch(
487-
self_link,
488-
proxies=self.proxies,
489-
verify=self.verify,
490-
headers=headers,
491-
json=pruned_patch
492-
)
493-
after_response_code = after_response.status_code
494-
except Exception as e:
495-
raise RuntimeError(f"error with PATCH request to {self_link}, caught {e}")
496-
if after_response_code in [STATUS_CODES.codes.OK, STATUS_CODES.codes.ACCEPTED]:
497-
try:
498-
resource = after_response.json()
499-
except ValueError as e:
500-
raise RuntimeError(f"failed to load {type} object from PATCH response, caught {e}")
462+
before_resource, status_symbol = get_generic_resource(url=self_link, headers=headers, proxies=self.proxies, verify=self.verify, accept='update')
463+
# compare the patch to the discovered, current state, adding new or updated keys to pruned_patch
464+
pruned_patch = dict()
465+
for k in patch.keys():
466+
if k not in RESOURCES[plural(type)].no_update_props and before_resource.get(k):
467+
if isinstance(patch[k], list):
468+
if not set(before_resource[k]) == set(patch[k]):
469+
pruned_patch[k] = list(set(patch[k]))
501470
else:
502-
raise RuntimeError(f"got unexpected HTTP code {STATUS_CODES._codes[after_response_code][0].upper()} ({after_response_code}) for patch: {json.dumps(patch, indent=2)}")
471+
if not before_resource[k] == patch[k]:
472+
pruned_patch[k] = patch[k]
473+
474+
# attempt to update if there's at least one difference between the current resource and the submitted patch
475+
if len(pruned_patch.keys()) > 0:
476+
if not pruned_patch.get('name'):
477+
pruned_patch["name"] = before_resource["name"]
478+
# if entity is a service and "model" is patched then always include "modelType"
479+
if type == "services" and not pruned_patch.get('modelType') and pruned_patch.get('model'):
480+
pruned_patch["modelType"] = before_resource["modelType"]
481+
try:
482+
after_response = http.patch(
483+
self_link,
484+
proxies=self.proxies,
485+
verify=self.verify,
486+
headers=headers,
487+
json=pruned_patch
488+
)
489+
after_response_code = after_response.status_code
490+
except Exception as e:
491+
raise RuntimeError(f"error with PATCH request to {self_link}, caught {e}")
492+
if after_response_code in [STATUS_CODES.codes.OK, STATUS_CODES.codes.ACCEPTED]:
493+
try:
494+
resource = after_response.json()
495+
except ValueError as e:
496+
raise RuntimeError(f"failed to load {type} object from PATCH response, caught {e}")
497+
else:
498+
raise RuntimeError(f"got unexpected HTTP code {STATUS_CODES._codes[after_response_code][0].upper()} ({after_response_code}) for patch: {json.dumps(patch, indent=2)}")
503499

504-
if resource.get('_links') and resource['_links'].get('process-executions'):
505-
_links = resource['_links'].get('process-executions')
506-
if isinstance(_links, list):
507-
process_id = _links[0]['href'].split('/')[6]
508-
else:
509-
process_id = _links['href'].split('/')[6]
510-
if wait:
511-
self.wait_for_statuses(expected_statuses=RESOURCES["process-executions"].status_symbols['complete'], type="process-executions", id=process_id, wait=wait, sleep=sleep)
512-
return(resource)
513-
else: # only wait for the process to start, not finish, or timeout
514-
self.wait_for_statuses(expected_statuses=RESOURCES['process-executions'].status_symbols['progress'] + RESOURCES['process-executions'].status_symbols['complete'], type="process-executions", id=process_id, wait=9, sleep=2)
515-
return(resource)
516-
elif wait:
517-
logging.warning("unable to wait for async complete because response did not provide a process execution id")
500+
if resource.get('_links') and resource['_links'].get('process-executions'):
501+
_links = resource['_links'].get('process-executions')
502+
if isinstance(_links, list):
503+
process_id = _links[0]['href'].split('/')[6]
504+
else:
505+
process_id = _links['href'].split('/')[6]
506+
if wait:
507+
self.wait_for_statuses(expected_statuses=RESOURCES["process-executions"].status_symbols['complete'], type="process-executions", id=process_id, wait=wait, sleep=sleep)
518508
return(resource)
509+
else: # only wait for the process to start, not finish, or timeout
510+
self.wait_for_statuses(expected_statuses=RESOURCES['process-executions'].status_symbols['progress'] + RESOURCES['process-executions'].status_symbols['complete'], type="process-executions", id=process_id, wait=9, sleep=2)
511+
return(resource)
512+
elif wait:
513+
logging.warning("unable to wait for async complete because response did not provide a process execution id")
514+
return(resource)
519515
else:
520-
# no change, return the existing unmodified entity
521-
return(before_resource)
516+
return(resource)
517+
else:
518+
# no change, return the existing unmodified entity
519+
return(before_resource)
522520

523521
def put_resource(self, put: dict, type: str = None, id: str = None, wait: int = 0, sleep: int = 2, progress: bool = False):
524522
"""Update a resource with a complete set of properties.
@@ -576,6 +574,8 @@ def put_resource(self, put: dict, type: str = None, id: str = None, wait: int =
576574
elif wait:
577575
logging.warning("unable to wait for async complete because response did not provide a process execution id")
578576
return(resource)
577+
else:
578+
return(resource)
579579

580580
def create_resource(self, type: str, post: dict, wait: int = 30, sleep: int = 2, progress: bool = False):
581581
"""
@@ -625,6 +625,8 @@ def create_resource(self, type: str, post: dict, wait: int = 30, sleep: int = 2,
625625
elif wait:
626626
logging.warning("unable to wait for async complete because response did not provide a process execution id")
627627
return(resource)
628+
else:
629+
return(resource)
628630

629631
def create_endpoint(self, name: str, attributes: list = [], session_identity: str = None, wait: int = 30, sleep: int = 2, progress: bool = False):
630632
"""Create an endpoint.
@@ -690,6 +692,8 @@ def create_endpoint(self, name: str, attributes: list = [], session_identity: st
690692
elif wait:
691693
logging.warning("unable to wait for async complete because response did not provide a process execution id")
692694
return(resource)
695+
else:
696+
return(resource)
693697

694698
@docstring_parameters(providers=str(DC_PROVIDERS))
695699
def create_edge_router(self, name: str, attributes: list = list(), link_listener: bool = False, data_center_id: str = None,
@@ -785,6 +789,8 @@ def create_edge_router(self, name: str, attributes: list = list(), link_listener
785789
elif wait:
786790
logging.warning("unable to wait for async complete because response did not provide a process execution id")
787791
return(resource)
792+
else:
793+
return(resource)
788794

789795
def create_edge_router_policy(self, name: str, endpoint_attributes: list = [], edge_router_attributes: list = [], wait: int = 30):
790796
"""Create an edge router Policy.
@@ -986,6 +992,8 @@ def create_service_simple(self, name: str, client_host_name: str, client_port: i
986992
elif wait:
987993
logging.warning("unable to wait for async complete because response did not provide a process execution id")
988994
return(resource)
995+
else:
996+
return(resource)
989997

990998
# the above method was renamed to follow the development of PSM-based services (platform service models)
991999
create_service = create_service_simple
@@ -1065,6 +1073,8 @@ def create_service_policy(self, name: str, services: list, endpoints: list, type
10651073
elif wait:
10661074
logging.warning("unable to wait for async complete because response did not provide a process execution id")
10671075
return(resource)
1076+
else:
1077+
return(resource)
10681078

10691079
def create_service_edge_router_policy(self, name: str, services: list, edge_routers: list, semantic: str = "AnyOf",
10701080
dry_run: bool = False, wait: int = 30, sleep: int = 10, progress: bool = False):
@@ -1135,6 +1145,8 @@ def create_service_edge_router_policy(self, name: str, services: list, edge_rout
11351145
elif wait:
11361146
logging.warning("unable to wait for async complete because response did not provide a process execution id")
11371147
return(resource)
1148+
else:
1149+
return(resource)
11381150

11391151
def create_service_with_configs(self, name: str, intercept_config_data: dict, host_config_data: dict, attributes: list = [],
11401152
encryption_required: bool = True, dry_run: bool = False, wait: int = 60, sleep: int = 10,
@@ -1222,6 +1234,8 @@ def create_service_with_configs(self, name: str, intercept_config_data: dict, ho
12221234
elif wait:
12231235
logging.warning("unable to wait for async complete because response did not provide a process execution id")
12241236
return(resource)
1237+
else:
1238+
return(resource)
12251239

12261240
@docstring_parameters(valid_service_protocols=VALID_SERVICE_PROTOCOLS)
12271241
def create_service_transparent(self, name: str, client_hosts: list, client_ports: list, transparent_hosts: list,
@@ -1523,6 +1537,8 @@ def create_service_advanced(self, name: str, endpoints: list, client_hosts: list
15231537
elif wait:
15241538
logging.warning("unable to wait for async complete because response did not provide a process execution id")
15251539
return(resource)
1540+
else:
1541+
return(resource)
15261542

15271543
# the above method was renamed to follow the development of PSM-based services (platform service models)
15281544
create_endpoint_service = create_service_advanced
@@ -1956,6 +1972,8 @@ def delete_resource(self, type: str, id: str = None, wait: int = 0, progress: bo
19561972
elif wait:
19571973
logging.warning("unable to wait for async complete because response did not provide a process execution id")
19581974
return(False)
1975+
else:
1976+
return(True)
19591977

19601978

19611979
class Networks:

0 commit comments

Comments
 (0)