summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--changelogs/fragments/66604-powershell-unc-paths.yml2
-rw-r--r--lib/ansible/plugins/shell/powershell.py16
-rw-r--r--test/units/plugins/shell/test_powershell.py10
3 files changed, 19 insertions, 9 deletions
diff --git a/changelogs/fragments/66604-powershell-unc-paths.yml b/changelogs/fragments/66604-powershell-unc-paths.yml
new file mode 100644
index 0000000000..a79bcc857a
--- /dev/null
+++ b/changelogs/fragments/66604-powershell-unc-paths.yml
@@ -0,0 +1,2 @@
+minor_changes:
+ - "powershell (shell plugin) - Fix `join_path` to support UNC paths (https://github.com/ansible/ansible/issues/66341)"
diff --git a/lib/ansible/plugins/shell/powershell.py b/lib/ansible/plugins/shell/powershell.py
index ee23147cc5..ca2d5ebf5b 100644
--- a/lib/ansible/plugins/shell/powershell.py
+++ b/lib/ansible/plugins/shell/powershell.py
@@ -22,6 +22,7 @@ import re
import shlex
import pkgutil
import xml.etree.ElementTree as ET
+import ntpath
from ansible.errors import AnsibleError
from ansible.module_utils._text import to_bytes, to_text
@@ -93,14 +94,13 @@ class ShellModule(ShellBase):
return ""
def join_path(self, *args):
- parts = []
- for arg in args:
- arg = self._unquote(arg).replace('/', '\\')
- parts.extend([a for a in arg.split('\\') if a])
- path = '\\'.join(parts)
- if path.startswith('~'):
- return path
- return path
+ # use normpath() to remove doubled slashed and convert forward to backslashes
+ parts = [ntpath.normpath(self._unquote(arg)) for arg in args]
+
+ # Becuase ntpath.join treats any component that begins with a backslash as an absolute path,
+ # we have to strip slashes from at least the beginning, otherwise join will ignore all previous
+ # path components except for the drive.
+ return ntpath.join(parts[0], *[part.strip('\\') for part in parts[1:]])
def get_remote_filename(self, pathname):
# powershell requires that script files end with .ps1
diff --git a/test/units/plugins/shell/test_powershell.py b/test/units/plugins/shell/test_powershell.py
index a73070c689..6da7ffd5e6 100644
--- a/test/units/plugins/shell/test_powershell.py
+++ b/test/units/plugins/shell/test_powershell.py
@@ -1,4 +1,4 @@
-from ansible.plugins.shell.powershell import _parse_clixml
+from ansible.plugins.shell.powershell import _parse_clixml, ShellModule
def test_parse_clixml_empty():
@@ -51,3 +51,11 @@ def test_parse_clixml_multiple_streams():
expected = b"hi info"
actual = _parse_clixml(multiple_stream, stream="Info")
assert actual == expected
+
+
+def test_join_path_unc():
+ pwsh = ShellModule()
+ unc_path_parts = ['\\\\host\\share\\dir1\\\\dir2\\', '\\dir3/dir4', 'dir5', 'dir6\\']
+ expected = '\\\\host\\share\\dir1\\dir2\\dir3\\dir4\\dir5\\dir6'
+ actual = pwsh.join_path(*unc_path_parts)
+ assert actual == expected