diff --git a/changelogs/fragments/win_template-dest-dir-fix.yaml b/changelogs/fragments/win_template-dest-dir-fix.yaml new file mode 100644 index 00000000000..84919d42a32 --- /dev/null +++ b/changelogs/fragments/win_template-dest-dir-fix.yaml @@ -0,0 +1,2 @@ +bugfixes: +- win_template - fix when specifying the dest option as a directory with and without the trailing slash https://github.com/ansible/ansible/issues/39886 diff --git a/lib/ansible/modules/windows/win_copy.ps1 b/lib/ansible/modules/windows/win_copy.ps1 index a4e4e38c828..e142e5a5a20 100644 --- a/lib/ansible/modules/windows/win_copy.ps1 +++ b/lib/ansible/modules/windows/win_copy.ps1 @@ -368,7 +368,7 @@ if ($copy_mode -eq "query") { } # the dest parameter is a directory, we need to append original_basename - if ($dest.EndsWith("/") -or $dest.EndsWith("`\")) { + if ($dest.EndsWith("/") -or $dest.EndsWith("`\") -or (Test-Path -Path $dest -PathType Container)) { $remote_dest = Join-Path -Path $dest -ChildPath $original_basename $parent_dir = Split-Path -Path $remote_dest diff --git a/lib/ansible/modules/windows/win_file.ps1 b/lib/ansible/modules/windows/win_file.ps1 index 3399b5e30bb..5ff30982ab0 100644 --- a/lib/ansible/modules/windows/win_file.ps1 +++ b/lib/ansible/modules/windows/win_file.ps1 @@ -15,6 +15,12 @@ $check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -default $path = Get-AnsibleParam -obj $params -name "path" -type "path" -failifempty $true -aliases "dest","name" $state = Get-AnsibleParam -obj $params -name "state" -type "str" -validateset "absent","directory","file","touch" +# used in template/copy when dest is the path to a dir and source is a file +$original_basename = Get-AnsibleParam -obj $params -name "original_basename" -type "str" +if ((Test-Path -Path $path -PathType Container) -and ($null -ne $original_basename)) { + $path = Join-Path -Path $path -ChildPath $original_basename +} + $result = @{ changed = $false } diff --git a/test/integration/targets/win_template/tasks/main.yml b/test/integration/targets/win_template/tasks/main.yml index 1aa7995aff9..cd1829dfc4f 100644 --- a/test/integration/targets/win_template/tasks/main.yml +++ b/test/integration/targets/win_template/tasks/main.yml @@ -119,6 +119,105 @@ that: - '"FC: no differences encountered" in diff_result.stdout' +- name: create template dest directory + win_file: + path: '{{win_output_dir}}\directory' + state: directory + +- name: template src file to directory with backslash (check mode) + win_template: + src: foo.j2 + dest: '{{win_output_dir}}\directory\' + check_mode: yes + register: template_to_dir_backslash_check + +- name: get result of template src file to directory with backslash (check_mode) + win_stat: + path: '{{win_output_dir}}\directory\foo.j2' + register: template_to_dir_backslash_result_check + +- name: assert template src file to directory with backslash (check mode) + assert: + that: + - template_to_dir_backslash_check is changed + - not template_to_dir_backslash_result_check.stat.exists + +- name: template src file to directory with backslash + win_template: + src: foo.j2 + dest: '{{win_output_dir}}\directory\' + register: template_to_dir_backslash + +- name: get result of template src file to directory with backslash + win_stat: + path: '{{win_output_dir}}\directory\foo.j2' + register: template_to_dir_backslash_result + +- name: assert template src file to directory with backslash + assert: + that: + - template_to_dir_backslash is changed + - template_to_dir_backslash_result.stat.exists + - template_to_dir_backslash_result.stat.checksum == 'ed4f166b2937875ecad39c06648551f5af0b56d3' + +- name: template src file to directory with backslash (idempotent) + win_template: + src: foo.j2 + dest: '{{win_output_dir}}\directory\' + register: template_to_dir_backslash_again + +- name: assert template src file to directory with backslash (idempotent) + assert: + that: + - not template_to_dir_backslash_again is changed + +- name: template src file to directory (check mode) + win_template: + src: another_foo.j2 + dest: '{{win_output_dir}}\directory' + check_mode: yes + register: template_to_dir_check + +- name: get result of template src file to directory (check_mode) + win_stat: + path: '{{win_output_dir}}\directory\another_foo.j2' + register: template_to_dir_result_check + +- name: assert template src file to directory (check mode) + assert: + that: + - template_to_dir_check is changed + - not template_to_dir_result_check.stat.exists + +- name: template src file to directory + win_template: + src: another_foo.j2 + dest: '{{win_output_dir}}\directory' + register: template_to_dir + +- name: get result of template src file to directory + win_stat: + path: '{{win_output_dir}}\directory\another_foo.j2' + register: template_to_dir_result + +- name: assert template src file to directory with + assert: + that: + - template_to_dir is changed + - template_to_dir_result.stat.exists + - template_to_dir_result.stat.checksum == 'b10b6f27290d554a77da2457b2ccd7d6de86b920' + +- name: template src file to directory (idempotent) + win_template: + src: another_foo.j2 + dest: '{{win_output_dir}}\directory' + register: template_to_dir_again + +- name: assert template src file to directory (idempotent) + assert: + that: + - not template_to_dir_again is changed + # VERIFY MODE # can't set file mode on windows so commenting this test out #- name: set file mode diff --git a/test/integration/targets/win_template/templates/another_foo.j2 b/test/integration/targets/win_template/templates/another_foo.j2 new file mode 100644 index 00000000000..4ee9bca2d76 --- /dev/null +++ b/test/integration/targets/win_template/templates/another_foo.j2 @@ -0,0 +1,3 @@ +ABC +{{ templated_var }} +DEF