Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fetch fails on Windows filenames containing dollar sign #62781

Closed
sckfranke opened this issue Sep 24, 2019 · 2 comments · Fixed by #71411
Closed

fetch fails on Windows filenames containing dollar sign #62781

sckfranke opened this issue Sep 24, 2019 · 2 comments · Fixed by #71411
Labels
affects_2.7 This issue/PR affects Ansible v2.7 bug This issue/PR relates to a bug. files Files category module This issue/PR relates to a module. python3 support:core This issue/PR relates to code supported by the Ansible Engineering Team. traceback This issue/PR includes a traceback. windows Windows community

Comments

@sckfranke
Copy link

SUMMARY

fetch module fails on Windows with file names containing dollar signs (winrm FETCH does not quote these from PowerShell). When using |quote or backslash-escaping the dollars, slurp, which is executed by fetch, does handle such paths correctly and therefore fails on pre-quoted ones.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

fetch

ANSIBLE VERSION
ansible 2.7.4
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/etc/ansible/plugins/modules', '/etc/venus/common/ansible/modules']
  ansible python module location = /usr/local/ansible/2.7/lib/python3.6/site-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 3.6.1 (default, Oct 24 2017, 05:44:23) [GCC 5.3.0]
CONFIGURATION
ANSIBLE_PIPELINING(/etc/ansible/ansible.cfg) = True
CACHE_PLUGIN(/etc/ansible/ansible.cfg) = jsonfile
CACHE_PLUGIN_CONNECTION(/etc/ansible/ansible.cfg) = /var/lib/ansible/facts
CACHE_PLUGIN_TIMEOUT(/etc/ansible/ansible.cfg) = 86400
DEFAULT_ACTION_PLUGIN_PATH(/etc/ansible/ansible.cfg) = ['/etc/ansible/plugins/action', '/etc/venus/common/ansible/action']
DEFAULT_CALLBACK_PLUGIN_PATH(/etc/ansible/ansible.cfg) = ['/etc/ansible/plugins/callback', '/etc/venus/common/ansible/callback']
DEFAULT_CALLBACK_WHITELIST(/etc/ansible/ansible.cfg) = ['log_plays', 'playbook_name', 'json']
DEFAULT_CONNECTION_PLUGIN_PATH(/etc/ansible/ansible.cfg) = ['/etc/ansible/plugins/connection', '/etc/venus/common/ansible/connection']
DEFAULT_FILTER_PLUGIN_PATH(/etc/ansible/ansible.cfg) = ['/etc/ansible/plugins/filter', '/etc/venus/common/ansible/filter']
DEFAULT_FORKS(/etc/ansible/ansible.cfg) = 30
DEFAULT_GATHERING(/etc/ansible/ansible.cfg) = smart
DEFAULT_HOST_LIST(/etc/ansible/ansible.cfg) = ['/etc/ansible/inventory/venus.yml', '/etc/ansible/inventory/hosts.yml']
DEFAULT_INVENTORY_PLUGIN_PATH(/etc/ansible/ansible.cfg) = ['/etc/ansible/plugins/inventory', '/etc/venus/common/ansible/inventory']
DEFAULT_LOG_PATH(/etc/ansible/ansible.cfg) = /var/log/ansible/ansible.log
DEFAULT_LOOKUP_PLUGIN_PATH(/etc/ansible/ansible.cfg) = ['/etc/ansible/plugins/lookup', '/etc/venus/common/ansible/lookup']
DEFAULT_MODULE_PATH(/etc/ansible/ansible.cfg) = ['/etc/ansible/plugins/modules', '/etc/venus/common/ansible/modules']
DEFAULT_POLL_INTERVAL(/etc/ansible/ansible.cfg) = 15
DEFAULT_ROLES_PATH(/etc/ansible/ansible.cfg) = ['/etc/ansible/roles']
DEFAULT_STDOUT_CALLBACK(/etc/ansible/ansible.cfg) = debug
DEFAULT_TRANSPORT(/etc/ansible/ansible.cfg) = venus
DEFAULT_VARS_PLUGIN_PATH(/etc/ansible/ansible.cfg) = ['/etc/ansible/plugins/vars', '/etc/venus/common/ansible/vars']
INVENTORY_ENABLED(/etc/ansible/ansible.cfg) = ['venus', 'yaml', 'advanced_host_list', 'host_list']
RETRY_FILES_ENABLED(/etc/ansible/ansible.cfg) = False
OS / ENVIRONMENT
  • Control host: CentOS 7.6
  • target: Microsoft Windows Server 2008 R2 Standard Service Pack 1
STEPS TO REPRODUCE

Create a file such as C:\Temp\file_with_$dollar.txt

- name: Get Logs
  hosts: all
  vars:
    log_files:
      - "C:/Temp/testfile_with_$dollar.txt"
  tasks:
  - name: touch test files
    win_file:
       path: "{{ item }}"
       state: touch
    with_items: "{{ log_files }}"
  - name: fetch log files
    fetch:
        src: "{{ item }}"
        dest: "{{ tmp_dir }}/{{ item | basename }}"
        flat: yes
      with_items: "{{ log_files }}"
EXPECTED RESULTS

File gets copied from Windows remote to localhost.

ACTUAL RESULTS
ansible-playbook 2.7.4
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/etc/ansible/plugins/modules', '/etc/venus/common/ansible/modules']
  ansible python module location = /usr/local/ansible/2.7/lib/python3.6/site-packages/ansible
  executable location = /usr/local/bin/ansible-playbook
  python version = 3.6.1 (default, Oct 24 2017, 05:44:23) [GCC 5.3.0]
Using /etc/ansible/ansible.cfg as config file
setting up inventory plugins
Parsed /etc/ansible/inventory/venus.yml inventory source with venus plugin
/etc/ansible/inventory/hosts.yml did not meet venus requirements, check plugin documentation if this is unexpected
Set default localhost to localhost
Parsed /etc/ansible/inventory/hosts.yml inventory source with yaml plugin
Loading callback plugin debug of type stdout, v2.0 from /usr/local/ansible/2.7/lib/python3.6/site-packages/ansible/plugins/callback/debug.py
Loading callback plugin log_plays of type notification, v2.0 from /usr/local/ansible/2.7/lib/python3.6/site-packages/ansible/plugins/callback/log_plays.py

PLAYBOOK: test.yml ***************************************************************************************************************************************************************************
1 plays in test.yml

PLAY [testclient] ****************************************************************************************************************************************************************************
META: ran handlers

TASK [touch test files] **********************************************************************************************************************************************************************
task path: /home/testuser/ansible/test.yml:7
Using module file /usr/local/ansible/2.7/lib/python3.6/site-packages/ansible/modules/windows/win_file.ps1
<testclient> ESTABLISH WINRM CONNECTION FOR USER: testuser@DOMAIN on PORT 5985 TO testclient
checking if winrm_host testclient is an IPv6 address
EXEC (via pipeline wrapper)
changed: [testclient] => (item=C:/Temp/testfile_with_$dollar.txt) => {
    "changed": true,
    "item": "C:/Temp/testfile_with_$dollar.txt"
}

TASK [fetch log files] ***********************************************************************************************************************************************************************
task path: /home/testuser/ansible/packages/co2mo/test.yml:12
Using module file /usr/local/ansible/2.7/lib/python3.6/site-packages/ansible/modules/windows/win_stat.ps1
<testclient> ESTABLISH WINRM CONNECTION FOR USER: testuser@DOMAIN on PORT 5985 TO testclient
checking if winrm_host testclient is an IPv6 address
EXEC (via pipeline wrapper)
<testclient> FETCH "C:\Temp\testfile_with_$dollar.txt" TO "/home/testuser/ansible/testfile_with_$dollar.txt"
Traceback (most recent call last):
  File "/usr/local/ansible/2.7/lib/python3.6/site-packages/ansible/plugins/connection/winrm.py", line 681, in fetch_file
    raise IOError(to_native(result.std_err))
OSError: #< CLIXML
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04"><S S="Error">The variable '$dollar' cannot be retrieved because it has not been set._x000D__x000A_</S><S S="Error">At line:2 char:32_x000D__x000A_</S><S S="Error">+ $path = "C:\Temp\testfile_with_$dollar.txt"_x000D__x000A_</S><S S="Error">+                                ~~~~~~~_x000D__x000A_</S><S S="Error">    + CategoryInfo          : InvalidOperation: (dollar:String) [], RuntimeExc _x000D__x000A_</S><S S="Error">   eption_x000D__x000A_</S><S S="Error">    + FullyQualifiedErrorId : VariableIsUndefined_x000D__x000A_</S><S S="Error"> _x000D__x000A_</S><S S="Error">The variable '$path' cannot be retrieved because it has not been set._x000D__x000A_</S><S S="Error">At line:3 char:21_x000D__x000A_</S><S S="Error">+ If (Test-Path -Path $path -PathType Leaf)_x000D__x000A_</S><S S="Error">+                     ~~~~~_x000D__x000A_</S><S S="Error">    + CategoryInfo          : InvalidOperation: (path:String) [], RuntimeExcep _x000D__x000A_</S><S S="Error">   tion_x000D__x000A_</S><S S="Error">    + FullyQualifiedErrorId : VariableIsUndefined_x000D__x000A_</S><S S="Error"> _x000D__x000A_</S></Objs>
fatal: [testclient]: FAILED! => {}

MSG:

failed to transfer file to "/home/testuser/ansible//testfile_with_$dollar.txt"


PLAY RECAP ***********************************************************************************************************************************************************************************
testclient                 : ok=1    changed=1    unreachable=0    failed=1   

When replacing src: "{{ item }}" with src: "{{ item|quote }}":

TASK [fetch log files] ***********************************************************************************************************************************************************************
task path: /home/testuser/ansible/test.yml:12
Using module file /usr/local/ansible/2.7/lib/python3.6/site-packages/ansible/modules/windows/win_stat.ps1
<testclient> ESTABLISH WINRM CONNECTION FOR USER: testuser@DOMAIN on PORT 5985 TO testclient
checking if winrm_host testclient is an IPv6 address
EXEC (via pipeline wrapper)
<testclient> FETCH "C:\Temp\testfile_with_$dollar.txt" TO "/home/testuser/ansible/testfile_with_$dollar.txt"
Traceback (most recent call last):
  File "/usr/local/ansible/2.7/lib/python3.6/site-packages/ansible/plugins/connection/winrm.py", line 681, in fetch_file
    raise IOError(to_native(result.std_err))
OSError: #< CLIXML
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04"><S S="Error">The variable '$dollar' cannot be retrieved because it has not been set._x000D__x000A_</S><S S="Error">At line:2 char:32_x000D__x000A_</S><S S="Error">+ $path = "C:\Temp\testfile_with_$dollar.txt"_x000D__x000A_</S><S S="Error">+                                ~~~~~~~_x000D__x000A_</S><S S="Error">    + CategoryInfo          : InvalidOperation: (dollar:String) [], RuntimeExc _x000D__x000A_</S><S S="Error">   eption_x000D__x000A_</S><S S="Error">    + FullyQualifiedErrorId : VariableIsUndefined_x000D__x000A_</S><S S="Error"> _x000D__x000A_</S><S S="Error">The variable '$path' cannot be retrieved because it has not been set._x000D__x000A_</S><S S="Error">At line:3 char:21_x000D__x000A_</S><S S="Error">+ If (Test-Path -Path $path -PathType Leaf)_x000D__x000A_</S><S S="Error">+                     ~~~~~_x000D__x000A_</S><S S="Error">    + CategoryInfo          : InvalidOperation: (path:String) [], RuntimeExcep _x000D__x000A_</S><S S="Error">   tion_x000D__x000A_</S><S S="Error">    + FullyQualifiedErrorId : VariableIsUndefined_x000D__x000A_</S><S S="Error"> _x000D__x000A_</S></Objs>
fatal: [testclient]: FAILED! => {}

When replacing src: "{{ item }}" with src: "{{ item|replace('$', '\\$') }}":

TASK [fetch log files] ***********************************************************************************************************************************************************************
task path: /home/testuser/ansible/test.yml:12
Using module file /usr/local/ansible/2.7/lib/python3.6/site-packages/ansible/modules/windows/win_stat.ps1
<testclient> ESTABLISH WINRM CONNECTION FOR USER: testuser@DOMAIN on PORT 5985 TO testclient
checking if winrm_host testclient is an IPv6 address
EXEC (via pipeline wrapper)
Using module file /usr/local/ansible/2.7/lib/python3.6/site-packages/ansible/modules/windows/slurp.ps1
EXEC (via pipeline wrapper)
failed: [testclient] (item=C:/Temp/testfile_with_$dollar.txt) => {
    "changed": false,
    "item": "C:/Temp/testfile_with_$dollar.txt"
}

MSG:

Path C:\Temp\testfile_with_\$dollar.txt is not found
WORKAROUND
    - name: create temporary copy of log files
      win_copy:
        remote_src: true
        src: "{{ item }}"
        dest: "{{ item | replace('$', 'DOLLAR') }}.transfer"
        force: no
      with_items: "{{ log_files }}"
    - name: fetch log files
      fetch:
        src: "{{ item | replace('$', 'DOLLAR') }}.transfer"
        dest: "{{ tmp_dir }}/{{ item | basename }}"
        flat: yes
      with_items: "{{ log_files }}"
    - name: remove temporary copy of log files
      win_file:
        path: "{{ item | replace('$', 'DOLLAR') }}.transfer"
        state: absent
      with_items: "{{ log_files }}"
@ansibot
Copy link
Contributor

ansibot commented Sep 24, 2019

Files identified in the description:

If these files are inaccurate, please update the component name section of the description or use the !component bot command.

click here for bot help

@ansibot ansibot added affects_2.7 This issue/PR affects Ansible v2.7 bug This issue/PR relates to a bug. files Files category module This issue/PR relates to a module. needs_triage Needs a first human triage before being processed. python3 support:core This issue/PR relates to code supported by the Ansible Engineering Team. traceback This issue/PR includes a traceback. labels Sep 24, 2019
@nitzmahone nitzmahone added windows Windows community and removed needs_triage Needs a first human triage before being processed. labels Oct 3, 2019
@ansibot
Copy link
Contributor

ansibot commented May 16, 2020

Files identified in the description:

If these files are incorrect, please update the component name section of the description or use the !component bot command.

click here for bot help

netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this issue Sep 8, 2020
v2.9.13
=======

Minor Changes
-------------
- Updated network integration auth timeout to 90 secs.
- ansible-test - Remove ``pytest < 6.0.0`` constraint for managed installations on Python 3.x now that pytest 6 is supported.
- known_hosts - fix reference to non-existent parameter in example (ansible/ansible#71417)

Security Fixes
--------------
- The fix for CVE-2020-1736 has been reverted. Users are encouraged to specify a ``mode`` parameter in their file-based tasks when the files being manipulated contain sensitive data.
- dnf - Previously, regardless of the ``disable_gpg_check`` option, packages were not GPG validated. They are now. (CVE-2020-14365)

Bugfixes
--------
- Confirmed commit fails with TypeError in IOS XR netconf plugin (ansible-collections/cisco.iosxr#74)
- Fix an exit code for a non-failing playbook (ansible/ansible#71306)
- Fix execution of the meta tasks 'clear_facts', 'clear_host_errors', 'end_play', 'end_host', and 'reset_connection' when the CLI flag '--flush-cache' is provided.
- Fix statistics reporting when rescue block contains another block (issue ansible/ansible#61253).
- Fixed Ansible reporting validate not supported by netconf server when enabled in netconf - (ansible-collections/ansible.netcommon#119).
- TOML inventory - Ensure we register dump functions for ``AnsibleUnsafe`` to support dumping unsafe values. Note that the TOML format has no functionality to mark that the data is unsafe for re-consumption. (ansible/ansible#71307)
- ansible-test units - fixed collection location code to work under pytest >= 6.0.0
- aws_acm_info - fix `KeyError` failure when retrieving keys with a `Failed` status (ansible-collections/community.aws#198)
- cron - cron file should not be empty after adding var (ansible/ansible#71207)
- mongodb_replicaset - fixes authentication to determine replicaset name (ansible-collections/community.mongodb#136).
- powershell - fix escaping of strings that broken modules like fetch when dealing with special chars - ansible/ansible#62781
- powershell - fix the CLIXML parser when it contains nested CLIXML objects - ansible/ansible#69550
- psrp - Use native PSRP mechanism when copying files to support custom endpoints
- setup - Add a null check for ``Win32_Bios.ReleaseData`` to avoid a failure when that value is not set - ansible/ansible#69736
- strftime filter - Input epoch is allowed to be a float (ansible/ansible#71257)
- systemd - fixed chroot usage on new versions of systemd, that broke because of upstream changes in systemctl output
- systemd - made the systemd module work correctly when the SYSTEMD_OFFLINE environment variable is set
- zabbix_host - fixed inventory_mode key error, which occurs with Zabbix 4.4.1 or more (ansible/ansible#65304).
- zabbix_proxy - fixed support for Zabbix 5.0
@ansible ansible locked and limited conversation to collaborators Sep 22, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
affects_2.7 This issue/PR affects Ansible v2.7 bug This issue/PR relates to a bug. files Files category module This issue/PR relates to a module. python3 support:core This issue/PR relates to code supported by the Ansible Engineering Team. traceback This issue/PR includes a traceback. windows Windows community
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants