From d4882f67e8972c75ce9ff44657c5800b42593c71 Mon Sep 17 00:00:00 2001 From: s-hertel <19572925+s-hertel@users.noreply.github.com> Date: Fri, 20 Aug 2021 14:30:18 -0400 Subject: [PATCH 1/4] Try to find any valid vault id before raising an exception --- lib/ansible/cli/__init__.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/lib/ansible/cli/__init__.py b/lib/ansible/cli/__init__.py index 0ffafc5a69e457..38a5e96683cdd9 100644 --- a/lib/ansible/cli/__init__.py +++ b/lib/ansible/cli/__init__.py @@ -175,6 +175,7 @@ def setup_vault_secrets(loader, vault_ids, vault_password_files=None, create_new_password, auto_prompt=auto_prompt) + last_exception = found_vault_secret = None for vault_id_slug in vault_ids: vault_id_name, vault_id_value = CLI.split_vault_id(vault_id_slug) if vault_id_value in ['prompt', 'prompt_ask_vault_pass']: @@ -198,6 +199,7 @@ def setup_vault_secrets(loader, vault_ids, vault_password_files=None, display.warning('Error in vault password prompt (%s): %s' % (vault_id_name, exc)) raise + found_vault_secret = True vault_secrets.append((built_vault_id, prompted_vault_secret)) # update loader with new secrets incrementally, so we can load a vault password @@ -208,9 +210,15 @@ def setup_vault_secrets(loader, vault_ids, vault_password_files=None, # assuming anything else is a password file display.vvvvv('Reading vault password file: %s' % vault_id_value) # read vault_pass from a file - file_vault_secret = get_file_vault_secret(filename=vault_id_value, - vault_id=vault_id_name, - loader=loader) + try: + file_vault_secret = get_file_vault_secret(filename=vault_id_value, + vault_id=vault_id_name, + loader=loader) + except AnsibleError as exc: + display.warning('Error getting secret from vault password file (%s): %s' % (vault_id_name, to_text(exc))) + last_exception = exc + continue + found_vault_secret = True # an invalid password file will error globally try: @@ -227,6 +235,10 @@ def setup_vault_secrets(loader, vault_ids, vault_password_files=None, # update loader with as-yet-known vault secrets loader.set_vault_secrets(vault_secrets) + # No valid vault secrets and at least one error + if last_exception and not found_vault_secret: + raise last_exception + return vault_secrets @staticmethod From 94e4e35aea0eb7a3a6f8723cbbddaec9b17635cb Mon Sep 17 00:00:00 2001 From: s-hertel <19572925+s-hertel@users.noreply.github.com> Date: Fri, 20 Aug 2021 14:50:49 -0400 Subject: [PATCH 2/4] changelog --- .../75540-warn-invalid-configured-vault-secret-files.yaml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelogs/fragments/75540-warn-invalid-configured-vault-secret-files.yaml diff --git a/changelogs/fragments/75540-warn-invalid-configured-vault-secret-files.yaml b/changelogs/fragments/75540-warn-invalid-configured-vault-secret-files.yaml new file mode 100644 index 00000000000000..b51e0c844c6cf1 --- /dev/null +++ b/changelogs/fragments/75540-warn-invalid-configured-vault-secret-files.yaml @@ -0,0 +1,2 @@ +bugfixes: + - vault - Warn instead of fail for missing vault IDs if at least one valid vault secret is found. From d3ab65d414cf9b59708b4574229d08c4372236dd Mon Sep 17 00:00:00 2001 From: s-hertel <19572925+s-hertel@users.noreply.github.com> Date: Mon, 23 Aug 2021 17:20:07 -0400 Subject: [PATCH 3/4] Add a test do the same for errors during vault password file loading --- lib/ansible/cli/__init__.py | 9 +++++---- test/integration/targets/ansible-vault/runme.sh | 8 +++++++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/ansible/cli/__init__.py b/lib/ansible/cli/__init__.py index 38a5e96683cdd9..cf1632395e51b8 100644 --- a/lib/ansible/cli/__init__.py +++ b/lib/ansible/cli/__init__.py @@ -218,15 +218,15 @@ def setup_vault_secrets(loader, vault_ids, vault_password_files=None, display.warning('Error getting secret from vault password file (%s): %s' % (vault_id_name, to_text(exc))) last_exception = exc continue - found_vault_secret = True - # an invalid password file will error globally try: file_vault_secret.load() except AnsibleError as exc: display.warning('Error in vault password file loading (%s): %s' % (vault_id_name, to_text(exc))) - raise + last_exception = exc + continue + found_vault_secret = True if vault_id_name: vault_secrets.append((vault_id_name, file_vault_secret)) else: @@ -235,7 +235,8 @@ def setup_vault_secrets(loader, vault_ids, vault_password_files=None, # update loader with as-yet-known vault secrets loader.set_vault_secrets(vault_secrets) - # No valid vault secrets and at least one error + # An invalid or missing password file will error globally + # if no valid vault secret was found. if last_exception and not found_vault_secret: raise last_exception diff --git a/test/integration/targets/ansible-vault/runme.sh b/test/integration/targets/ansible-vault/runme.sh index e3b21d7f579d8d..4fc0f4867307cd 100755 --- a/test/integration/targets/ansible-vault/runme.sh +++ b/test/integration/targets/ansible-vault/runme.sh @@ -521,4 +521,10 @@ ansible-playbook -i ../../inventory -v "$@" --vault-password-file vault-password # Ensure we don't leave unencrypted temp files dangling ansible-playbook -v "$@" --vault-password-file vault-password test_dangling_temp.yml -ansible-playbook "$@" --vault-password-file vault-password single_vault_as_string.yml \ No newline at end of file +ansible-playbook "$@" --vault-password-file vault-password single_vault_as_string.yml + +# Test that only one accessible vault password is required +touch "${MYTMPDIR}/unreadable" +sudo chmod 000 "${MYTMPDIR}/unreadable" +ANSIBLE_VAULT_IDENTITY_LIST="id1@./nonexistent, id2@${MYTMPDIR}/unreadable, id3@./vault-password" ansible-vault encrypt_string content +[ "$?" -eq 0 ] From df495629af51a89066b634039a566362c44e1bbb Mon Sep 17 00:00:00 2001 From: s-hertel <19572925+s-hertel@users.noreply.github.com> Date: Wed, 25 Aug 2021 15:24:51 -0400 Subject: [PATCH 4/4] Improve the warning msg and tests --- lib/ansible/cli/__init__.py | 2 +- .../targets/ansible-vault/runme.sh | 23 +++++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/lib/ansible/cli/__init__.py b/lib/ansible/cli/__init__.py index cf1632395e51b8..2f3a08b852fe40 100644 --- a/lib/ansible/cli/__init__.py +++ b/lib/ansible/cli/__init__.py @@ -215,7 +215,7 @@ def setup_vault_secrets(loader, vault_ids, vault_password_files=None, vault_id=vault_id_name, loader=loader) except AnsibleError as exc: - display.warning('Error getting secret from vault password file (%s): %s' % (vault_id_name, to_text(exc))) + display.warning('Error getting vault password file (%s): %s' % (vault_id_name, to_text(exc))) last_exception = exc continue diff --git a/test/integration/targets/ansible-vault/runme.sh b/test/integration/targets/ansible-vault/runme.sh index 4fc0f4867307cd..09de6bd2685092 100755 --- a/test/integration/targets/ansible-vault/runme.sh +++ b/test/integration/targets/ansible-vault/runme.sh @@ -524,7 +524,26 @@ ansible-playbook -v "$@" --vault-password-file vault-password test_dangling_temp ansible-playbook "$@" --vault-password-file vault-password single_vault_as_string.yml # Test that only one accessible vault password is required +export ANSIBLE_VAULT_IDENTITY_LIST="id1@./nonexistent, id2@${MYTMPDIR}/unreadable, id3@./vault-password" + touch "${MYTMPDIR}/unreadable" sudo chmod 000 "${MYTMPDIR}/unreadable" -ANSIBLE_VAULT_IDENTITY_LIST="id1@./nonexistent, id2@${MYTMPDIR}/unreadable, id3@./vault-password" ansible-vault encrypt_string content -[ "$?" -eq 0 ] + +ansible-vault encrypt_string content +ansible-vault encrypt_string content --encrypt-vault-id id3 + +set +e + +# Try to use a missing vault password file +ansible-vault encrypt_string content --encrypt-vault-id id1 2>&1 | tee out.txt +test $? -ne 0 +grep out.txt -e '[WARNING]: Error getting vault password file (id1)' +grep out.txt -e "ERROR! Did not find a match for --encrypt-vault-id=id2 in the known vault-ids ['id3']" + +# Try to use an inaccessible vault password file +ansible-vault encrypt_string content --encrypt-vault-id id2 2>&1 | tee out.txt +test $? -ne 0 +grep out.txt -e "[WARNING]: Error in vault password file loading (id2)" +grep out.txt -e "ERROR! Did not find a match for --encrypt-vault-id=id2 in the known vault-ids ['id3']" + +set -e