mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
win_stat - add follow option and fix broken tests (#51522)
* win_stat - add follow option and fix broken tests * fix docs issues
This commit is contained in:
parent
a9b459e406
commit
6a2aac487d
7 changed files with 138 additions and 19 deletions
2
changelogs/fragments/win_stat-follow.yaml
Normal file
2
changelogs/fragments/win_stat-follow.yaml
Normal file
|
@ -0,0 +1,2 @@
|
|||
minor_changes:
|
||||
- win_stat - added the ``follow`` module option to follow ``path`` when getting the file or directory info
|
|
@ -7,7 +7,7 @@
|
|||
#Requires -Module Ansible.ModuleUtils.FileUtil
|
||||
#Requires -Module Ansible.ModuleUtils.LinkUtil
|
||||
|
||||
function DateTo-Timestamp($start_date, $end_date) {
|
||||
function ConvertTo-Timestamp($start_date, $end_date) {
|
||||
if ($start_date -and $end_date) {
|
||||
return (New-TimeSpan -Start $start_date -End $end_date).TotalSeconds
|
||||
}
|
||||
|
@ -33,12 +33,34 @@ function Get-FileChecksum($path, $algorithm) {
|
|||
return $hash
|
||||
}
|
||||
|
||||
function Get-FileInfo {
|
||||
param([String]$Path, [Switch]$Follow)
|
||||
|
||||
$info = Get-AnsibleItem -Path $Path -ErrorAction SilentlyContinue
|
||||
$link_info = $null
|
||||
if ($null -ne $info) {
|
||||
try {
|
||||
$link_info = Get-Link -link_path $info.FullName
|
||||
} catch {
|
||||
$module.Warn("Failed to check/get link info for file: $($_.Exception.Message)")
|
||||
}
|
||||
|
||||
# If follow=true we want to follow the link all the way back to root object
|
||||
if ($Follow -and $null -ne $link_info -and $link_info.Type -in @("SymbolicLink", "JunctionPoint")) {
|
||||
$info, $link_info = Get-FileInfo -Path $link_info.AbsolutePath -Follow
|
||||
}
|
||||
}
|
||||
|
||||
return $info, $link_info
|
||||
}
|
||||
|
||||
$spec = @{
|
||||
options = @{
|
||||
path = @{ type='path'; required=$true; aliases=@( 'dest', 'name' ) }
|
||||
get_checksum = @{ type='bool'; default=$true }
|
||||
checksum_algorithm = @{ type='str'; default='sha1'; choices=@( 'md5', 'sha1', 'sha256', 'sha384', 'sha512' ) }
|
||||
get_md5 = @{ type='bool'; default=$false; removed_in_version='2.9' }
|
||||
follow = @{ type='bool'; default=$false }
|
||||
}
|
||||
supports_check_mode = $true
|
||||
}
|
||||
|
@ -49,10 +71,12 @@ $path = $module.Params.path
|
|||
$get_md5 = $module.Params.get_md5
|
||||
$get_checksum = $module.Params.get_checksum
|
||||
$checksum_algorithm = $module.Params.checksum_algorithm
|
||||
$follow = $module.Params.follow
|
||||
|
||||
$module.Result.stat = @{ exists=$false }
|
||||
|
||||
$info = Get-AnsibleItem -Path $path -ErrorAction SilentlyContinue
|
||||
Load-LinkUtils
|
||||
$info, $link_info = Get-FileInfo -Path $path -Follow:$follow
|
||||
If ($null -ne $info) {
|
||||
$epoch_date = Get-Date -Date "01/01/1970"
|
||||
$attributes = @()
|
||||
|
@ -77,9 +101,9 @@ If ($null -ne $info) {
|
|||
# lnk_target = islnk or isjunction Target of the symlink. Note that relative paths remain relative
|
||||
# lnk_source = islnk os isjunction Target of the symlink normalized for the remote filesystem
|
||||
hlnk_targets = @()
|
||||
creationtime = (DateTo-Timestamp -start_date $epoch_date -end_date $info.CreationTime)
|
||||
lastaccesstime = (DateTo-Timestamp -start_date $epoch_date -end_date $info.LastAccessTime)
|
||||
lastwritetime = (DateTo-Timestamp -start_date $epoch_date -end_date $info.LastWriteTime)
|
||||
creationtime = (ConvertTo-Timestamp -start_date $epoch_date -end_date $info.CreationTime)
|
||||
lastaccesstime = (ConvertTo-Timestamp -start_date $epoch_date -end_date $info.LastAccessTime)
|
||||
lastwritetime = (ConvertTo-Timestamp -start_date $epoch_date -end_date $info.LastWriteTime)
|
||||
# size = a file and directory - calculated below
|
||||
path = $info.FullName
|
||||
filename = $info.Name
|
||||
|
@ -100,8 +124,8 @@ If ($null -ne $info) {
|
|||
# values that are set according to the type of file
|
||||
if ($info.Attributes.HasFlag([System.IO.FileAttributes]::Directory)) {
|
||||
$stat.isdir = $true
|
||||
$share_info = Get-WmiObject -Class Win32_Share -Filter "Path='$($stat.path -replace '\\', '\\')'"
|
||||
if ($share_info -ne $null) {
|
||||
$share_info = Get-CimInstance -ClassName Win32_Share -Filter "Path='$($stat.path -replace '\\', '\\')'"
|
||||
if ($null -ne $share_info) {
|
||||
$stat.isshared = $true
|
||||
$stat.sharename = $share_info.Name
|
||||
}
|
||||
|
@ -137,13 +161,7 @@ If ($null -ne $info) {
|
|||
}
|
||||
|
||||
# Get symbolic link, junction point, hard link info
|
||||
Load-LinkUtils
|
||||
try {
|
||||
$link_info = Get-Link -link_path $info.FullName
|
||||
} catch {
|
||||
$module.Warn("Failed to check/get link info for file: $($_.Exception.Message)")
|
||||
}
|
||||
if ($link_info -ne $null) {
|
||||
if ($null -ne $link_info) {
|
||||
switch ($link_info.Type) {
|
||||
"SymbolicLink" {
|
||||
$stat.islnk = $true
|
||||
|
@ -175,3 +193,4 @@ If ($null -ne $info) {
|
|||
}
|
||||
|
||||
$module.ExitJson()
|
||||
|
||||
|
|
|
@ -52,6 +52,14 @@ options:
|
|||
default: sha1
|
||||
choices: [ md5, sha1, sha256, sha384, sha512 ]
|
||||
version_added: "2.3"
|
||||
follow:
|
||||
description:
|
||||
- Whether to follow symlinks or junction points.
|
||||
- In the case of C(path) pointing to another link, then that will
|
||||
be followed until no more links are found.
|
||||
type: bool
|
||||
default: no
|
||||
version_added: "2.8"
|
||||
seealso:
|
||||
- module: stat
|
||||
- module: win_file
|
||||
|
|
|
@ -509,7 +509,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
|
|||
path=path,
|
||||
follow=follow,
|
||||
get_checksum=checksum,
|
||||
checksum_algo='sha1',
|
||||
checksum_algorithm='sha1',
|
||||
)
|
||||
mystat = self._execute_module(module_name='stat', module_args=module_args, task_vars=all_vars,
|
||||
wrap_async=False)
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
cmd.exe /c mklink /H "{{win_stat_dir}}\nested\hard-link.ps1" "{{win_stat_dir}}\nested\hard-target.txt"
|
||||
cmd.exe /c mklink /J "{{win_stat_dir}}\junction-link" "{{win_stat_dir}}\junction-dest"
|
||||
cmd.exe /c mklink /D "{{win_stat_dir}}\nested\nested\link-rel" "..\..\link-dest"
|
||||
cmd.exe /c mklink /D "{{win_stat_dir}}\outer-link" "{{win_stat_dir}}\nested\nested\link-rel"
|
||||
|
||||
$date = Get-Date -Year 2016 -Month 11 -Day 1 -Hour 7 -Minute 10 -Second 5 -Millisecond 0
|
||||
Get-ChildItem -Path "{{win_stat_dir}}" -Recurse | ForEach-Object {
|
||||
|
|
|
@ -140,6 +140,7 @@
|
|||
- name: test win_stat on hard link file
|
||||
win_stat:
|
||||
path: '{{win_stat_dir}}\nested\hard-link.ps1'
|
||||
follow: True # just verifies we don't do any weird follow logic for hard links
|
||||
register: stat_hard_link
|
||||
|
||||
- name: check actual for hard link file
|
||||
|
@ -386,6 +387,37 @@
|
|||
- stat_file_symlink.stat.owner == 'BUILTIN\\Administrators'
|
||||
- stat_file_symlink.stat.path == win_stat_dir + '\\file-link.txt'
|
||||
|
||||
- name: test win_stat of file symlink with follow
|
||||
win_stat:
|
||||
path: '{{win_stat_dir}}\file-link.txt'
|
||||
follow: True
|
||||
register: stat_file_symlink_follow
|
||||
|
||||
- name: assert file system with follow actual
|
||||
assert:
|
||||
that:
|
||||
- stat_file_symlink_follow.stat.attributes == 'Archive'
|
||||
- stat_file_symlink_follow.stat.checksum == 'a9993e364706816aba3e25717850c26c9cd0d89d'
|
||||
- stat_file_symlink_follow.stat.creationtime is defined
|
||||
- stat_file_symlink_follow.stat.exists == True
|
||||
- stat_file_symlink_follow.stat.extension == '.ps1'
|
||||
- stat_file_symlink_follow.stat.filename == 'file.ps1'
|
||||
- stat_file_symlink_follow.stat.hlnk_targets == []
|
||||
- stat_file_symlink_follow.stat.isarchive == True
|
||||
- stat_file_symlink_follow.stat.isdir == False
|
||||
- stat_file_symlink_follow.stat.ishidden == False
|
||||
- stat_file_symlink_follow.stat.isjunction == False
|
||||
- stat_file_symlink_follow.stat.islnk == False
|
||||
- stat_file_symlink_follow.stat.isreadonly == False
|
||||
- stat_file_symlink_follow.stat.isreg == True
|
||||
- stat_file_symlink_follow.stat.isshared == False
|
||||
- stat_file_symlink_follow.stat.lastaccesstime is defined
|
||||
- stat_file_symlink_follow.stat.lastwritetime is defined
|
||||
- stat_file_symlink_follow.stat.md5 is not defined
|
||||
- stat_file_symlink_follow.stat.nlink == 1
|
||||
- stat_file_symlink_follow.stat.owner == 'BUILTIN\\Administrators'
|
||||
- stat_file_symlink_follow.stat.path == win_stat_dir + '\\nested\\file.ps1'
|
||||
|
||||
- name: test win_stat on relative symlink
|
||||
win_stat:
|
||||
path: '{{win_stat_dir}}\nested\nested\link-rel'
|
||||
|
@ -417,6 +449,36 @@
|
|||
- stat_rel_symlink.stat.checksum is not defined
|
||||
- stat_rel_symlink.stat.md5 is not defined
|
||||
|
||||
- name: test win_stat on relative multiple symlink with follow
|
||||
win_stat:
|
||||
path: '{{win_stat_dir}}\outer-link'
|
||||
follow: True
|
||||
register: stat_symlink_follow
|
||||
|
||||
- name: assert directory relative symlink actual
|
||||
assert:
|
||||
that:
|
||||
- stat_symlink_follow.stat.attributes == 'Directory'
|
||||
- stat_symlink_follow.stat.creationtime is defined
|
||||
- stat_symlink_follow.stat.exists == True
|
||||
- stat_symlink_follow.stat.filename == 'link-dest'
|
||||
- stat_symlink_follow.stat.hlnk_targets == []
|
||||
- stat_symlink_follow.stat.isarchive == False
|
||||
- stat_symlink_follow.stat.isdir == True
|
||||
- stat_symlink_follow.stat.ishidden == False
|
||||
- stat_symlink_follow.stat.isjunction == False
|
||||
- stat_symlink_follow.stat.islnk == False
|
||||
- stat_symlink_follow.stat.isreadonly == False
|
||||
- stat_symlink_follow.stat.isreg == False
|
||||
- stat_symlink_follow.stat.isshared == False
|
||||
- stat_symlink_follow.stat.lastaccesstime is defined
|
||||
- stat_symlink_follow.stat.lastwritetime is defined
|
||||
- stat_symlink_follow.stat.nlink == 1
|
||||
- stat_symlink_follow.stat.owner == 'BUILTIN\\Administrators'
|
||||
- stat_symlink_follow.stat.path == win_stat_dir + '\\link-dest'
|
||||
- stat_symlink_follow.stat.checksum is not defined
|
||||
- stat_symlink_follow.stat.md5 is not defined
|
||||
|
||||
- name: test win_stat on junction
|
||||
win_stat:
|
||||
path: '{{win_stat_dir}}\junction-link'
|
||||
|
@ -447,6 +509,35 @@
|
|||
- stat_junction_point.stat.path == win_stat_dir + '\\junction-link'
|
||||
- stat_junction_point.stat.size == 0
|
||||
|
||||
- name: test win_stat on junction with follow
|
||||
win_stat:
|
||||
path: '{{win_stat_dir}}\junction-link'
|
||||
follow: True
|
||||
register: stat_junction_point_follow
|
||||
|
||||
- name: assert junction with follow actual
|
||||
assert:
|
||||
that:
|
||||
- stat_junction_point_follow.stat.attributes == 'Directory'
|
||||
- stat_junction_point_follow.stat.creationtime is defined
|
||||
- stat_junction_point_follow.stat.exists == True
|
||||
- stat_junction_point_follow.stat.filename == 'junction-dest'
|
||||
- stat_junction_point_follow.stat.hlnk_targets == []
|
||||
- stat_junction_point_follow.stat.isarchive == False
|
||||
- stat_junction_point_follow.stat.isdir == True
|
||||
- stat_junction_point_follow.stat.ishidden == False
|
||||
- stat_junction_point_follow.stat.isjunction == False
|
||||
- stat_junction_point_follow.stat.islnk == False
|
||||
- stat_junction_point_follow.stat.isreadonly == False
|
||||
- stat_junction_point_follow.stat.isreg == False
|
||||
- stat_junction_point_follow.stat.isshared == False
|
||||
- stat_junction_point_follow.stat.lastaccesstime is defined
|
||||
- stat_junction_point_follow.stat.lastwritetime is defined
|
||||
- stat_junction_point_follow.stat.nlink == 1
|
||||
- stat_junction_point_follow.stat.owner == 'BUILTIN\\Administrators'
|
||||
- stat_junction_point_follow.stat.path == win_stat_dir + '\\junction-dest'
|
||||
- stat_junction_point_follow.stat.size == 0
|
||||
|
||||
- name: test win_stat module non-existent path
|
||||
win_stat:
|
||||
path: '{{win_stat_dir}}\this_file_should_not_exist'
|
||||
|
|
|
@ -66,8 +66,6 @@ lib/ansible/modules/windows/win_security_policy.ps1 PSUseApprovedVerbs
|
|||
lib/ansible/modules/windows/win_security_policy.ps1 PSUseDeclaredVarsMoreThanAssignments
|
||||
lib/ansible/modules/windows/win_shell.ps1 PSAvoidUsingCmdletAliases
|
||||
lib/ansible/modules/windows/win_shell.ps1 PSUseApprovedVerbs
|
||||
lib/ansible/modules/windows/win_stat.ps1 PSAvoidUsingWMICmdlet
|
||||
lib/ansible/modules/windows/win_stat.ps1 PSUseApprovedVerbs
|
||||
lib/ansible/modules/windows/win_unzip.ps1 PSAvoidUsingCmdletAliases
|
||||
lib/ansible/modules/windows/win_unzip.ps1 PSUseApprovedVerbs
|
||||
lib/ansible/modules/windows/win_uri.ps1 PSAvoidUsingEmptyCatchBlock
|
||||
|
|
Loading…
Reference in a new issue