From 90889389fdf6978f9ec163af46b97c359b2a9569 Mon Sep 17 00:00:00 2001 From: Will Thames Date: Thu, 14 May 2020 14:18:48 +1000 Subject: [PATCH] Improve handling of dict patches in lists List items should be properly recursively patched, otherwise changes to nested fields can be ignored. This does change one of the tests to allow the deeper patching to work correctly --- openshift/dynamic/apply.py | 9 ++++----- test/unit/test_apply.py | 24 +++++++++++++++++++++++- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/openshift/dynamic/apply.py b/openshift/dynamic/apply.py index b975b950..3b0ef325 100644 --- a/openshift/dynamic/apply.py +++ b/openshift/dynamic/apply.py @@ -129,9 +129,9 @@ def apply(resource, definition): # from last_applied to desired. To find it, we compute deletions, which are the deletions from # last_applied to desired, and delta, which is the difference from actual to desired without # deletions, and then apply delta to deletions as a patch, which should be strictly additive. -def merge(last_applied, desired, actual): +def merge(last_applied, desired, actual, position=None): deletions = get_deletions(last_applied, desired) - delta = get_delta(last_applied, actual, desired, desired['kind']) + delta = get_delta(last_applied, actual, desired, position or desired['kind']) return dict_merge(deletions, delta) @@ -176,9 +176,8 @@ def list_merge(last_applied, actual, desired, position): if key not in actual_dict or key not in last_applied_dict: result.append(desired_dict[key]) else: - deletions = set(last_applied_dict[key].keys()) - set(desired_dict[key].keys()) - result.append(dict_merge({k: v for k, v in actual_dict[key].items() if k not in deletions}, - desired_dict[key])) + patch = merge(last_applied_dict[key], desired_dict[key], actual_dict[key], position) + result.append(dict_merge(actual_dict[key], patch)) return result else: return desired diff --git a/test/unit/test_apply.py b/test/unit/test_apply.py index a6cf0417..d8d74bb0 100644 --- a/test/unit/test_apply.py +++ b/test/unit/test_apply.py @@ -141,7 +141,29 @@ metadata=dict(name="foo"), spec=dict(ports=[dict(port=8443, name="https")]) ), - expected = dict(spec=dict(ports=[dict(port=8443, name="https", protocol='TCP')])) + expected = dict(spec=dict(ports=[dict(madeup=None, port=8443, name="https", protocol='TCP')])) + ), + dict( + last_applied = dict( + kind="Pod", + metadata=dict(name="foo"), + spec=dict(containers=[dict(name="busybox", image="busybox", + resources=dict(requests=dict(cpu="100m", memory="100Mi"), limits=dict(cpu="100m", memory="100Mi")))]) + ), + actual = dict( + kind="Pod", + metadata=dict(name="foo"), + spec=dict(containers=[dict(name="busybox", image="busybox", + resources=dict(requests=dict(cpu="100m", memory="100Mi"), limits=dict(cpu="100m", memory="100Mi")))]) + ), + desired = dict( + kind="Pod", + metadata=dict(name="foo"), + spec=dict(containers=[dict(name="busybox", image="busybox", + resources=dict(requests=dict(cpu="50m", memory="50Mi"), limits=dict(memory="50Mi")))]) + ), + expected=dict(spec=dict(containers=[dict(name="busybox", image="busybox", + resources=dict(requests=dict(cpu="50m", memory="50Mi"), limits=dict(cpu=None, memory="50Mi")))])) ), # This next one is based on a real world case where definition was mostly