From 3d8d3e9748c2ab56a3faa4b5df2976f9d5d1df29 Mon Sep 17 00:00:00 2001 From: Evgeni Golov Date: Tue, 27 Aug 2024 08:53:43 +0200 Subject: [PATCH] correctly catch facts with vault and other ansible-specific data --- .../fragments/1769-callback-vault-facts.yml | 2 ++ plugins/callback/foreman.py | 17 +++++++++++++++-- tests/callback/three_hosts.yml | 9 +++++++++ .../dir_store/foreman/testhost-facts.json | 4 +++- .../dir_store/proxy/testhost-report.json | 4 +++- 5 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 changelogs/fragments/1769-callback-vault-facts.yml diff --git a/changelogs/fragments/1769-callback-vault-facts.yml b/changelogs/fragments/1769-callback-vault-facts.yml new file mode 100644 index 000000000..6cf923b54 --- /dev/null +++ b/changelogs/fragments/1769-callback-vault-facts.yml @@ -0,0 +1,2 @@ +bugfixes: + - callback plugin - correctly catch facts with vault data and replace it with ``ENCRYPTED_VAULT_VALUE_NOT_REPORTED``, preventing ``Object of type AnsibleVaultEncryptedUnicode is not JSON serializable`` errors diff --git a/plugins/callback/foreman.py b/plugins/callback/foreman.py index 6f70fb07e..2c976775a 100644 --- a/plugins/callback/foreman.py +++ b/plugins/callback/foreman.py @@ -118,6 +118,7 @@ HAS_REQUESTS = False from ansible.module_utils._text import to_text +from ansible.module_utils.common.json import AnsibleJSONEncoder from ansible.module_utils.parsing.convert_bool import boolean as to_bool from ansible.plugins.callback import CallbackBase @@ -172,6 +173,15 @@ def get_now(): return datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S+00:00") +class AnsibleNoVaultJSONEncoder(AnsibleJSONEncoder): + def default(self, o): + if getattr(o, '__ENCRYPTED__', False): + value = 'ENCRYPTED_VAULT_VALUE_NOT_REPORTED' + else: + value = super(AnsibleNoVaultJSONEncoder, self).default(o) + return value + + class CallbackModule(CallbackBase): CALLBACK_VERSION = 2.0 CALLBACK_TYPE = 'notification' @@ -243,14 +253,17 @@ def _send_data(self, data_type, report_type, host, data): else: self._display.warning(u'Unknown report_type: {rt}'.format(rt=report_type)) + json_data = json.dumps(data, indent=2, sort_keys=True, cls=AnsibleNoVaultJSONEncoder) + if len(self.dir_store) > 0: filename = u'{host}-{dt}.json'.format(host=to_text(host), dt=data_type) filename = os.path.join(self.dir_store, filename) with open(filename, 'w') as f: - json.dump(data, f, indent=2, sort_keys=True) + f.write(json_data) else: try: - response = self.session.post(url=url, json=data) + headers = {'content-type': 'application/json'} + response = self.session.post(url=url, data=json_data, headers=headers) response.raise_for_status() except requests.exceptions.RequestException as err: self._display.warning(u'Sending data to Foreman at {url} failed for {host}: {err}'.format( diff --git a/tests/callback/three_hosts.yml b/tests/callback/three_hosts.yml index c333195c8..584329219 100644 --- a/tests/callback/three_hosts.yml +++ b/tests/callback/three_hosts.yml @@ -47,6 +47,15 @@ - name: Vault fact set_fact: geheim: "{{ crypt }}" + crypt: !vault | + $ANSIBLE_VAULT;1.1;AES256 + 62343962363339363461373565656663663734393265636161313466326163666638333735303061 + 6134346238366533616262663462396332363535363662660a323339326635373330633230336332 + 38363334373037356466383063616532656632303636333839313831626264386132386661303535 + 3864663564356332390a633631363962353163316236323038363861623763616265343762366435 + 6237 + unsafe: !unsafe | + THIS IS {{ crypt }} handlers: - name: Test handler 1 diff --git a/tests/fixtures/callback/dir_store/foreman/testhost-facts.json b/tests/fixtures/callback/dir_store/foreman/testhost-facts.json index d2b0ddb80..6270adc1d 100644 --- a/tests/fixtures/callback/dir_store/foreman/testhost-facts.json +++ b/tests/fixtures/callback/dir_store/foreman/testhost-facts.json @@ -3,7 +3,9 @@ "_timestamp": "2000-01-01 12:00:00+00:00", "_type": "ansible", "ansible_facts": { - "geheim": "admin" + "crypt": "ENCRYPTED_VAULT_VALUE_NOT_REPORTED", + "geheim": "admin", + "unsafe": "THIS IS {{ crypt }}\n" } }, "name": "testhost" diff --git a/tests/fixtures/callback/dir_store/proxy/testhost-report.json b/tests/fixtures/callback/dir_store/proxy/testhost-report.json index 8b8af9966..61de85ab8 100644 --- a/tests/fixtures/callback/dir_store/proxy/testhost-report.json +++ b/tests/fixtures/callback/dir_store/proxy/testhost-report.json @@ -296,7 +296,9 @@ "failed": false, "result": { "ansible_facts": { - "geheim": "admin" + "crypt": "ENCRYPTED_VAULT_VALUE_NOT_REPORTED", + "geheim": "admin", + "unsafe": "THIS IS {{ crypt }}\n" }, "changed": false },