From 1e2ce4c8ab3f4dfbd802a71216d2445482527480 Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Tue, 12 Sep 2017 09:51:48 -0700 Subject: [PATCH] support missing drive letters in PS `path` type (#29884) * fixes #26623 * Test-Path (and thus `-type path` in Get-AnsibleParam) fail on a nonexistent drive letter, since it can't be mapped to a PSProvider. * added support and basic smoke tests for --- .../Ansible.ModuleUtils.Legacy.psm1 | 12 +++++++++- .../targets/win_module_utils_legacy/aliases | 2 ++ .../library/testpath.ps1 | 9 ++++++++ .../win_module_utils_legacy/tasks/main.yml | 23 +++++++++++++++++++ 4 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 test/integration/targets/win_module_utils_legacy/aliases create mode 100644 test/integration/targets/win_module_utils_legacy/library/testpath.ps1 create mode 100644 test/integration/targets/win_module_utils_legacy/tasks/main.yml diff --git a/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.Legacy.psm1 b/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.Legacy.psm1 index 49ee868f39..a526211be0 100644 --- a/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.Legacy.psm1 +++ b/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.Legacy.psm1 @@ -207,7 +207,17 @@ Function Get-AnsibleParam($obj, $name, $default = $null, $resultobj = @{}, $fail $value = Expand-Environment($value) # Test if a valid path is provided if (-not (Test-Path -IsValid $value)) { - Fail-Json -obj $resultobj -message "Get-AnsibleParam: Parameter '$name' has an invalid path '$value' specified." + $path_invalid = $true + # could still be a valid-shaped path with a nonexistent drive letter + if ($value -match "^\w:") { + # rewrite path with a valid drive letter and recheck the shape- this might still fail, eg, a nonexistent non-filesystem PS path + if (Test-Path -IsValid $(@(Get-PSDrive -PSProvider Filesystem)[0].Name + $value.Substring(1))) { + $path_invalid = $false + } + } + if ($path_invalid) { + Fail-Json -obj $resultobj -message "Get-AnsibleParam: Parameter '$name' has an invalid path '$value' specified." + } } } elseif ($type -eq "str") { # Convert str types to real Powershell strings diff --git a/test/integration/targets/win_module_utils_legacy/aliases b/test/integration/targets/win_module_utils_legacy/aliases new file mode 100644 index 0000000000..d26fc09d51 --- /dev/null +++ b/test/integration/targets/win_module_utils_legacy/aliases @@ -0,0 +1,2 @@ +windows/ci/group1 +windows/ci/smoketest \ No newline at end of file diff --git a/test/integration/targets/win_module_utils_legacy/library/testpath.ps1 b/test/integration/targets/win_module_utils_legacy/library/testpath.ps1 new file mode 100644 index 0000000000..55cad70fb9 --- /dev/null +++ b/test/integration/targets/win_module_utils_legacy/library/testpath.ps1 @@ -0,0 +1,9 @@ +#powershell + +#Requires -Module Ansible.ModuleUtils.Legacy + +$params = Parse-Args $args + +$path = Get-AnsibleParam -Obj $params -Name path -Type path + +Exit-Json @{ path=$path } diff --git a/test/integration/targets/win_module_utils_legacy/tasks/main.yml b/test/integration/targets/win_module_utils_legacy/tasks/main.yml new file mode 100644 index 0000000000..85c81938cd --- /dev/null +++ b/test/integration/targets/win_module_utils_legacy/tasks/main.yml @@ -0,0 +1,23 @@ +# NB: these tests are just a placeholder until we have pester unit tests. +# They are being run as part of the Windows smoke tests. Please do not significantly +# increase the size of these tests, as the smoke tests need to remain fast. +# Any significant additions should be made to the (as yet nonexistent) PS module_utils unit tests. + +- name: find a nonexistent drive letter + raw: foreach($c in [char[]]([char]'D'..[char]'Z')) { If (-not $(Get-PSDrive $c -ErrorAction SilentlyContinue)) { return $c } } + register: bogus_driveletter + +- assert: + that: bogus_driveletter.stdout_lines[0] | length == 1 + +- name: test path shape validation + testpath: + path: "{{ item.path }}" + failed_when: path_shapes | failed != (item.should_fail | default(false)) + register: path_shapes + with_items: + - path: C:\Windows + - path: HKLM:\Software + - path: '{{ bogus_driveletter.stdout_lines[0] }}:\goodpath' + - path: '{{ bogus_driveletter.stdout_lines[0] }}:\badpath*%@:\blar' + should_fail: true