Add vaulted_file test (#83717)
* Add vaulted_file test * fix is_encrypted_file while we are here Co-authored-by: Martin Krizek <martin.krizek@gmail.com>
This commit is contained in:
5
changelogs/fragments/vaulted_file_and_fixes.yml
Normal file
5
changelogs/fragments/vaulted_file_and_fixes.yml
Normal file
@ -0,0 +1,5 @@
|
||||
bugfixes:
|
||||
- vault.is_encrypted_file is now optimized to be called in runtime and not for being called in tests
|
||||
- vault_encrypted test documentation, name and examples have been fixed, other parts were clarified
|
||||
minor_changes:
|
||||
- vaulted_file test filter added, to test if the provided path is an 'Ansible vaulted' file
|
||||
@ -18,7 +18,7 @@ from ansible.module_utils.six import binary_type, text_type
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
||||
from ansible.parsing.quoting import unquote
|
||||
from ansible.parsing.utils.yaml import from_yaml
|
||||
from ansible.parsing.vault import VaultLib, b_HEADER, is_encrypted, is_encrypted_file, parse_vaulttext_envelope, PromptVaultSecret
|
||||
from ansible.parsing.vault import VaultLib, is_encrypted, is_encrypted_file, parse_vaulttext_envelope, PromptVaultSecret
|
||||
from ansible.utils.path import unfrackpath
|
||||
from ansible.utils.display import Display
|
||||
|
||||
@ -388,7 +388,7 @@ class DataLoader:
|
||||
# Limit how much of the file is read since we do not know
|
||||
# whether this is a vault file and therefore it could be very
|
||||
# large.
|
||||
if is_encrypted_file(f, count=len(b_HEADER)):
|
||||
if is_encrypted_file(f):
|
||||
# if the file is encrypted and no password was specified,
|
||||
# the decrypt call would throw an error, but we check first
|
||||
# since the decrypt function doesn't know the file name
|
||||
|
||||
@ -103,15 +103,17 @@ def is_encrypted(data):
|
||||
return False
|
||||
|
||||
|
||||
def is_encrypted_file(file_obj, start_pos=0, count=-1):
|
||||
def is_encrypted_file(file_obj, start_pos=0, count=len(b_HEADER)):
|
||||
"""Test if the contents of a file obj are a vault encrypted data blob.
|
||||
|
||||
:arg file_obj: A file object that will be read from.
|
||||
:kwarg start_pos: A byte offset in the file to start reading the header
|
||||
from. Defaults to 0, the beginning of the file.
|
||||
:kwarg count: Read up to this number of bytes from the file to determine
|
||||
if it looks like encrypted vault data. The default is -1, read to the
|
||||
end of file.
|
||||
if it looks like encrypted vault data. The default is the size of the
|
||||
the vault header, which is what is needed most times.
|
||||
For some IO classes, or files that don't begin with the vault itself,
|
||||
set to -1 to read to the end of file.
|
||||
:returns: True if the file looks like a vault file. Otherwise, False.
|
||||
"""
|
||||
# read the header and reset the file stream to where it started
|
||||
|
||||
@ -25,8 +25,9 @@ from collections.abc import MutableMapping, MutableSequence
|
||||
from ansible.module_utils.compat.version import LooseVersion, StrictVersion
|
||||
|
||||
from ansible import errors
|
||||
from ansible.module_utils.common.text.converters import to_native, to_text
|
||||
from ansible.module_utils.common.text.converters import to_native, to_text, to_bytes
|
||||
from ansible.module_utils.parsing.convert_bool import boolean
|
||||
from ansible.parsing.vault import is_encrypted_file
|
||||
from ansible.utils.display import Display
|
||||
from ansible.utils.version import SemanticVersion
|
||||
|
||||
@ -143,6 +144,18 @@ def vault_encrypted(value):
|
||||
return getattr(value, '__ENCRYPTED__', False) and value.is_encrypted()
|
||||
|
||||
|
||||
def vaulted_file(value):
|
||||
"""Evaluate whether a file is a vault
|
||||
|
||||
.. versionadded:: 2.18
|
||||
"""
|
||||
try:
|
||||
with open(to_bytes(value), 'rb') as f:
|
||||
return is_encrypted_file(f)
|
||||
except (OSError, IOError) as e:
|
||||
raise errors.AnsibleFilterError(f"Cannot test if the file {value} is a vault", orig_exc=e)
|
||||
|
||||
|
||||
def match(value, pattern='', ignorecase=False, multiline=False):
|
||||
''' Perform a `re.match` returning a boolean '''
|
||||
return regex(value, pattern, ignorecase, multiline, 'match')
|
||||
@ -282,4 +295,5 @@ class TestModule(object):
|
||||
|
||||
# vault
|
||||
'vault_encrypted': vault_encrypted,
|
||||
'vaulted_file': vaulted_file,
|
||||
}
|
||||
|
||||
@ -1,18 +1,18 @@
|
||||
DOCUMENTATION:
|
||||
name: truthy
|
||||
name: vault_encrypted
|
||||
author: Ansible Core
|
||||
version_added: "2.10"
|
||||
short_description: Is this an encrypted vault
|
||||
short_description: Is this an encrypted vault string
|
||||
description:
|
||||
- Verifies if the input is an Ansible vault.
|
||||
- Verifies if the input string is an Ansible vault or not
|
||||
options:
|
||||
_input:
|
||||
description: The possible vault.
|
||||
description: The possible vault string
|
||||
type: string
|
||||
required: True
|
||||
EXAMPLES: |
|
||||
thisisfalse: '{{ "any string" is ansible_vault }}'
|
||||
thisistrue: '{{ "$ANSIBLE_VAULT;1.2;AES256;dev...." is ansible_vault }}'
|
||||
thisisfalse: '{{ "any string" is vault_encryped}}'
|
||||
thisistrue: '{{ "$ANSIBLE_VAULT;1.2;AES256;dev...." is vault_encrypted}}'
|
||||
RETURN:
|
||||
_value:
|
||||
description: Returns V(True) if the input is a valid ansible vault, V(False) otherwise.
|
||||
|
||||
19
lib/ansible/plugins/test/vaulted_file.yml
Normal file
19
lib/ansible/plugins/test/vaulted_file.yml
Normal file
@ -0,0 +1,19 @@
|
||||
DOCUMENTATION:
|
||||
name: vaulted_file
|
||||
author: Ansible Core
|
||||
version_added: "2.18"
|
||||
short_description: Is this file an encrypted vault
|
||||
description:
|
||||
- Verifies if the input path is an Ansible vault file.
|
||||
options:
|
||||
_input:
|
||||
description: The path to the possible vault.
|
||||
type: path
|
||||
required: True
|
||||
EXAMPLES: |
|
||||
thisisfalse: '{{ "/etc/hosts" is vaulted_file}}'
|
||||
thisistrue: '{{ "/path/to/vaulted/file" is vaulted_file}}'
|
||||
RETURN:
|
||||
_value:
|
||||
description: Returns V(True) if the path is a valid ansible vault, V(False) otherwise.
|
||||
type: boolean
|
||||
1
test/integration/targets/test_core/files/notvault
Normal file
1
test/integration/targets/test_core/files/notvault
Normal file
@ -0,0 +1 @@
|
||||
this is not a vault!!!
|
||||
6
test/integration/targets/test_core/files/vault1
Normal file
6
test/integration/targets/test_core/files/vault1
Normal file
@ -0,0 +1,6 @@
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
36383565336439373638626535313963373838613433343434663465656531316530663865363434
|
||||
3137636638393164646537643034303962633365613463310a303164353037663062376539313834
|
||||
65303131346266643934306364653063663061326165323737666636633363383337393731613030
|
||||
3164613334616465620a386234323862623764363834336364336662313932633866303262646565
|
||||
3861
|
||||
6
test/integration/targets/test_core/files/vault2
Normal file
6
test/integration/targets/test_core/files/vault2
Normal file
@ -0,0 +1,6 @@
|
||||
$ANSIBLE_VAULT;1.2;AES256;yolo
|
||||
61303130346664303063346433663231333561616535623536613465663137626332633339326666
|
||||
3565393632323837663930656461643266663634643332300a343030333136353966636537326537
|
||||
36383536386164373565636335316436316538313135346264383561316333386461343262323766
|
||||
6335663033373666370a316432313733303338363936313364663532313335383239646561313864
|
||||
6663
|
||||
@ -361,3 +361,10 @@
|
||||
that:
|
||||
- vaulted_value is vault_encrypted
|
||||
- inventory_hostname is not vault_encrypted
|
||||
|
||||
- name: Check vaulted_file test
|
||||
assert:
|
||||
that:
|
||||
- "'files/notvault' is not vaulted_file"
|
||||
- "'files/vault1' is vaulted_file"
|
||||
- "'files/vault2' is vaulted_file"
|
||||
|
||||
@ -450,12 +450,12 @@ class TestVaultIsEncryptedFile(unittest.TestCase):
|
||||
data = u"$ANSIBLE_VAULT;9.9;TEST\n%s" % u"ァ ア ィ イ ゥ ウ ェ エ ォ オ カ ガ キ ギ ク グ ケ "
|
||||
b_data = to_bytes(data)
|
||||
b_data_fo = io.BytesIO(b_data)
|
||||
self.assertFalse(vault.is_encrypted_file(b_data_fo))
|
||||
self.assertFalse(vault.is_encrypted_file(b_data_fo, count=-1))
|
||||
|
||||
def test_text_file_handle_invalid(self):
|
||||
data = u"$ANSIBLE_VAULT;9.9;TEST\n%s" % u"ァ ア ィ イ ゥ ウ ェ エ ォ オ カ ガ キ ギ ク グ ケ "
|
||||
data_fo = io.StringIO(data)
|
||||
self.assertFalse(vault.is_encrypted_file(data_fo))
|
||||
self.assertFalse(vault.is_encrypted_file(data_fo, count=-1))
|
||||
|
||||
def test_file_already_read_from_finds_header(self):
|
||||
b_data = b"$ANSIBLE_VAULT;9.9;TEST\n%s" % hexlify(b"ansible\ntesting\nfile pos")
|
||||
|
||||
Reference in New Issue
Block a user