From cf30d71863484b314d2632ac8cb2c42367745a3c Mon Sep 17 00:00:00 2001 From: Jonathan Quintanilla Date: Mon, 9 Oct 2023 15:58:02 -0400 Subject: [PATCH 1/7] Bugfix: Allow retries on existing resources This PR fixes a bug where Ansible was retrying resources with a cached resourceVersion, so if the resourceVersion changed it would fall into a failure loop of not applying against the latest resourceVersion. Now, Ansible will be using the latest resourceVersion when applying a resource. --- library/openshift_provision.py | 38 +++++++++++++++------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/library/openshift_provision.py b/library/openshift_provision.py index 3f5c663..f552163 100644 --- a/library/openshift_provision.py +++ b/library/openshift_provision.py @@ -1386,30 +1386,19 @@ def get_resource_version_and_last_applied_configuration(self, resource): metadata = resource.get('metadata', {}) resource_version = metadata \ - .get('resourceVersion', None) + .pop('resourceVersion', None) last_applied_configuration = metadata \ .get('annotations', {}) \ - .get('kubectl.kubernetes.io/last-applied-configuration', None) + .pop('kubectl.kubernetes.io/last-applied-configuration', None) return resource_version, last_applied_configuration - def set_resource_version_and_last_applied_configuration(self, resource_version, last_applied_configuration): - if not resource_version or not last_applied_configuration: - return - merge_dict(self.resource, { - 'metadata': { - 'annotations': { - 'kubectl.kubernetes.io/last-applied-configuration': last_applied_configuration - }, - 'resourceVersion': resource_version - } - }, overwrite=True) - def provision(self): current_resource = self.get_current_resource() current_resource_version, current_last_applied_configuration = \ self.get_resource_version_and_last_applied_configuration(current_resource) if current_resource and self.action in ['apply', 'replace']: self.set_dynamic_values(current_resource) + self.current_resource_version = current_resource_version # Check if changes are required and if we need to reset the apply metadata. reset_last_applied_configuration = False @@ -1495,17 +1484,22 @@ def provision(self): command += ['-n', self.namespace] self.run_oc(command, data=json.dumps(self.resource), check_rc=True) else: # apply, create, delete, replace + resource = copy.deepcopy(self.resource) if self.action == 'apply': - self.set_resource_version_and_last_applied_configuration( - current_resource_version, - current_last_applied_configuration - ) + merge_dict(resource, { + 'metadata': { + 'annotations': { + 'kubectl.kubernetes.io/last-applied-configuration': current_last_applied_configuration + }, + 'resourceVersion': current_resource_version + } + }) command = [self.action, '-f', '-'] if self.namespace: command += ['-n', self.namespace] if reset_last_applied_configuration: command += ['--save-config'] - self.run_oc(command, data=json.dumps(self.resource), check_rc=True) + self.run_oc(command, data=json.dumps(resource), check_rc=True) def run_module(): module_args = { @@ -1559,14 +1553,16 @@ def run_module(): msg=str(e), action=provisioner.action, traceback=traceback.format_exc().split('\n'), - resource=provisioner.resource + resource=provisioner.resource, + current_resource_version=provisioner.current_resource_version ) module.exit_json( action=provisioner.action, changed=provisioner.changed, patch=provisioner.patch, - resource=provisioner.resource + resource=provisioner.resource, + current_resource_version=provisioner.current_resource_version ) def main(): From 2b23d4730af9a35d254125a9d77abb9db260f3cb Mon Sep 17 00:00:00 2001 From: Jonathan Quintanilla Date: Tue, 10 Oct 2023 17:05:58 -0400 Subject: [PATCH 2/7] adjusting compare_to and resource --- library/openshift_provision.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/library/openshift_provision.py b/library/openshift_provision.py index f552163..397b310 100644 --- a/library/openshift_provision.py +++ b/library/openshift_provision.py @@ -1294,6 +1294,8 @@ def comparison_fields(self): def compare_resource(self, resource, compare_to=None): if compare_to == None: compare_to = self.resource + resource = copy.deepcopy(resource) + compare_to = copy.deepcopy(compare_to) config = self.normalize_resource(compare_to) current = self.normalize_resource(resource) @@ -1488,9 +1490,6 @@ def provision(self): if self.action == 'apply': merge_dict(resource, { 'metadata': { - 'annotations': { - 'kubectl.kubernetes.io/last-applied-configuration': current_last_applied_configuration - }, 'resourceVersion': current_resource_version } }) From d8fbbda8312d7f387eafeb1fb93c9bb9a3ba6228 Mon Sep 17 00:00:00 2001 From: Jonathan Quintanilla Date: Tue, 10 Oct 2023 17:31:54 -0400 Subject: [PATCH 3/7] adding more output to failure json --- library/openshift_provision.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/library/openshift_provision.py b/library/openshift_provision.py index 397b310..29b360e 100644 --- a/library/openshift_provision.py +++ b/library/openshift_provision.py @@ -1553,7 +1553,8 @@ def run_module(): action=provisioner.action, traceback=traceback.format_exc().split('\n'), resource=provisioner.resource, - current_resource_version=provisioner.current_resource_version + current_resource_version=str(provisioner.current_resource_version or None), + jontest="Jon Test" ) module.exit_json( @@ -1561,7 +1562,8 @@ def run_module(): changed=provisioner.changed, patch=provisioner.patch, resource=provisioner.resource, - current_resource_version=provisioner.current_resource_version + current_resource_version=str(provisioner.current_resource_version or None), + jontest="Jon Test" ) def main(): From de7ddb4ffa83bb03887e76764d9bbdefd781e014 Mon Sep 17 00:00:00 2001 From: Jonathan Quintanilla Date: Tue, 10 Oct 2023 17:54:39 -0400 Subject: [PATCH 4/7] adding current_resource_version check --- library/openshift_provision.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/openshift_provision.py b/library/openshift_provision.py index 29b360e..526becb 100644 --- a/library/openshift_provision.py +++ b/library/openshift_provision.py @@ -1487,7 +1487,7 @@ def provision(self): self.run_oc(command, data=json.dumps(self.resource), check_rc=True) else: # apply, create, delete, replace resource = copy.deepcopy(self.resource) - if self.action == 'apply': + if self.action == 'apply' and current_resource_version: merge_dict(resource, { 'metadata': { 'resourceVersion': current_resource_version From 5efe5612ba314a5fee3c824fa3d217480fe0ba23 Mon Sep 17 00:00:00 2001 From: Jonathan Quintanilla Date: Tue, 10 Oct 2023 17:57:31 -0400 Subject: [PATCH 5/7] adding to fail_json --- library/openshift_provision.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/library/openshift_provision.py b/library/openshift_provision.py index 526becb..f2f5688 100644 --- a/library/openshift_provision.py +++ b/library/openshift_provision.py @@ -1111,7 +1111,10 @@ def run_oc(self, args, **kwargs): (rc, stdout, stderr) = self.module.run_command(self.oc_cmd + args, **kwargs) if rc != 0 and check_rc: - self.module.fail_json(cmd=args, rc=rc, stdout=stdout, stderr=stderr, msg=stderr) + self.module.fail_json( + cmd=args, rc=rc, stdout=stdout, stderr=stderr, msg=stderr, + resource=self.resource, current_resource_version=self.current_resource_version + ) return (rc, stdout, stderr) From f09ed1681fba940bac6691fe5ad2f5a5d0ac4669 Mon Sep 17 00:00:00 2001 From: Jonathan Quintanilla Date: Thu, 12 Oct 2023 12:20:45 -0400 Subject: [PATCH 6/7] adding print statements --- library/openshift_provision.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/openshift_provision.py b/library/openshift_provision.py index f2f5688..4820282 100644 --- a/library/openshift_provision.py +++ b/library/openshift_provision.py @@ -1122,7 +1122,9 @@ def get_current_resource(self): command = ['get', self.resource['kind'], self.resource['metadata']['name'], '-o', 'json'] if self.namespace: command += ['-n', self.namespace] + print("THIS IS THE COMMAND {}".format(" ".join(command))) (rc, stdout, stderr) = self.run_oc(command, check_rc=False) + print("THIS IS THE STDOUT {}".format(stdout)) if rc != 0: return None resource = json.loads(stdout) @@ -1297,8 +1299,6 @@ def comparison_fields(self): def compare_resource(self, resource, compare_to=None): if compare_to == None: compare_to = self.resource - resource = copy.deepcopy(resource) - compare_to = copy.deepcopy(compare_to) config = self.normalize_resource(compare_to) current = self.normalize_resource(resource) From ba719432866857a0b0cb04103f2977b7fa1db696 Mon Sep 17 00:00:00 2001 From: Jonathan Quintanilla Date: Thu, 12 Oct 2023 12:35:27 -0400 Subject: [PATCH 7/7] conditional to check stdout --- library/openshift_provision.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/openshift_provision.py b/library/openshift_provision.py index 4820282..efcb491 100644 --- a/library/openshift_provision.py +++ b/library/openshift_provision.py @@ -1122,9 +1122,9 @@ def get_current_resource(self): command = ['get', self.resource['kind'], self.resource['metadata']['name'], '-o', 'json'] if self.namespace: command += ['-n', self.namespace] - print("THIS IS THE COMMAND {}".format(" ".join(command))) (rc, stdout, stderr) = self.run_oc(command, check_rc=False) - print("THIS IS THE STDOUT {}".format(stdout)) + if self.resource['kind'] == "CertManager" and self.resource['metadata']['name'] == "cluster": + print("Resource stdout: {}".format(stdout)) if rc != 0: return None resource = json.loads(stdout)