summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Coca <bcoca@users.noreply.github.com>2021-04-05 10:16:45 -0400
committerGitHub <noreply@github.com>2021-04-05 09:16:45 -0500
commit1995b1b6e0a4f1812ade88317786da5ee2926a24 (patch)
treec4cee60bd975429507b8957fc964515bbecb4f1f
parent7683dfb7278afa24ee0d6d53968110b8bd467641 (diff)
downloadansible-1995b1b6e0a4f1812ade88317786da5ee2926a24.tar.gz
find - set proper default based on use_regex (#73961) (#73965)
When using "use_regex: yes" and setting an excludes: without specifying a pattern: the existing code passes the file-glob '*' to the regex matcher. This results in an internal invalid-regex exception being thrown. This maintains the old semantics of a default match-all for pattern: but switches the default to '.*' when use_regex is specified. The code made sense as-is before excludes: was added (2.5). In that case, it made no sense to set use_regex but *not* set a pattern. However, with excludes: it now makes sense to only want to exclude a given regex but not specify a specific matching pattern. Closes: #50067 * moved change to new location added changelog * Update lib/ansible/modules/find.py Co-authored-by: Ian Wienand <iwienand@redhat.com> (cherry picked from commit 089d0a0508a470799d099d95fc371e66756a00b3) * Fix up bad rebase, nuke duplicate "elements:" lines Signed-off-by: Rick Elrod <rick@elrod.me> Co-authored-by: Rick Elrod <rick@elrod.me> Co-authored-by: Brian Coca <bcoca@users.noreply.github.com> Co-authored-by: Sam Doran <sdoran@redhat.com>
-rw-r--r--changelogs/fragments/fix_find_default.yml2
-rw-r--r--lib/ansible/modules/find.py21
-rw-r--r--test/integration/targets/find/tasks/main.yml22
3 files changed, 40 insertions, 5 deletions
diff --git a/changelogs/fragments/fix_find_default.yml b/changelogs/fragments/fix_find_default.yml
new file mode 100644
index 0000000000..b49a88da82
--- /dev/null
+++ b/changelogs/fragments/fix_find_default.yml
@@ -0,0 +1,2 @@
+bugfixes:
+ - find - fix default pattern when use_regex is true (https://github.com/ansible/ansible/issues/50067).
diff --git a/lib/ansible/modules/find.py b/lib/ansible/modules/find.py
index b831e86eec..1aebaf9be0 100644
--- a/lib/ansible/modules/find.py
+++ b/lib/ansible/modules/find.py
@@ -29,7 +29,7 @@ options:
first letter of any of those words (e.g., "1w").
type: str
patterns:
- default: '*'
+ default: []
description:
- One or more (shell or regex) patterns, which type is controlled by C(use_regex) option.
- The patterns restrict the list of files to be returned to those whose basenames match at
@@ -41,18 +41,19 @@ options:
- This parameter expects a list, which can be either comma separated or YAML. If any of the
patterns contain a comma, make sure to put them in a list to avoid splitting the patterns
in undesirable ways.
+ - Defaults to '*' when C(use_regex=False), or '.*' when C(use_regex=True).
type: list
- aliases: [ pattern ]
elements: str
+ aliases: [ pattern ]
excludes:
description:
- One or more (shell or regex) patterns, which type is controlled by C(use_regex) option.
- Items whose basenames match an C(excludes) pattern are culled from C(patterns) matches.
Multiple patterns can be specified using a list.
type: list
+ elements: str
aliases: [ exclude ]
version_added: "2.5"
- elements: str
contains:
description:
- A regular expression or pattern which should be matched against the file content.
@@ -62,8 +63,8 @@ options:
- List of paths of directories to search. All paths must be fully qualified.
type: list
required: true
- aliases: [ name, path ]
elements: str
+ aliases: [ name, path ]
file_type:
description:
- Type of file to select.
@@ -360,7 +361,7 @@ def main():
module = AnsibleModule(
argument_spec=dict(
paths=dict(type='list', required=True, aliases=['name', 'path'], elements='str'),
- patterns=dict(type='list', default=['*'], aliases=['pattern'], elements='str'),
+ patterns=dict(type='list', default=[], aliases=['pattern'], elements='str'),
excludes=dict(type='list', aliases=['exclude'], elements='str'),
contains=dict(type='str'),
file_type=dict(type='str', default="file", choices=['any', 'directory', 'file', 'link']),
@@ -379,6 +380,16 @@ def main():
params = module.params
+ # Set the default match pattern to either a match-all glob or
+ # regex depending on use_regex being set. This makes sure if you
+ # set excludes: without a pattern pfilter gets something it can
+ # handle.
+ if not params['patterns']:
+ if params['use_regex']:
+ params['patterns'] = ['.*']
+ else:
+ params['patterns'] = ['*']
+
filelist = []
if params['age'] is None:
diff --git a/test/integration/targets/find/tasks/main.yml b/test/integration/targets/find/tasks/main.yml
index 6879404d88..d38daf44aa 100644
--- a/test/integration/targets/find/tasks/main.yml
+++ b/test/integration/targets/find/tasks/main.yml
@@ -139,3 +139,25 @@
# dir contents are considered until the depth exceeds the requested depth
# there are 6 files/directories in the requested depth and 4 that exceed it by 1
- files_with_depth.examined == 10
+
+- name: exclude with regex
+ find:
+ paths: "{{ output_dir_test }}"
+ recurse: yes
+ use_regex: true
+ exclude: .*\.ogg
+ register: find_test3
+# Note that currently sane ways of doing this with map() or
+# selectattr() aren't available in centos6 era jinja2 ...
+- set_fact:
+ find_test3_list: >-
+ [ {% for f in find_test3.files %}
+ {{ f.path }}
+ {% if not loop.last %},{% endif %}
+ {% endfor %}
+ ]
+- debug: var=find_test3_list
+- name: assert we skipped the ogg file
+ assert:
+ that:
+ - '"{{ output_dir_test }}/e/f/g/h/8.ogg" not in find_test3_list'