From 3335ea953e24a4aafed8e7f849004c964eb1f33e Mon Sep 17 00:00:00 2001 From: Dominique Quatravaux Date: Thu, 29 Oct 2020 11:57:30 +0100 Subject: [PATCH 1/3] [feature] Keep pod_spec_override-provided pod labels - Write a deepmerge() implementation, keeping only the test suite of https://stackoverflow.com/a/20666342/435004 - Use it to deep-merge pod['metadata'] with user input, instead of replacing fields in it --- awx/main/scheduler/kubernetes.py | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/awx/main/scheduler/kubernetes.py b/awx/main/scheduler/kubernetes.py index 862cfd3f04..9dc1ca94e3 100644 --- a/awx/main/scheduler/kubernetes.py +++ b/awx/main/scheduler/kubernetes.py @@ -12,6 +12,22 @@ from awx.main.utils.common import parse_yaml_or_json logger = logging.getLogger('awx.main.scheduler') +def deepmerge(a, b): + """ + >>> a = { 'first' : { 'all_rows' : { 'pass' : 'dog', 'number' : '1' } } } + >>> b = { 'first' : { 'all_rows' : { 'fail' : 'cat', 'number' : '5' } } } + >>> deepmerge(b, a) == { 'first' : { 'all_rows' : { 'pass' : 'dog', 'fail' : 'cat', 'number' : '5' } } } + True + """ + if isinstance(a, dict) and isinstance(b, dict): + return dict([(k, deepmerge(a.get(k), b.get(k))) + for k in set(a.keys()).union(b.keys())]) + elif b is None: + return a + else: + return b + + class PodManager(object): def __init__(self, task=None): @@ -128,11 +144,13 @@ class PodManager(object): pod_spec = {**default_pod_spec, **pod_spec_override} if self.task: - pod_spec['metadata']['name'] = self.pod_name - pod_spec['metadata']['labels'] = { - 'ansible-awx': settings.INSTALL_UUID, - 'ansible-awx-job-id': str(self.task.id) - } + pod_spec['metadata'] = deepmerge( + pod_spec.get('metadata', {}), + dict(name=self.pod_name, + labels={ + 'ansible-awx': settings.INSTALL_UUID, + 'ansible-awx-job-id': str(self.task.id) + })) pod_spec['spec']['containers'][0]['name'] = self.pod_name return pod_spec From 87b97530ff823aa0fd466713761b33c2d7b0490d Mon Sep 17 00:00:00 2001 From: Dominique Quatravaux Date: Thu, 29 Oct 2020 13:14:59 +0100 Subject: [PATCH 2/3] [fix] flake8 --- awx/main/scheduler/kubernetes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/awx/main/scheduler/kubernetes.py b/awx/main/scheduler/kubernetes.py index 9dc1ca94e3..b6893f593a 100644 --- a/awx/main/scheduler/kubernetes.py +++ b/awx/main/scheduler/kubernetes.py @@ -21,7 +21,7 @@ def deepmerge(a, b): """ if isinstance(a, dict) and isinstance(b, dict): return dict([(k, deepmerge(a.get(k), b.get(k))) - for k in set(a.keys()).union(b.keys())]) + for k in set(a.keys()).union(b.keys())]) elif b is None: return a else: @@ -150,7 +150,7 @@ class PodManager(object): labels={ 'ansible-awx': settings.INSTALL_UUID, 'ansible-awx-job-id': str(self.task.id) - })) + })) pod_spec['spec']['containers'][0]['name'] = self.pod_name return pod_spec From deb56bf4f862a3ddf613e7d96bd657d8672a1f32 Mon Sep 17 00:00:00 2001 From: Dominique Quatravaux Date: Thu, 29 Oct 2020 14:03:19 +0100 Subject: [PATCH 3/3] [fix] Now with doctest that actually passes --- awx/main/scheduler/kubernetes.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/awx/main/scheduler/kubernetes.py b/awx/main/scheduler/kubernetes.py index b6893f593a..529a5e5442 100644 --- a/awx/main/scheduler/kubernetes.py +++ b/awx/main/scheduler/kubernetes.py @@ -14,10 +14,12 @@ logger = logging.getLogger('awx.main.scheduler') def deepmerge(a, b): """ - >>> a = { 'first' : { 'all_rows' : { 'pass' : 'dog', 'number' : '1' } } } - >>> b = { 'first' : { 'all_rows' : { 'fail' : 'cat', 'number' : '5' } } } - >>> deepmerge(b, a) == { 'first' : { 'all_rows' : { 'pass' : 'dog', 'fail' : 'cat', 'number' : '5' } } } - True + Merge dict structures and return the result. + + >>> a = {'first': {'all_rows': {'pass': 'dog', 'number': '1'}}} + >>> b = {'first': {'all_rows': {'fail': 'cat', 'number': '5'}}} + >>> import pprint; pprint.pprint(deepmerge(a, b)) + {'first': {'all_rows': {'fail': 'cat', 'number': '5', 'pass': 'dog'}}} """ if isinstance(a, dict) and isinstance(b, dict): return dict([(k, deepmerge(a.get(k), b.get(k)))