win_find - Refactor for better performance and alignment to find (#65536)
* win_find - refactor to make more performance and use newer style * win_find - refactor for performance improvements and alignment to find * More path alignment to find * Fix yamllint error
This commit is contained in:
parent
96cbbdd59f
commit
fcdebe41e9
5 changed files with 867 additions and 679 deletions
2
changelogs/fragments/win_find-performance.yaml
Normal file
2
changelogs/fragments/win_find-performance.yaml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
minor_changes:
|
||||||
|
- win_find - Improve performance when scanning heavily nested directories and align behaviour to the ``find`` module.
|
|
@ -98,6 +98,10 @@ Noteworthy module changes
|
||||||
* :ref:`zabbix_action <zabbix_action_module>` no longer requires ``esc_period`` and ``event_source`` arguments when ``state=absent``.
|
* :ref:`zabbix_action <zabbix_action_module>` no longer requires ``esc_period`` and ``event_source`` arguments when ``state=absent``.
|
||||||
* :ref:`gitlab_user <gitlab_user_module>` no longer requires ``name``, ``email`` and ``password`` arguments when ``state=absent``.
|
* :ref:`gitlab_user <gitlab_user_module>` no longer requires ``name``, ``email`` and ``password`` arguments when ``state=absent``.
|
||||||
* :ref:`win_pester <win_pester_module>` no longer runs all ``*.ps1`` file in the directory specified due to it executing potentially unknown scripts. It will follow the default behaviour of only running tests for files that are like ``*.tests.ps1`` which is built into Pester itself
|
* :ref:`win_pester <win_pester_module>` no longer runs all ``*.ps1`` file in the directory specified due to it executing potentially unknown scripts. It will follow the default behaviour of only running tests for files that are like ``*.tests.ps1`` which is built into Pester itself
|
||||||
|
* :ref:`win_find <win_find_module>` has been refactored to better match the behaviour of the ``find`` module. Here is what has changed:
|
||||||
|
* When the directory specified by ``paths`` does not exist or is a file, it will no longer fail and will just warn the user
|
||||||
|
* Junction points are no longer reported as ``islnk``, use ``isjunction`` to properly report these files. This behaviour matches the :ref:`win_stat <win_stat_module>`
|
||||||
|
* Directories no longer return a ``size``, this matches the ``stat`` and ``find`` behaviour and has been removed due to the difficulties in correctly reporting the size of a directory
|
||||||
|
|
||||||
Plugins
|
Plugins
|
||||||
=======
|
=======
|
||||||
|
|
|
@ -3,357 +3,414 @@
|
||||||
# Copyright: (c) 2016, Ansible Project
|
# Copyright: (c) 2016, Ansible Project
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
#Requires -Module Ansible.ModuleUtils.Legacy
|
#AnsibleRequires -CSharpUtil Ansible.Basic
|
||||||
|
#Requires -Module Ansible.ModuleUtils.LinkUtil
|
||||||
|
|
||||||
$ErrorActionPreference = "Stop"
|
$spec = @{
|
||||||
|
options = @{
|
||||||
$params = Parse-Args -arguments $args -supports_check_mode $true
|
paths = @{ type = "list"; elements = "str"; required = $true }
|
||||||
$_remote_tmp = Get-AnsibleParam $params "_ansible_remote_tmp" -type "path" -default $env:TMP
|
age = @{ type = "str" }
|
||||||
|
age_stamp = @{ type = "str"; default = "mtime"; choices = "mtime", "ctime", "atime" }
|
||||||
$paths = Get-AnsibleParam -obj $params -name 'paths' -failifempty $true
|
file_type = @{ type = "str"; default = "file"; choices = "file", "directory" }
|
||||||
|
follow = @{ type = "bool"; default = $false }
|
||||||
$age = Get-AnsibleParam -obj $params -name 'age'
|
hidden = @{ type = "bool"; default = $false }
|
||||||
$age_stamp = Get-AnsibleParam -obj $params -name 'age_stamp' -default 'mtime' -ValidateSet 'mtime','ctime','atime'
|
patterns = @{ type = "list"; elements = "str"; aliases = "regex", "regexp" }
|
||||||
$file_type = Get-AnsibleParam -obj $params -name 'file_type' -default 'file' -ValidateSet 'file','directory'
|
recurse = @{ type = "bool"; default = $false }
|
||||||
$follow = Get-AnsibleParam -obj $params -name 'follow' -type "bool" -default $false
|
size = @{ type = "str" }
|
||||||
$hidden = Get-AnsibleParam -obj $params -name 'hidden' -type "bool" -default $false
|
use_regex = @{ type = "bool"; default = $false }
|
||||||
$patterns = Get-AnsibleParam -obj $params -name 'patterns' -aliases "regex","regexp"
|
get_checksum = @{ type = "bool"; default = $true }
|
||||||
$recurse = Get-AnsibleParam -obj $params -name 'recurse' -type "bool" -default $false
|
checksum_algorithm = @{ type = "str"; default = "sha1"; choices = "md5", "sha1", "sha256", "sha384", "sha512" }
|
||||||
$size = Get-AnsibleParam -obj $params -name 'size'
|
}
|
||||||
$use_regex = Get-AnsibleParam -obj $params -name 'use_regex' -type "bool" -default $false
|
supports_check_mode = $true
|
||||||
$get_checksum = Get-AnsibleParam -obj $params -name 'get_checksum' -type "bool" -default $true
|
|
||||||
$checksum_algorithm = Get-AnsibleParam -obj $params -name 'checksum_algorithm' -default 'sha1' -ValidateSet 'md5', 'sha1', 'sha256', 'sha384', 'sha512'
|
|
||||||
|
|
||||||
$result = @{
|
|
||||||
files = @()
|
|
||||||
examined = 0
|
|
||||||
matched = 0
|
|
||||||
changed = $false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# C# code to determine link target, copied from http://chrisbensen.blogspot.com.au/2010/06/getfinalpathnamebyhandle.html
|
$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec)
|
||||||
$symlink_util = @"
|
|
||||||
using System;
|
|
||||||
using System.Text;
|
|
||||||
using Microsoft.Win32.SafeHandles;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Ansible.Command {
|
$paths = $module.Params.paths
|
||||||
public class SymLinkHelper {
|
$age = $module.Params.age
|
||||||
private const int FILE_SHARE_WRITE = 2;
|
$age_stamp = $module.Params.age_stamp
|
||||||
private const int CREATION_DISPOSITION_OPEN_EXISTING = 3;
|
$file_type = $module.Params.file_type
|
||||||
private const int FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;
|
$follow = $module.Params.follow
|
||||||
|
$hidden = $module.Params.hidden
|
||||||
|
$patterns = $module.Params.patterns
|
||||||
|
$recurse = $module.Params.recurse
|
||||||
|
$size = $module.Params.size
|
||||||
|
$use_regex = $module.Params.use_regex
|
||||||
|
$get_checksum = $module.Params.get_checksum
|
||||||
|
$checksum_algorithm = $module.Params.checksum_algorithm
|
||||||
|
|
||||||
[DllImport("kernel32.dll", EntryPoint = "GetFinalPathNameByHandleW", CharSet = CharSet.Unicode, SetLastError = true)]
|
$module.Result.examined = 0
|
||||||
public static extern int GetFinalPathNameByHandle(IntPtr handle, [In, Out] StringBuilder path, int bufLen, int flags);
|
$module.Result.files = @()
|
||||||
|
$module.Result.matched = 0
|
||||||
|
|
||||||
[DllImport("kernel32.dll", EntryPoint = "CreateFileW", CharSet = CharSet.Unicode, SetLastError = true)]
|
Load-LinkUtils
|
||||||
public static extern SafeFileHandle CreateFile(string lpFileName, int dwDesiredAccess,
|
|
||||||
int dwShareMode, IntPtr SecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile);
|
|
||||||
|
|
||||||
public static string GetSymbolicLinkTarget(System.IO.DirectoryInfo symlink) {
|
Function Assert-Age {
|
||||||
SafeFileHandle directoryHandle = CreateFile(symlink.FullName, 0, 2, System.IntPtr.Zero, CREATION_DISPOSITION_OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, System.IntPtr.Zero);
|
Param (
|
||||||
if(directoryHandle.IsInvalid)
|
[System.IO.FileSystemInfo]$File,
|
||||||
throw new Win32Exception(Marshal.GetLastWin32Error());
|
[System.Int64]$Age,
|
||||||
|
[System.String]$AgeStamp
|
||||||
|
)
|
||||||
|
|
||||||
StringBuilder path = new StringBuilder(512);
|
$actual_age = switch ($AgeStamp) {
|
||||||
int size = GetFinalPathNameByHandle(directoryHandle.DangerousGetHandle(), path, path.Capacity, 0);
|
mtime { $File.LastWriteTime.Ticks }
|
||||||
|
ctime { $File.CreationTime.Ticks }
|
||||||
|
atime { $File.LastAccessTime.Ticks }
|
||||||
|
}
|
||||||
|
|
||||||
if (size<0)
|
if ($Age -ge 0) {
|
||||||
throw new Win32Exception(Marshal.GetLastWin32Error()); // The remarks section of GetFinalPathNameByHandle mentions the return being prefixed with "\\?\" // More information about "\\?\" here -> http://msdn.microsoft.com/en-us/library/aa365247(v=VS.85).aspx
|
return $Age -ge $actual_age
|
||||||
if (path[0] == '\\' && path[1] == '\\' && path[2] == '?' && path[3] == '\\')
|
} else {
|
||||||
return path.ToString().Substring(4);
|
return ($Age * -1) -le $actual_age
|
||||||
else
|
|
||||||
return path.ToString();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
"@
|
|
||||||
$original_tmp = $env:TMP
|
|
||||||
$env:TMP = $_remote_tmp
|
|
||||||
Add-Type -TypeDefinition $symlink_util
|
|
||||||
$env:TMP = $original_tmp
|
|
||||||
|
|
||||||
Function Assert-Age($info) {
|
Function Assert-FileType {
|
||||||
|
Param (
|
||||||
|
[System.IO.FileSystemInfo]$File,
|
||||||
|
[System.String]$FileType
|
||||||
|
)
|
||||||
|
|
||||||
|
$is_dir = $File.Attributes.HasFlag([System.IO.FileAttributes]::Directory)
|
||||||
|
return ($FileType -eq 'directory' -and $is_dir) -or ($FileType -eq 'file' -and -not $is_dir)
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Assert-FileHidden {
|
||||||
|
Param (
|
||||||
|
[System.IO.FileSystemInfo]$File,
|
||||||
|
[Switch]$IsHidden
|
||||||
|
)
|
||||||
|
|
||||||
|
$file_is_hidden = $File.Attributes.HasFlag([System.IO.FileAttributes]::Hidden)
|
||||||
|
return $IsHidden.IsPresent -eq $file_is_hidden
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Function Assert-FileNamePattern {
|
||||||
|
Param (
|
||||||
|
[System.IO.FileSystemInfo]$File,
|
||||||
|
[System.String[]]$Patterns,
|
||||||
|
[Switch]$UseRegex
|
||||||
|
)
|
||||||
|
|
||||||
|
$valid_match = $false
|
||||||
|
foreach ($pattern in $Patterns) {
|
||||||
|
if ($UseRegex) {
|
||||||
|
if ($File.Name -match $pattern) {
|
||||||
$valid_match = $true
|
$valid_match = $true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($File.Name -like $pattern) {
|
||||||
|
$valid_match = $true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $valid_match
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Assert-FileSize {
|
||||||
|
Param (
|
||||||
|
[System.IO.FileSystemInfo]$File,
|
||||||
|
[System.Int64]$Size
|
||||||
|
)
|
||||||
|
|
||||||
|
if ($Size -ge 0) {
|
||||||
|
return $File.Length -ge $Size
|
||||||
|
} else {
|
||||||
|
return $File.Length -le ($Size * -1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Get-FileChecksum {
|
||||||
|
Param (
|
||||||
|
[System.String]$Path,
|
||||||
|
[System.String]$Algorithm
|
||||||
|
)
|
||||||
|
|
||||||
|
$sp = switch ($algorithm) {
|
||||||
|
'md5' { New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider }
|
||||||
|
'sha1' { New-Object -TypeName System.Security.Cryptography.SHA1CryptoServiceProvider }
|
||||||
|
'sha256' { New-Object -TypeName System.Security.Cryptography.SHA256CryptoServiceProvider }
|
||||||
|
'sha384' { New-Object -TypeName System.Security.Cryptography.SHA384CryptoServiceProvider }
|
||||||
|
'sha512' { New-Object -TypeName System.Security.Cryptography.SHA512CryptoServiceProvider }
|
||||||
|
}
|
||||||
|
|
||||||
|
$fp = [System.IO.File]::Open($Path, [System.IO.Filemode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite)
|
||||||
|
try {
|
||||||
|
$hash = [System.BitConverter]::ToString($sp.ComputeHash($fp)).Replace("-", "").ToLower()
|
||||||
|
} finally {
|
||||||
|
$fp.Dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
return $hash
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Search-Path {
|
||||||
|
[CmdletBinding()]
|
||||||
|
Param (
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[System.String]
|
||||||
|
$Path,
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[AllowEmptyCollection()]
|
||||||
|
[System.Collections.Generic.HashSet`1[System.String]]
|
||||||
|
$CheckedPaths,
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[Object]
|
||||||
|
$Module,
|
||||||
|
|
||||||
|
[System.Int64]
|
||||||
|
$Age,
|
||||||
|
|
||||||
|
[System.String]
|
||||||
|
$AgeStamp,
|
||||||
|
|
||||||
|
[System.String]
|
||||||
|
$FileType,
|
||||||
|
|
||||||
|
[Switch]
|
||||||
|
$Follow,
|
||||||
|
|
||||||
|
[Switch]
|
||||||
|
$GetChecksum,
|
||||||
|
|
||||||
|
[Switch]
|
||||||
|
$IsHidden,
|
||||||
|
|
||||||
|
[System.String[]]
|
||||||
|
$Patterns,
|
||||||
|
|
||||||
|
[Switch]
|
||||||
|
$Recurse,
|
||||||
|
|
||||||
|
[System.Int64]
|
||||||
|
$Size,
|
||||||
|
|
||||||
|
[Switch]
|
||||||
|
$UseRegex
|
||||||
|
)
|
||||||
|
|
||||||
|
$dir_obj = New-Object -TypeName System.IO.DirectoryInfo -ArgumentList $Path
|
||||||
|
if ([Int32]$dir_obj.Attributes -eq -1) {
|
||||||
|
$Module.Warn("Argument path '$Path' does not exist, skipping")
|
||||||
|
return
|
||||||
|
} elseif (-not $dir_obj.Attributes.HasFlag([System.IO.FileAttributes]::Directory)) {
|
||||||
|
$Module.Warn("Argument path '$Path' is a file not a directory, skipping")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$dir_files = @()
|
||||||
|
try {
|
||||||
|
$dir_files = $dir_obj.EnumerateFileSystemInfos("*", [System.IO.SearchOption]::TopDirectoryOnly)
|
||||||
|
} catch [System.IO.DirectoryNotFoundException] { # Broken ReparsePoint/Symlink, cannot enumerate
|
||||||
|
} catch [System.UnauthorizedAccessException] {} # No ListDirectory permissions, Get-ChildItem ignored this
|
||||||
|
|
||||||
|
foreach ($dir_child in $dir_files) {
|
||||||
|
if ($dir_child.Attributes.HasFlag([System.IO.FileAttributes]::Directory) -and $Recurse) {
|
||||||
|
if ($Follow -or -not $dir_child.Attributes.HasFlag([System.IO.FileAttributes]::ReparsePoint)) {
|
||||||
|
$PSBoundParameters.Remove('Path') > $null
|
||||||
|
Search-Path -Path $dir_child.FullName @PSBoundParameters
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check to see if we've already encountered this path and skip if we have.
|
||||||
|
if (-not $CheckedPaths.Add($dir_child.FullName.ToLowerInvariant())) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
$Module.Result.examined++
|
||||||
|
|
||||||
|
if ($PSBoundParameters.ContainsKey('Age')) {
|
||||||
|
$age_match = Assert-Age -File $dir_child -Age $Age -AgeStamp $AgeStamp
|
||||||
|
} else {
|
||||||
|
$age_match = $true
|
||||||
|
}
|
||||||
|
|
||||||
|
$file_type_match = Assert-FileType -File $dir_child -FileType $FileType
|
||||||
|
$hidden_match = Assert-FileHidden -File $dir_child -IsHidden:$IsHidden
|
||||||
|
|
||||||
|
if ($PSBoundParameters.ContainsKey('Patterns')) {
|
||||||
|
$pattern_match = Assert-FileNamePattern -File $dir_child -Patterns $Patterns -UseRegex:$UseRegex.IsPresent
|
||||||
|
} else {
|
||||||
|
$pattern_match = $true
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($PSBoundParameters.ContainsKey('Size')) {
|
||||||
|
$size_match = Assert-FileSize -File $dir_child -Size $Size
|
||||||
|
} else {
|
||||||
|
$size_match = $true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not ($age_match -and $file_type_match -and $hidden_match -and $pattern_match -and $size_match)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
# It passed all our filters so add it
|
||||||
|
$module.Result.matched++
|
||||||
|
|
||||||
|
# TODO: Make this generic so it can be shared with win_find and win_stat.
|
||||||
|
$epoch = New-Object -Type System.DateTime -ArgumentList 1970, 1, 1, 0, 0, 0, 0
|
||||||
|
$file_info = @{
|
||||||
|
attributes = $dir_child.Attributes.ToString()
|
||||||
|
checksum = $null
|
||||||
|
creationtime = (New-TimeSpan -Start $epoch -End $dir_child.CreationTime).TotalSeconds
|
||||||
|
exists = $true
|
||||||
|
extension = $null
|
||||||
|
filename = $dir_child.Name
|
||||||
|
isarchive = $dir_child.Attributes.HasFlag([System.IO.FileAttributes]::Archive)
|
||||||
|
isdir = $dir_child.Attributes.HasFlag([System.IO.FileAttributes]::Directory)
|
||||||
|
ishidden = $dir_child.Attributes.HasFlag([System.IO.FileAttributes]::Hidden)
|
||||||
|
isreadonly = $dir_child.Attributes.HasFlag([System.IO.FileAttributes]::ReadOnly)
|
||||||
|
isreg = $false
|
||||||
|
isshared = $false
|
||||||
|
lastaccesstime = (New-TimeSpan -Start $epoch -End $dir_child.LastAccessTime).TotalSeconds
|
||||||
|
lastwritetime = (New-TimeSpan -Start $epoch -End $dir_child.LastWriteTime).TotalSeconds
|
||||||
|
owner = $null
|
||||||
|
path = $dir_child.FullName
|
||||||
|
sharename = $null
|
||||||
|
size = $null
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$file_info.owner = $dir_child.GetAccessControl().Owner
|
||||||
|
} catch {} # May not have rights to get the Owner, historical behaviour is to ignore.
|
||||||
|
|
||||||
|
if ($dir_child.Attributes.HasFlag([System.IO.FileAttributes]::Directory)) {
|
||||||
|
$share_info = Get-CimInstance -ClassName Win32_Share -Filter "Path='$($dir_child.FullName -replace '\\', '\\')'"
|
||||||
|
if ($null -ne $share_info) {
|
||||||
|
$file_info.isshared = $true
|
||||||
|
$file_info.sharename = $share_info.Name
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$file_info.extension = $dir_child.Extension
|
||||||
|
$file_info.isreg = $true
|
||||||
|
$file_info.size = $dir_child.Length
|
||||||
|
|
||||||
|
if ($GetChecksum) {
|
||||||
|
try {
|
||||||
|
$file_info.checksum = Get-FileChecksum -Path $dir_child.FullName -Algorithm $checksum_algorithm
|
||||||
|
} catch {} # Just keep the checksum as $null in the case of a failure.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Append the link information if the path is a link
|
||||||
|
$link_info = @{
|
||||||
|
isjunction = $false
|
||||||
|
islnk = $false
|
||||||
|
nlink = 1
|
||||||
|
lnk_source = $null
|
||||||
|
lnk_target = $null
|
||||||
|
hlnk_targets = @()
|
||||||
|
}
|
||||||
|
$link_stat = Get-Link -link_path $dir_child.FullName
|
||||||
|
if ($null -ne $link_stat) {
|
||||||
|
switch ($link_stat.Type) {
|
||||||
|
"SymbolicLink" {
|
||||||
|
$link_info.islnk = $true
|
||||||
|
$link_info.isreg = $false
|
||||||
|
$link_info.lnk_source = $link_stat.AbsolutePath
|
||||||
|
$link_info.lnk_target = $link_stat.TargetPath
|
||||||
|
break
|
||||||
|
}
|
||||||
|
"JunctionPoint" {
|
||||||
|
$link_info.isjunction = $true
|
||||||
|
$link_info.isreg = $false
|
||||||
|
$link_info.lnk_source = $link_stat.AbsolutePath
|
||||||
|
$link_info.lnk_target = $link_stat.TargetPath
|
||||||
|
break
|
||||||
|
}
|
||||||
|
"HardLink" {
|
||||||
|
$link_info.nlink = $link_stat.HardTargets.Count
|
||||||
|
|
||||||
|
# remove current path from the targets
|
||||||
|
$hlnk_targets = $link_info.HardTargets | Where-Object { $_ -ne $dir_child.FullName }
|
||||||
|
$link_info.hlnk_targets = @($hlnk_targets)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($kv in $link_info.GetEnumerator()) {
|
||||||
|
$file_info.$($kv.Key) = $kv.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
# Output the file_info object
|
||||||
|
$file_info
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$search_params = @{
|
||||||
|
CheckedPaths = [System.Collections.Generic.HashSet`1[System.String]]@()
|
||||||
|
GetChecksum = $get_checksum
|
||||||
|
Module = $module
|
||||||
|
FileType = $file_type
|
||||||
|
Follow = $follow
|
||||||
|
IsHidden = $hidden
|
||||||
|
Recurse = $recurse
|
||||||
|
}
|
||||||
|
|
||||||
if ($null -ne $age) {
|
if ($null -ne $age) {
|
||||||
$seconds_per_unit = @{'s'=1; 'm'=60; 'h'=3600; 'd'=86400; 'w'=604800}
|
$seconds_per_unit = @{'s'=1; 'm'=60; 'h'=3600; 'd'=86400; 'w'=604800}
|
||||||
$seconds_pattern = '^(-?\d+)(s|m|h|d|w)?$'
|
$seconds_pattern = '^(-?\d+)(s|m|h|d|w)?$'
|
||||||
$match = $age -match $seconds_pattern
|
$match = $age -match $seconds_pattern
|
||||||
if ($match) {
|
if ($Match) {
|
||||||
[int]$specified_seconds = $matches[1]
|
$specified_seconds = [Int64]$Matches[1]
|
||||||
if ($null -eq $matches[2]) {
|
if ($null -eq $Matches[2]) {
|
||||||
$chosen_unit = 's'
|
$chosen_unit = 's'
|
||||||
} else {
|
} else {
|
||||||
$chosen_unit = $matches[2]
|
$chosen_unit = $Matches[2]
|
||||||
}
|
}
|
||||||
|
|
||||||
$abs_seconds = $specified_seconds * ($seconds_per_unit.$chosen_unit)
|
$total_seconds = $specified_seconds * ($seconds_per_unit.$chosen_unit)
|
||||||
$epoch = New-Object -Type DateTime -ArgumentList 1970, 1, 1, 0, 0, 0, 0
|
|
||||||
if ($age_stamp -eq 'mtime') {
|
|
||||||
$age_comparison = $epoch.AddSeconds($info.lastwritetime)
|
|
||||||
} elseif ($age_stamp -eq 'ctime') {
|
|
||||||
$age_comparison = $epoch.AddSeconds($info.creationtime)
|
|
||||||
} elseif ($age_stamp -eq 'atime') {
|
|
||||||
$age_comparison = $epoch.AddSeconds($info.lastaccesstime)
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($specified_seconds -ge 0) {
|
if ($total_seconds -ge 0) {
|
||||||
$start_date = (Get-Date).AddSeconds($abs_seconds * -1)
|
$search_params.Age = (Get-Date).AddSeconds($total_seconds * -1).Ticks
|
||||||
if ($age_comparison -gt $start_date) {
|
|
||||||
$valid_match = $false
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
$start_date = (Get-Date).AddSeconds($abs_seconds)
|
# Make sure we add the positive value of seconds to current time then make it negative for later comparisons.
|
||||||
if ($age_comparison -lt $start_date) {
|
$age = (Get-Date).AddSeconds($total_seconds).Ticks
|
||||||
$valid_match = $false
|
$search_params.Age = $age * -1
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
$search_params.AgeStamp = $age_stamp
|
||||||
} else {
|
} else {
|
||||||
throw "failed to process age for file $($info.FullName)"
|
$module.FailJson("Invalid age pattern specified")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$valid_match
|
|
||||||
}
|
|
||||||
|
|
||||||
Function Assert-FileType($info) {
|
|
||||||
$valid_match = $true
|
|
||||||
|
|
||||||
if ($file_type -eq 'directory' -and $info.isdir -eq $false) {
|
|
||||||
$valid_match = $false
|
|
||||||
}
|
|
||||||
if ($file_type -eq 'file' -and $info.isdir -eq $true) {
|
|
||||||
$valid_match = $false
|
|
||||||
}
|
|
||||||
|
|
||||||
$valid_match
|
|
||||||
}
|
|
||||||
|
|
||||||
Function Assert-Hidden($info) {
|
|
||||||
$valid_match = $true
|
|
||||||
|
|
||||||
if ($hidden -eq $true -and $info.ishidden -eq $false) {
|
|
||||||
$valid_match = $false
|
|
||||||
}
|
|
||||||
if ($hidden -eq $false -and $info.ishidden -eq $true) {
|
|
||||||
$valid_match = $false
|
|
||||||
}
|
|
||||||
|
|
||||||
$valid_match
|
|
||||||
}
|
|
||||||
|
|
||||||
Function Assert-Pattern($info) {
|
|
||||||
$valid_match = $false
|
|
||||||
|
|
||||||
if ($null -ne $patterns) {
|
if ($null -ne $patterns) {
|
||||||
foreach ($pattern in $patterns) {
|
$search_params.Patterns = $patterns
|
||||||
if ($use_regex -eq $true) {
|
$search_params.UseRegex = $use_regex
|
||||||
# Use -match for regex matching
|
|
||||||
if ($info.filename -match $pattern) {
|
|
||||||
$valid_match = $true
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
# Use -like for wildcard matching
|
|
||||||
if ($info.filename -like $pattern) {
|
|
||||||
$valid_match = $true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$valid_match = $true
|
|
||||||
}
|
|
||||||
|
|
||||||
$valid_match
|
|
||||||
}
|
|
||||||
|
|
||||||
Function Assert-Size($info) {
|
|
||||||
$valid_match = $true
|
|
||||||
|
|
||||||
if ($null -ne $size) {
|
if ($null -ne $size) {
|
||||||
$bytes_per_unit = @{'b'=1; 'k'=1024; 'm'=1024*1024; 'g'=1024*1024*1024; 't'=1024*1024*1024*1024}
|
$bytes_per_unit = @{'b'=1; 'k'=1KB; 'm'=1MB; 'g'=1GB;'t'=1TB}
|
||||||
$size_pattern = '^(-?\d+)(b|k|m|g|t)?$'
|
$size_pattern = '^(-?\d+)(b|k|m|g|t)?$'
|
||||||
$match = $size -match $size_pattern
|
$match = $size -match $size_pattern
|
||||||
if ($match) {
|
if ($Match) {
|
||||||
[int64]$specified_size = $matches[1]
|
$specified_size = [Int64]$Matches[1]
|
||||||
if ($null -eq $matches[2]) {
|
if ($null -eq $Matches[2]) {
|
||||||
$chosen_byte = 'b'
|
$chosen_byte = 'b'
|
||||||
} else {
|
} else {
|
||||||
$chosen_byte = $matches[2]
|
$chosen_byte = $Matches[2]
|
||||||
}
|
}
|
||||||
|
|
||||||
$abs_size = $specified_size * ($bytes_per_unit.$chosen_byte)
|
$search_params.Size = $specified_size * ($bytes_per_unit.$chosen_byte)
|
||||||
if ($specified_size -ge 0) {
|
|
||||||
if ($info.size -lt $abs_size) {
|
|
||||||
$valid_match = $false
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if ($info.size -gt $abs_size * -1) {
|
$module.FailJson("Invalid size pattern specified")
|
||||||
$valid_match = $false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw "failed to process size for file $($info.FullName)"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$valid_match
|
$matched_files = foreach ($path in $paths) {
|
||||||
|
# Ensure we pass in an absolute path. We use the ExecutionContext as this is based on the PSProvider path not the
|
||||||
|
# process location which can be different.
|
||||||
|
$abs_path = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($path)
|
||||||
|
Search-Path -Path $abs_path @search_params
|
||||||
}
|
}
|
||||||
|
|
||||||
Function Assert-FileStat($info) {
|
# Make sure we sort the files in alphabetical order.
|
||||||
$age_match = Assert-Age -info $info
|
$module.Result.files = @() + ($matched_files | Sort-Object -Property {$_.path})
|
||||||
$file_type_match = Assert-FileType -info $info
|
|
||||||
$hidden_match = Assert-Hidden -info $info
|
|
||||||
$pattern_match = Assert-Pattern -info $info
|
|
||||||
$size_match = Assert-Size -info $info
|
|
||||||
|
|
||||||
if ($age_match -and $file_type_match -and $hidden_match -and $pattern_match -and $size_match) {
|
$module.ExitJson()
|
||||||
$info
|
|
||||||
} else {
|
|
||||||
$false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Function Get-FileStat($file) {
|
|
||||||
$epoch = New-Object -Type DateTime -ArgumentList 1970, 1, 1, 0, 0, 0, 0
|
|
||||||
$access_control = $file.GetAccessControl()
|
|
||||||
$attributes = @()
|
|
||||||
foreach ($attribute in ($file.Attributes -split ',')) {
|
|
||||||
$attributes += $attribute.Trim()
|
|
||||||
}
|
|
||||||
|
|
||||||
$file_stat = @{
|
|
||||||
isreadonly = $attributes -contains 'ReadOnly'
|
|
||||||
ishidden = $attributes -contains 'Hidden'
|
|
||||||
isarchive = $attributes -contains 'Archive'
|
|
||||||
attributes = $file.Attributes.ToString()
|
|
||||||
owner = $access_control.Owner
|
|
||||||
lastwritetime = (New-TimeSpan -Start $epoch -End $file.LastWriteTime).TotalSeconds
|
|
||||||
creationtime = (New-TimeSpan -Start $epoch -End $file.CreationTime).TotalSeconds
|
|
||||||
lastaccesstime = (New-TimeSpan -Start $epoch -End $file.LastAccessTime).TotalSeconds
|
|
||||||
path = $file.FullName
|
|
||||||
filename = $file.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
$islnk = $false
|
|
||||||
$isdir = $attributes -contains 'Directory'
|
|
||||||
$isshared = $false
|
|
||||||
|
|
||||||
if ($attributes -contains 'ReparsePoint') {
|
|
||||||
# TODO: Find a way to differenciate between soft and junction links
|
|
||||||
$islnk = $true
|
|
||||||
|
|
||||||
# Try and get the symlink source, can result in failure if link is broken
|
|
||||||
try {
|
|
||||||
$lnk_source = [Ansible.Command.SymLinkHelper]::GetSymbolicLinkTarget($file)
|
|
||||||
$file_stat.lnk_source = $lnk_source
|
|
||||||
} catch {}
|
|
||||||
} elseif ($file.PSIsContainer) {
|
|
||||||
$isdir = $true
|
|
||||||
|
|
||||||
$share_info = Get-CIMInstance -Class Win32_Share -Filter "Path='$($file.Fullname -replace '\\', '\\')'"
|
|
||||||
if ($null -ne $share_info) {
|
|
||||||
$isshared = $true
|
|
||||||
$file_stat.sharename = $share_info.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
# only get the size of a directory if there are files (not directories) inside the folder
|
|
||||||
# Get-ChildItem -LiteralPath does not work properly on older OS', use .NET instead
|
|
||||||
$dir_files = @()
|
|
||||||
try {
|
|
||||||
$dir_files = $file.EnumerateFiles("*", [System.IO.SearchOption]::AllDirectories)
|
|
||||||
} catch [System.IO.DirectoryNotFoundException] { # Broken ReparsePoint/Symlink, cannot enumerate
|
|
||||||
} catch [System.UnauthorizedAccessException] {} # No ListDirectory permissions, Get-ChildItem ignored this
|
|
||||||
$size = 0
|
|
||||||
foreach ($dir_file in $dir_files) {
|
|
||||||
$size += $dir_file.Length
|
|
||||||
}
|
|
||||||
$file_stat.size = $size
|
|
||||||
} else {
|
|
||||||
$file_stat.size = $file.length
|
|
||||||
$file_stat.extension = $file.Extension
|
|
||||||
|
|
||||||
if ($get_checksum) {
|
|
||||||
try {
|
|
||||||
$checksum = Get-FileChecksum -path $path -algorithm $checksum_algorithm
|
|
||||||
$file_stat.checksum = $checksum
|
|
||||||
} catch {
|
|
||||||
throw "failed to get checksum for file $($file.FullName)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$file_stat.islnk = $islnk
|
|
||||||
$file_stat.isdir = $isdir
|
|
||||||
$file_stat.isshared = $isshared
|
|
||||||
|
|
||||||
Assert-FileStat -info $file_stat
|
|
||||||
}
|
|
||||||
|
|
||||||
Function Get-FilesInFolder($path) {
|
|
||||||
$items = @()
|
|
||||||
|
|
||||||
# Get-ChildItem -LiteralPath can bomb out on older OS', use .NET instead
|
|
||||||
$dir = New-Object -TypeName System.IO.DirectoryInfo -ArgumentList $path
|
|
||||||
$dir_files = @()
|
|
||||||
try {
|
|
||||||
$dir_files = $dir.EnumerateFileSystemInfos("*", [System.IO.SearchOption]::TopDirectoryOnly)
|
|
||||||
} catch [System.IO.DirectoryNotFoundException] { # Broken ReparsePoint/Symlink, cannot enumerate
|
|
||||||
} catch [System.UnauthorizedAccessException] {} # No ListDirectory permissions, Get-ChildItem ignored this
|
|
||||||
foreach ($item in $dir_files) {
|
|
||||||
if ($item -is [System.IO.DirectoryInfo] -and $recurse) {
|
|
||||||
if (($item.Attributes -like '*ReparsePoint*' -and $follow) -or ($item.Attributes -notlike '*ReparsePoint*')) {
|
|
||||||
# File is a link and we want to follow a link OR file is not a link
|
|
||||||
$items += $item.FullName
|
|
||||||
$items += Get-FilesInFolder -path $item.FullName
|
|
||||||
} else {
|
|
||||||
# File is a link but we don't want to follow a link
|
|
||||||
$items += $item.FullName
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$items += $item.FullName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$items
|
|
||||||
}
|
|
||||||
|
|
||||||
$paths_to_check = @()
|
|
||||||
foreach ($path in $paths) {
|
|
||||||
if (Test-Path -LiteralPath $path) {
|
|
||||||
if ((Get-Item -LiteralPath $path -Force).PSIsContainer) {
|
|
||||||
$paths_to_check += Get-FilesInFolder -path $path
|
|
||||||
} else {
|
|
||||||
Fail-Json $result "Argument path $path is a file not a directory"
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Fail-Json $result "Argument path $path does not exist cannot get information on"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$paths_to_check = $paths_to_check | Select-Object -Unique | Sort-Object
|
|
||||||
|
|
||||||
foreach ($path in $paths_to_check) {
|
|
||||||
try {
|
|
||||||
$file = Get-Item -LiteralPath $path -Force
|
|
||||||
$info = Get-FileStat -file $file
|
|
||||||
} catch {
|
|
||||||
Add-Warning -obj $result -message "win_find failed to check some files, these files were ignored and will not be part of the result output"
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
$new_examined = $result.examined + 1
|
|
||||||
$result.examined = $new_examined
|
|
||||||
|
|
||||||
if ($info -ne $false) {
|
|
||||||
$files = $result.Files
|
|
||||||
$files += $info
|
|
||||||
|
|
||||||
$new_matched = $result.matched + 1
|
|
||||||
$result.matched = $new_matched
|
|
||||||
$result.files = $files
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Exit-Json $result
|
|
||||||
|
|
|
@ -235,6 +235,11 @@ files:
|
||||||
returned: success, path exists
|
returned: success, path exists
|
||||||
type: float
|
type: float
|
||||||
sample: 1477984205.15
|
sample: 1477984205.15
|
||||||
|
exists:
|
||||||
|
description: Whether the file exists, will always be true for M(win_find).
|
||||||
|
returned: success, path exists
|
||||||
|
type: bool
|
||||||
|
sample: true
|
||||||
extension:
|
extension:
|
||||||
description: The extension of the file at path.
|
description: The extension of the file at path.
|
||||||
returned: success, path exists, path is a file
|
returned: success, path exists, path is a file
|
||||||
|
@ -245,6 +250,13 @@ files:
|
||||||
returned: success, path exists
|
returned: success, path exists
|
||||||
type: str
|
type: str
|
||||||
sample: temp
|
sample: temp
|
||||||
|
hlnk_targets:
|
||||||
|
description: List of other files pointing to the same file (hard links), excludes the current file.
|
||||||
|
returned: success, path exists
|
||||||
|
type: list
|
||||||
|
sample:
|
||||||
|
- C:\temp\file.txt
|
||||||
|
- C:\Windows\update.log
|
||||||
isarchive:
|
isarchive:
|
||||||
description: If the path is ready for archiving or not.
|
description: If the path is ready for archiving or not.
|
||||||
returned: success, path exists
|
returned: success, path exists
|
||||||
|
@ -260,9 +272,14 @@ files:
|
||||||
returned: success, path exists
|
returned: success, path exists
|
||||||
type: bool
|
type: bool
|
||||||
sample: true
|
sample: true
|
||||||
|
isjunction:
|
||||||
|
description: If the path is a junction point.
|
||||||
|
returned: success, path exists
|
||||||
|
type: bool
|
||||||
|
sample: true
|
||||||
islnk:
|
islnk:
|
||||||
description: If the path is a symbolic link or junction or not.
|
description: If the path is a symbolic link.
|
||||||
returned: success, path exists or deduped files
|
returned: success, path exists
|
||||||
type: bool
|
type: bool
|
||||||
sample: true
|
sample: true
|
||||||
isreadonly:
|
isreadonly:
|
||||||
|
@ -270,6 +287,11 @@ files:
|
||||||
returned: success, path exists
|
returned: success, path exists
|
||||||
type: bool
|
type: bool
|
||||||
sample: true
|
sample: true
|
||||||
|
isreg:
|
||||||
|
description: If the path is a regular file or not.
|
||||||
|
returned: success, path exists
|
||||||
|
type: bool
|
||||||
|
sample: true
|
||||||
isshared:
|
isshared:
|
||||||
description: If the path is shared or not.
|
description: If the path is shared or not.
|
||||||
returned: success, path exists
|
returned: success, path exists
|
||||||
|
@ -286,10 +308,20 @@ files:
|
||||||
type: float
|
type: float
|
||||||
sample: 1477984205.15
|
sample: 1477984205.15
|
||||||
lnk_source:
|
lnk_source:
|
||||||
description: The target of the symbolic link, will return null if not a link or the link is broken.
|
description: The target of the symlink normalized for the remote filesystem.
|
||||||
returned: success, path exists, path is a symbolic link
|
returned: success, path exists, path is a symbolic link or junction point
|
||||||
type: str
|
type: str
|
||||||
sample: C:\temp
|
sample: C:\temp
|
||||||
|
lnk_target:
|
||||||
|
description: The target of the symlink. Note that relative paths remain relative, will return null if not a link.
|
||||||
|
returned: success, path exists, path is a symbolic link or junction point
|
||||||
|
type: str
|
||||||
|
sample: temp
|
||||||
|
nlink:
|
||||||
|
description: Number of links to the file (hard links)
|
||||||
|
returned: success, path exists
|
||||||
|
type: int
|
||||||
|
sample: 1
|
||||||
owner:
|
owner:
|
||||||
description: The owner of the file.
|
description: The owner of the file.
|
||||||
returned: success, path exists
|
returned: success, path exists
|
||||||
|
@ -306,8 +338,8 @@ files:
|
||||||
type: str
|
type: str
|
||||||
sample: file-share
|
sample: file-share
|
||||||
size:
|
size:
|
||||||
description: The size in bytes of a file or folder.
|
description: The size in bytes of the file.
|
||||||
returned: success, path exists, path is not a link
|
returned: success, path exists, path is a file
|
||||||
type: int
|
type: int
|
||||||
sample: 1024
|
sample: 1024
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -1,103 +1,139 @@
|
||||||
---
|
---
|
||||||
- name: expect failure when not setting paths
|
- name: expected skip when paths to a file
|
||||||
win_find:
|
|
||||||
patterns: a
|
|
||||||
register: actual
|
|
||||||
failed_when: "actual.msg != 'Get-AnsibleParam: Missing required argument: paths'"
|
|
||||||
|
|
||||||
- name: expect failure when setting paths to a file
|
|
||||||
win_find:
|
win_find:
|
||||||
paths: "{{win_find_dir}}\\single\\large.ps1"
|
paths: "{{win_find_dir}}\\single\\large.ps1"
|
||||||
register: actual
|
register: actual
|
||||||
failed_when: actual.msg != 'Argument path ' + win_find_dir + '\\single\\large.ps1 is a file not a directory'
|
|
||||||
|
|
||||||
- name: expect failure when path is set to a non existent folder
|
- name: assert skip when path is set to a file
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- not actual is changed
|
||||||
|
- actual.examined == 0
|
||||||
|
- actual.files == []
|
||||||
|
- actual.matched == 0
|
||||||
|
- actual.warnings == ["Argument path '" + win_find_dir + "\\single\\large.ps1' is a file not a directory, skipping"]
|
||||||
|
|
||||||
|
- name: expect skip when path is set to a non existent folder
|
||||||
win_find:
|
win_find:
|
||||||
paths: "{{win_find_dir}}\\thisisafakefolder"
|
paths: "{{win_find_dir}}\\thisisafakefolder"
|
||||||
register: actual
|
register: actual
|
||||||
failed_when: actual.msg != 'Argument path ' + win_find_dir + '\\thisisafakefolder does not exist cannot get information on'
|
|
||||||
|
- name: assert skip when path is set to a non existent folder
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- not actual is changed
|
||||||
|
- actual.examined == 0
|
||||||
|
- actual.files == []
|
||||||
|
- actual.matched == 0
|
||||||
|
- actual.warnings == ["Argument path '" + win_find_dir + "\\thisisafakefolder' does not exist, skipping"]
|
||||||
|
|
||||||
- name: get files in single directory
|
- name: get files in single directory
|
||||||
win_find:
|
win_find:
|
||||||
paths: "{{win_find_dir}}\\single"
|
paths: "{{win_find_dir}}\\single"
|
||||||
register: actual
|
register: actual
|
||||||
|
|
||||||
- name: set expected value for files in a single directory
|
- name: assert get files in single directory
|
||||||
set_fact:
|
|
||||||
expected:
|
|
||||||
changed: False
|
|
||||||
examined: 5
|
|
||||||
failed: False
|
|
||||||
files:
|
|
||||||
- { isarchive: True,
|
|
||||||
attributes: Archive,
|
|
||||||
checksum: f8d100cdcf0e6c1007db2f8dd0b7ee2884df89af,
|
|
||||||
creationtime: 1477984205,
|
|
||||||
extension: .ps1,
|
|
||||||
filename: large.ps1,
|
|
||||||
ishidden: False,
|
|
||||||
isdir: False,
|
|
||||||
islnk: False,
|
|
||||||
lastaccesstime: 1477984205,
|
|
||||||
lastwritetime: 1477984205,
|
|
||||||
owner: BUILTIN\Administrators,
|
|
||||||
path: "{{win_find_dir}}\\single\\large.ps1",
|
|
||||||
isreadonly: False,
|
|
||||||
isshared: False,
|
|
||||||
size: 260002 }
|
|
||||||
- { isarchive: True,
|
|
||||||
attributes: Archive,
|
|
||||||
checksum: 8df33cee3325596517df5bb5aa980cf9c5c1fda3,
|
|
||||||
creationtime: 1477984205,
|
|
||||||
extension: .log,
|
|
||||||
filename: out_20161101-091005.log,
|
|
||||||
ishidden: False,
|
|
||||||
isdir: False,
|
|
||||||
islnk: False,
|
|
||||||
lastaccesstime: 1477984205,
|
|
||||||
lastwritetime: 1477984205,
|
|
||||||
owner: BUILTIN\Administrators,
|
|
||||||
path: "{{win_find_dir}}\\single\\out_20161101-091005.log",
|
|
||||||
isreadonly: False,
|
|
||||||
isshared: False,
|
|
||||||
size: 14 }
|
|
||||||
- { isarchive: True,
|
|
||||||
attributes: Archive,
|
|
||||||
checksum: 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8,
|
|
||||||
creationtime: 1477984205,
|
|
||||||
extension: .ps1,
|
|
||||||
filename: small.ps1,
|
|
||||||
ishidden: False,
|
|
||||||
isdir: False,
|
|
||||||
islnk: False,
|
|
||||||
lastaccesstime: 1477984205,
|
|
||||||
lastwritetime: 1477984205,
|
|
||||||
owner: BUILTIN\Administrators,
|
|
||||||
path: "{{win_find_dir}}\\single\\small.ps1",
|
|
||||||
isreadonly: False,
|
|
||||||
isshared: False,
|
|
||||||
size: 1 }
|
|
||||||
- { isarchive: True,
|
|
||||||
attributes: Archive,
|
|
||||||
checksum: 8df33cee3325596517df5bb5aa980cf9c5c1fda3,
|
|
||||||
creationtime: 1477984205,
|
|
||||||
extension: .ps1,
|
|
||||||
filename: test.ps1,
|
|
||||||
ishidden: False,
|
|
||||||
isdir: False,
|
|
||||||
islnk: False,
|
|
||||||
lastaccesstime: 1477984205,
|
|
||||||
lastwritetime: 1477984205,
|
|
||||||
owner: BUILTIN\Administrators,
|
|
||||||
path: "{{win_find_dir}}\\single\\test.ps1",
|
|
||||||
isreadonly: False,
|
|
||||||
isshared: False,
|
|
||||||
size: 14 }
|
|
||||||
matched: 4
|
|
||||||
|
|
||||||
- name: assert actual == expected
|
|
||||||
assert:
|
assert:
|
||||||
that: actual == expected
|
that:
|
||||||
|
- not actual is changed
|
||||||
|
- actual.examined == 5
|
||||||
|
- actual.matched == 4
|
||||||
|
- actual.files[0].attributes == 'Archive'
|
||||||
|
- actual.files[0].checksum == 'f8d100cdcf0e6c1007db2f8dd0b7ee2884df89af'
|
||||||
|
- actual.files[0].creationtime == 1477984205
|
||||||
|
- actual.files[0].exists == True
|
||||||
|
- actual.files[0].extension == '.ps1'
|
||||||
|
- actual.files[0].filename == 'large.ps1'
|
||||||
|
- actual.files[0].hlnk_targets == []
|
||||||
|
- actual.files[0].isarchive == True
|
||||||
|
- actual.files[0].isdir == False
|
||||||
|
- actual.files[0].ishidden == False
|
||||||
|
- actual.files[0].isjunction == False
|
||||||
|
- actual.files[0].islnk == False
|
||||||
|
- actual.files[0].isreadonly == False
|
||||||
|
- actual.files[0].isreg == True
|
||||||
|
- actual.files[0].isshared == False
|
||||||
|
- actual.files[0].lastaccesstime == 1477984205
|
||||||
|
- actual.files[0].lastwritetime == 1477984205
|
||||||
|
- actual.files[0].lnk_source == None
|
||||||
|
- actual.files[0].lnk_target == None
|
||||||
|
- actual.files[0].nlink == 1
|
||||||
|
- actual.files[0].owner == 'BUILTIN\\Administrators'
|
||||||
|
- actual.files[0].path == win_find_dir + '\\single\\large.ps1'
|
||||||
|
- actual.files[0].sharename == None
|
||||||
|
- actual.files[0].size == 260002
|
||||||
|
- actual.files[1].attributes == 'Archive'
|
||||||
|
- actual.files[1].checksum == '8df33cee3325596517df5bb5aa980cf9c5c1fda3'
|
||||||
|
- actual.files[1].creationtime == 1477984205
|
||||||
|
- actual.files[1].exists == True
|
||||||
|
- actual.files[1].extension == '.log'
|
||||||
|
- actual.files[1].filename == 'out_20161101-091005.log'
|
||||||
|
- actual.files[1].hlnk_targets == []
|
||||||
|
- actual.files[1].isarchive == True
|
||||||
|
- actual.files[1].isdir == False
|
||||||
|
- actual.files[1].ishidden == False
|
||||||
|
- actual.files[1].isjunction == False
|
||||||
|
- actual.files[1].islnk == False
|
||||||
|
- actual.files[1].isreadonly == False
|
||||||
|
- actual.files[1].isreg == True
|
||||||
|
- actual.files[1].isshared == False
|
||||||
|
- actual.files[1].lastaccesstime == 1477984205
|
||||||
|
- actual.files[1].lastwritetime == 1477984205
|
||||||
|
- actual.files[1].lnk_source == None
|
||||||
|
- actual.files[1].lnk_target == None
|
||||||
|
- actual.files[1].nlink == 1
|
||||||
|
- actual.files[1].owner == 'BUILTIN\\Administrators'
|
||||||
|
- actual.files[1].path == win_find_dir + '\\single\\out_20161101-091005.log'
|
||||||
|
- actual.files[1].sharename == None
|
||||||
|
- actual.files[1].size == 14
|
||||||
|
- actual.files[2].attributes == 'Archive'
|
||||||
|
- actual.files[2].checksum == '86f7e437faa5a7fce15d1ddcb9eaeaea377667b8'
|
||||||
|
- actual.files[2].creationtime == 1477984205
|
||||||
|
- actual.files[2].exists == True
|
||||||
|
- actual.files[2].extension == '.ps1'
|
||||||
|
- actual.files[2].filename == 'small.ps1'
|
||||||
|
- actual.files[2].hlnk_targets == []
|
||||||
|
- actual.files[2].isarchive == True
|
||||||
|
- actual.files[2].isdir == False
|
||||||
|
- actual.files[2].ishidden == False
|
||||||
|
- actual.files[2].isjunction == False
|
||||||
|
- actual.files[2].islnk == False
|
||||||
|
- actual.files[2].isreadonly == False
|
||||||
|
- actual.files[2].isreg == True
|
||||||
|
- actual.files[2].isshared == False
|
||||||
|
- actual.files[2].lastaccesstime == 1477984205
|
||||||
|
- actual.files[2].lastwritetime == 1477984205
|
||||||
|
- actual.files[2].lnk_source == None
|
||||||
|
- actual.files[2].lnk_target == None
|
||||||
|
- actual.files[2].nlink == 1
|
||||||
|
- actual.files[2].owner == 'BUILTIN\\Administrators'
|
||||||
|
- actual.files[2].path == win_find_dir + '\\single\\small.ps1'
|
||||||
|
- actual.files[2].sharename == None
|
||||||
|
- actual.files[2].size == 1
|
||||||
|
- actual.files[3].attributes == 'Archive'
|
||||||
|
- actual.files[3].checksum == '8df33cee3325596517df5bb5aa980cf9c5c1fda3'
|
||||||
|
- actual.files[3].creationtime == 1477984205
|
||||||
|
- actual.files[3].exists == True
|
||||||
|
- actual.files[3].extension == '.ps1'
|
||||||
|
- actual.files[3].filename == 'test.ps1'
|
||||||
|
- actual.files[3].hlnk_targets == []
|
||||||
|
- actual.files[3].isarchive == True
|
||||||
|
- actual.files[3].isdir == False
|
||||||
|
- actual.files[3].ishidden == False
|
||||||
|
- actual.files[3].isjunction == False
|
||||||
|
- actual.files[3].islnk == False
|
||||||
|
- actual.files[3].isreadonly == False
|
||||||
|
- actual.files[3].isreg == True
|
||||||
|
- actual.files[3].isshared == False
|
||||||
|
- actual.files[3].lastaccesstime == 1477984205
|
||||||
|
- actual.files[3].lastwritetime == 1477984205
|
||||||
|
- actual.files[3].lnk_source == None
|
||||||
|
- actual.files[3].lnk_target == None
|
||||||
|
- actual.files[3].nlink == 1
|
||||||
|
- actual.files[3].owner == 'BUILTIN\\Administrators'
|
||||||
|
- actual.files[3].path == win_find_dir + '\\single\\test.ps1'
|
||||||
|
- actual.files[3].sharename == None
|
||||||
|
- actual.files[3].size == 14
|
||||||
|
|
||||||
- name: find hidden files
|
- name: find hidden files
|
||||||
win_find:
|
win_find:
|
||||||
|
@ -105,34 +141,36 @@
|
||||||
hidden: True
|
hidden: True
|
||||||
register: actual
|
register: actual
|
||||||
|
|
||||||
- name: set fact for hidden files
|
- name: assert get files in single directory
|
||||||
set_fact:
|
|
||||||
expected:
|
|
||||||
changed: False
|
|
||||||
examined: 11
|
|
||||||
failed: False
|
|
||||||
files:
|
|
||||||
- { isarchive: True,
|
|
||||||
attributes: "Hidden, Archive",
|
|
||||||
checksum: 8df33cee3325596517df5bb5aa980cf9c5c1fda3,
|
|
||||||
creationtime: 1477984205,
|
|
||||||
extension: .ps1,
|
|
||||||
filename: hidden.ps1,
|
|
||||||
ishidden: True,
|
|
||||||
isdir: False,
|
|
||||||
islnk: False,
|
|
||||||
lastaccesstime: 1477984205,
|
|
||||||
lastwritetime: 1477984205,
|
|
||||||
owner: BUILTIN\Administrators,
|
|
||||||
path: "{{win_find_dir}}\\single\\hidden.ps1",
|
|
||||||
isreadonly: False,
|
|
||||||
isshared: False,
|
|
||||||
size: 14 }
|
|
||||||
matched: 1
|
|
||||||
|
|
||||||
- name: assert actual == expected
|
|
||||||
assert:
|
assert:
|
||||||
that: actual == expected
|
that:
|
||||||
|
- not actual is changed
|
||||||
|
- actual.examined == 11
|
||||||
|
- actual.matched == 1
|
||||||
|
- actual.files[0].attributes == 'Hidden, Archive'
|
||||||
|
- actual.files[0].checksum == '8df33cee3325596517df5bb5aa980cf9c5c1fda3'
|
||||||
|
- actual.files[0].creationtime == 1477984205
|
||||||
|
- actual.files[0].exists == True
|
||||||
|
- actual.files[0].extension == '.ps1'
|
||||||
|
- actual.files[0].filename == 'hidden.ps1'
|
||||||
|
- actual.files[0].hlnk_targets == []
|
||||||
|
- actual.files[0].isarchive == True
|
||||||
|
- actual.files[0].isdir == False
|
||||||
|
- actual.files[0].ishidden == True
|
||||||
|
- actual.files[0].isjunction == False
|
||||||
|
- actual.files[0].islnk == False
|
||||||
|
- actual.files[0].isreadonly == False
|
||||||
|
- actual.files[0].isreg == True
|
||||||
|
- actual.files[0].isshared == False
|
||||||
|
- actual.files[0].lastaccesstime == 1477984205
|
||||||
|
- actual.files[0].lastwritetime == 1477984205
|
||||||
|
- actual.files[0].lnk_source == None
|
||||||
|
- actual.files[0].lnk_target == None
|
||||||
|
- actual.files[0].nlink == 1
|
||||||
|
- actual.files[0].owner == 'BUILTIN\\Administrators'
|
||||||
|
- actual.files[0].path == win_find_dir + '\\single\\hidden.ps1'
|
||||||
|
- actual.files[0].sharename == None
|
||||||
|
- actual.files[0].size == 14
|
||||||
|
|
||||||
- name: find file based on pattern
|
- name: find file based on pattern
|
||||||
win_find:
|
win_find:
|
||||||
|
@ -147,36 +185,37 @@
|
||||||
use_regex: True
|
use_regex: True
|
||||||
register: actual_regex
|
register: actual_regex
|
||||||
|
|
||||||
- name: set fact for pattern files
|
- name: assert find file based on pattern
|
||||||
set_fact:
|
|
||||||
expected:
|
|
||||||
changed: False
|
|
||||||
examined: 5
|
|
||||||
failed: False
|
|
||||||
files:
|
|
||||||
- { isarchive: True,
|
|
||||||
attributes: Archive,
|
|
||||||
checksum: 8df33cee3325596517df5bb5aa980cf9c5c1fda3,
|
|
||||||
creationtime: 1477984205,
|
|
||||||
extension: .log,
|
|
||||||
filename: out_20161101-091005.log,
|
|
||||||
ishidden: False,
|
|
||||||
isdir: False,
|
|
||||||
islnk: False,
|
|
||||||
lastaccesstime: 1477984205,
|
|
||||||
lastwritetime: 1477984205,
|
|
||||||
owner: BUILTIN\Administrators,
|
|
||||||
path: "{{win_find_dir}}\\single\\out_20161101-091005.log",
|
|
||||||
isreadonly: False,
|
|
||||||
isshared: False,
|
|
||||||
size: 14 }
|
|
||||||
matched: 1
|
|
||||||
|
|
||||||
- name: assert actual == expected
|
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- actual_pattern == expected
|
- not actual_pattern is changed
|
||||||
- actual_regex == expected
|
- actual_pattern.examined == 5
|
||||||
|
- actual_pattern.matched == 1
|
||||||
|
- actual_pattern.files[0].attributes == 'Archive'
|
||||||
|
- actual_pattern.files[0].checksum == '8df33cee3325596517df5bb5aa980cf9c5c1fda3'
|
||||||
|
- actual_pattern.files[0].creationtime == 1477984205
|
||||||
|
- actual_pattern.files[0].exists == True
|
||||||
|
- actual_pattern.files[0].extension == '.log'
|
||||||
|
- actual_pattern.files[0].filename == 'out_20161101-091005.log'
|
||||||
|
- actual_pattern.files[0].hlnk_targets == []
|
||||||
|
- actual_pattern.files[0].isarchive == True
|
||||||
|
- actual_pattern.files[0].isdir == False
|
||||||
|
- actual_pattern.files[0].ishidden == False
|
||||||
|
- actual_pattern.files[0].isjunction == False
|
||||||
|
- actual_pattern.files[0].islnk == False
|
||||||
|
- actual_pattern.files[0].isreadonly == False
|
||||||
|
- actual_pattern.files[0].isreg == True
|
||||||
|
- actual_pattern.files[0].isshared == False
|
||||||
|
- actual_pattern.files[0].lastaccesstime == 1477984205
|
||||||
|
- actual_pattern.files[0].lastwritetime == 1477984205
|
||||||
|
- actual_pattern.files[0].lnk_source == None
|
||||||
|
- actual_pattern.files[0].lnk_target == None
|
||||||
|
- actual_pattern.files[0].nlink == 1
|
||||||
|
- actual_pattern.files[0].owner == 'BUILTIN\\Administrators'
|
||||||
|
- actual_pattern.files[0].path == win_find_dir + '\\single\\out_20161101-091005.log'
|
||||||
|
- actual_pattern.files[0].sharename == None
|
||||||
|
- actual_pattern.files[0].size == 14
|
||||||
|
- actual_pattern == actual_regex
|
||||||
|
|
||||||
- name: find files with recurse set
|
- name: find files with recurse set
|
||||||
win_find:
|
win_find:
|
||||||
|
@ -185,66 +224,84 @@
|
||||||
patterns: "*.ps1"
|
patterns: "*.ps1"
|
||||||
register: actual
|
register: actual
|
||||||
|
|
||||||
- name: set expected value for files in a nested directory
|
- name: assert find files with recurse set
|
||||||
set_fact:
|
|
||||||
expected:
|
|
||||||
changed: False
|
|
||||||
examined: 8
|
|
||||||
failed: False
|
|
||||||
files:
|
|
||||||
- { isarchive: True,
|
|
||||||
attributes: Archive,
|
|
||||||
checksum: 8df33cee3325596517df5bb5aa980cf9c5c1fda3,
|
|
||||||
creationtime: 1477984205,
|
|
||||||
extension: .ps1,
|
|
||||||
filename: file.ps1,
|
|
||||||
ishidden: False,
|
|
||||||
isdir: False,
|
|
||||||
islnk: False,
|
|
||||||
lastaccesstime: 1477984205,
|
|
||||||
lastwritetime: 1477984205,
|
|
||||||
owner: BUILTIN\Administrators,
|
|
||||||
path: "{{win_find_dir}}\\nested\\file.ps1",
|
|
||||||
isreadonly: False,
|
|
||||||
isshared: False,
|
|
||||||
size: 14 }
|
|
||||||
- { isarchive: True,
|
|
||||||
attributes: Archive,
|
|
||||||
checksum: 8df33cee3325596517df5bb5aa980cf9c5c1fda3,
|
|
||||||
creationtime: 1477984205,
|
|
||||||
extension: .ps1,
|
|
||||||
filename: test.ps1,
|
|
||||||
ishidden: False,
|
|
||||||
isdir: False,
|
|
||||||
islnk: False,
|
|
||||||
lastaccesstime: 1477984205,
|
|
||||||
lastwritetime: 1477984205,
|
|
||||||
owner: BUILTIN\Administrators,
|
|
||||||
path: "{{win_find_dir}}\\nested\\sub-nest\\test.ps1",
|
|
||||||
isreadonly: False,
|
|
||||||
isshared: False,
|
|
||||||
size: 14 }
|
|
||||||
- { isarchive: True,
|
|
||||||
attributes: Archive,
|
|
||||||
checksum: 8df33cee3325596517df5bb5aa980cf9c5c1fda3,
|
|
||||||
creationtime: 1477984205,
|
|
||||||
extension: .ps1,
|
|
||||||
filename: test.ps1,
|
|
||||||
ishidden: False,
|
|
||||||
isdir: False,
|
|
||||||
islnk: False,
|
|
||||||
lastaccesstime: 1477984205,
|
|
||||||
lastwritetime: 1477984205,
|
|
||||||
owner: BUILTIN\Administrators,
|
|
||||||
path: "{{win_find_dir}}\\nested\\test.ps1",
|
|
||||||
isreadonly: False,
|
|
||||||
isshared: False,
|
|
||||||
size: 14 }
|
|
||||||
matched: 3
|
|
||||||
|
|
||||||
- name: assert actual == expected
|
|
||||||
assert:
|
assert:
|
||||||
that: actual == expected
|
that:
|
||||||
|
- not actual is changed
|
||||||
|
- actual.examined == 8
|
||||||
|
- actual.matched == 3
|
||||||
|
- actual.files[0].attributes == 'Archive'
|
||||||
|
- actual.files[0].checksum == '8df33cee3325596517df5bb5aa980cf9c5c1fda3'
|
||||||
|
- actual.files[0].creationtime == 1477984205
|
||||||
|
- actual.files[0].exists == True
|
||||||
|
- actual.files[0].extension == '.ps1'
|
||||||
|
- actual.files[0].filename == 'file.ps1'
|
||||||
|
- actual.files[0].hlnk_targets == []
|
||||||
|
- actual.files[0].isarchive == True
|
||||||
|
- actual.files[0].isdir == False
|
||||||
|
- actual.files[0].ishidden == False
|
||||||
|
- actual.files[0].isjunction == False
|
||||||
|
- actual.files[0].islnk == False
|
||||||
|
- actual.files[0].isreadonly == False
|
||||||
|
- actual.files[0].isreg == True
|
||||||
|
- actual.files[0].isshared == False
|
||||||
|
- actual.files[0].lastaccesstime == 1477984205
|
||||||
|
- actual.files[0].lastwritetime == 1477984205
|
||||||
|
- actual.files[0].lnk_source == None
|
||||||
|
- actual.files[0].lnk_target == None
|
||||||
|
- actual.files[0].nlink == 1
|
||||||
|
- actual.files[0].owner == 'BUILTIN\\Administrators'
|
||||||
|
- actual.files[0].path == win_find_dir + '\\nested\\file.ps1'
|
||||||
|
- actual.files[0].sharename == None
|
||||||
|
- actual.files[0].size == 14
|
||||||
|
- actual.files[1].attributes == 'Archive'
|
||||||
|
- actual.files[1].checksum == '8df33cee3325596517df5bb5aa980cf9c5c1fda3'
|
||||||
|
- actual.files[1].creationtime == 1477984205
|
||||||
|
- actual.files[1].exists == True
|
||||||
|
- actual.files[1].extension == '.ps1'
|
||||||
|
- actual.files[1].filename == 'test.ps1'
|
||||||
|
- actual.files[1].hlnk_targets == []
|
||||||
|
- actual.files[1].isarchive == True
|
||||||
|
- actual.files[1].isdir == False
|
||||||
|
- actual.files[1].ishidden == False
|
||||||
|
- actual.files[1].isjunction == False
|
||||||
|
- actual.files[1].islnk == False
|
||||||
|
- actual.files[1].isreadonly == False
|
||||||
|
- actual.files[1].isreg == True
|
||||||
|
- actual.files[1].isshared == False
|
||||||
|
- actual.files[1].lastaccesstime == 1477984205
|
||||||
|
- actual.files[1].lastwritetime == 1477984205
|
||||||
|
- actual.files[1].lnk_source == None
|
||||||
|
- actual.files[1].lnk_target == None
|
||||||
|
- actual.files[1].nlink == 1
|
||||||
|
- actual.files[1].owner == 'BUILTIN\\Administrators'
|
||||||
|
- actual.files[1].path == win_find_dir + '\\nested\\sub-nest\\test.ps1'
|
||||||
|
- actual.files[1].sharename == None
|
||||||
|
- actual.files[1].size == 14
|
||||||
|
- actual.files[2].attributes == 'Archive'
|
||||||
|
- actual.files[2].checksum == '8df33cee3325596517df5bb5aa980cf9c5c1fda3'
|
||||||
|
- actual.files[2].creationtime == 1477984205
|
||||||
|
- actual.files[2].exists == True
|
||||||
|
- actual.files[2].extension == '.ps1'
|
||||||
|
- actual.files[2].filename == 'test.ps1'
|
||||||
|
- actual.files[2].hlnk_targets == []
|
||||||
|
- actual.files[2].isarchive == True
|
||||||
|
- actual.files[2].isdir == False
|
||||||
|
- actual.files[2].ishidden == False
|
||||||
|
- actual.files[2].isjunction == False
|
||||||
|
- actual.files[2].islnk == False
|
||||||
|
- actual.files[2].isreadonly == False
|
||||||
|
- actual.files[2].isreg == True
|
||||||
|
- actual.files[2].isshared == False
|
||||||
|
- actual.files[2].lastaccesstime == 1477984205
|
||||||
|
- actual.files[2].lastwritetime == 1477984205
|
||||||
|
- actual.files[2].lnk_source == None
|
||||||
|
- actual.files[2].lnk_target == None
|
||||||
|
- actual.files[2].nlink == 1
|
||||||
|
- actual.files[2].owner == 'BUILTIN\\Administrators'
|
||||||
|
- actual.files[2].path == win_find_dir + '\\nested\\test.ps1'
|
||||||
|
- actual.files[2].sharename == None
|
||||||
|
- actual.files[2].size == 14
|
||||||
|
|
||||||
- name: find files with recurse set and follow links
|
- name: find files with recurse set and follow links
|
||||||
win_find:
|
win_find:
|
||||||
|
@ -254,82 +311,108 @@
|
||||||
patterns: "*.ps1"
|
patterns: "*.ps1"
|
||||||
register: actual
|
register: actual
|
||||||
|
|
||||||
- name: set expected value for files in a nested directory while following links
|
- name: assert find files with recurse set and follow links
|
||||||
set_fact:
|
|
||||||
expected:
|
|
||||||
changed: False
|
|
||||||
examined: 10
|
|
||||||
failed: False
|
|
||||||
files:
|
|
||||||
- { isarchive: True,
|
|
||||||
attributes: Archive,
|
|
||||||
checksum: 8df33cee3325596517df5bb5aa980cf9c5c1fda3,
|
|
||||||
creationtime: 1477984205,
|
|
||||||
extension: .ps1,
|
|
||||||
filename: file.ps1,
|
|
||||||
ishidden: False,
|
|
||||||
isdir: False,
|
|
||||||
islnk: False,
|
|
||||||
lastaccesstime: 1477984205,
|
|
||||||
lastwritetime: 1477984205,
|
|
||||||
owner: BUILTIN\Administrators,
|
|
||||||
path: "{{win_find_dir}}\\nested\\file.ps1",
|
|
||||||
isreadonly: False,
|
|
||||||
isshared: False,
|
|
||||||
size: 14 }
|
|
||||||
- { isarchive: True,
|
|
||||||
attributes: Archive,
|
|
||||||
checksum: 8df33cee3325596517df5bb5aa980cf9c5c1fda3,
|
|
||||||
creationtime: 1477984205,
|
|
||||||
extension: .ps1,
|
|
||||||
filename: link.ps1,
|
|
||||||
ishidden: False,
|
|
||||||
isdir: False,
|
|
||||||
islnk: False,
|
|
||||||
lastaccesstime: 1477984205,
|
|
||||||
lastwritetime: 1477984205,
|
|
||||||
owner: BUILTIN\Administrators,
|
|
||||||
path: "{{win_find_dir}}\\nested\\link\\link.ps1",
|
|
||||||
isreadonly: False,
|
|
||||||
isshared: False,
|
|
||||||
size: 14 }
|
|
||||||
- { isarchive: True,
|
|
||||||
attributes: Archive,
|
|
||||||
checksum: 8df33cee3325596517df5bb5aa980cf9c5c1fda3,
|
|
||||||
creationtime: 1477984205,
|
|
||||||
extension: .ps1,
|
|
||||||
filename: test.ps1,
|
|
||||||
ishidden: False,
|
|
||||||
isdir: False,
|
|
||||||
islnk: False,
|
|
||||||
lastaccesstime: 1477984205,
|
|
||||||
lastwritetime: 1477984205,
|
|
||||||
owner: BUILTIN\Administrators,
|
|
||||||
path: "{{win_find_dir}}\\nested\\sub-nest\\test.ps1",
|
|
||||||
isreadonly: False,
|
|
||||||
isshared: False,
|
|
||||||
size: 14 }
|
|
||||||
- { isarchive: True,
|
|
||||||
attributes: Archive,
|
|
||||||
checksum: 8df33cee3325596517df5bb5aa980cf9c5c1fda3,
|
|
||||||
creationtime: 1477984205,
|
|
||||||
extension: .ps1,
|
|
||||||
filename: test.ps1,
|
|
||||||
ishidden: False,
|
|
||||||
isdir: False,
|
|
||||||
islnk: False,
|
|
||||||
lastaccesstime: 1477984205,
|
|
||||||
lastwritetime: 1477984205,
|
|
||||||
owner: BUILTIN\Administrators,
|
|
||||||
path: "{{win_find_dir}}\\nested\\test.ps1",
|
|
||||||
isreadonly: False,
|
|
||||||
isshared: False,
|
|
||||||
size: 14 }
|
|
||||||
matched: 4
|
|
||||||
|
|
||||||
- name: assert actual == expected
|
|
||||||
assert:
|
assert:
|
||||||
that: actual == expected
|
that:
|
||||||
|
- not actual is changed
|
||||||
|
- actual.examined == 10
|
||||||
|
- actual.matched == 4
|
||||||
|
- actual.files[0].attributes == 'Archive'
|
||||||
|
- actual.files[0].checksum == '8df33cee3325596517df5bb5aa980cf9c5c1fda3'
|
||||||
|
- actual.files[0].creationtime == 1477984205
|
||||||
|
- actual.files[0].exists == True
|
||||||
|
- actual.files[0].extension == '.ps1'
|
||||||
|
- actual.files[0].filename == 'file.ps1'
|
||||||
|
- actual.files[0].hlnk_targets == []
|
||||||
|
- actual.files[0].isarchive == True
|
||||||
|
- actual.files[0].isdir == False
|
||||||
|
- actual.files[0].ishidden == False
|
||||||
|
- actual.files[0].isjunction == False
|
||||||
|
- actual.files[0].islnk == False
|
||||||
|
- actual.files[0].isreadonly == False
|
||||||
|
- actual.files[0].isreg == True
|
||||||
|
- actual.files[0].isshared == False
|
||||||
|
- actual.files[0].lastaccesstime == 1477984205
|
||||||
|
- actual.files[0].lastwritetime == 1477984205
|
||||||
|
- actual.files[0].lnk_source == None
|
||||||
|
- actual.files[0].lnk_target == None
|
||||||
|
- actual.files[0].nlink == 1
|
||||||
|
- actual.files[0].owner == 'BUILTIN\\Administrators'
|
||||||
|
- actual.files[0].path == win_find_dir + '\\nested\\file.ps1'
|
||||||
|
- actual.files[0].sharename == None
|
||||||
|
- actual.files[0].size == 14
|
||||||
|
- actual.files[1].attributes == 'Archive'
|
||||||
|
- actual.files[1].checksum == '8df33cee3325596517df5bb5aa980cf9c5c1fda3'
|
||||||
|
- actual.files[1].creationtime == 1477984205
|
||||||
|
- actual.files[1].exists == True
|
||||||
|
- actual.files[1].extension == '.ps1'
|
||||||
|
- actual.files[1].filename == 'link.ps1'
|
||||||
|
- actual.files[1].hlnk_targets == []
|
||||||
|
- actual.files[1].isarchive == True
|
||||||
|
- actual.files[1].isdir == False
|
||||||
|
- actual.files[1].ishidden == False
|
||||||
|
- actual.files[1].isjunction == False
|
||||||
|
- actual.files[1].islnk == False
|
||||||
|
- actual.files[1].isreadonly == False
|
||||||
|
- actual.files[1].isreg == True
|
||||||
|
- actual.files[1].isshared == False
|
||||||
|
- actual.files[1].lastaccesstime == 1477984205
|
||||||
|
- actual.files[1].lastwritetime == 1477984205
|
||||||
|
- actual.files[1].lnk_source == None
|
||||||
|
- actual.files[1].lnk_target == None
|
||||||
|
- actual.files[1].nlink == 1
|
||||||
|
- actual.files[1].owner == 'BUILTIN\\Administrators'
|
||||||
|
- actual.files[1].path == win_find_dir + '\\nested\\link\\link.ps1'
|
||||||
|
- actual.files[1].sharename == None
|
||||||
|
- actual.files[1].size == 14
|
||||||
|
- actual.files[2].attributes == 'Archive'
|
||||||
|
- actual.files[2].checksum == '8df33cee3325596517df5bb5aa980cf9c5c1fda3'
|
||||||
|
- actual.files[2].creationtime == 1477984205
|
||||||
|
- actual.files[2].exists == True
|
||||||
|
- actual.files[2].extension == '.ps1'
|
||||||
|
- actual.files[2].filename == 'test.ps1'
|
||||||
|
- actual.files[2].hlnk_targets == []
|
||||||
|
- actual.files[2].isarchive == True
|
||||||
|
- actual.files[2].isdir == False
|
||||||
|
- actual.files[2].ishidden == False
|
||||||
|
- actual.files[2].isjunction == False
|
||||||
|
- actual.files[2].islnk == False
|
||||||
|
- actual.files[2].isreadonly == False
|
||||||
|
- actual.files[2].isreg == True
|
||||||
|
- actual.files[2].isshared == False
|
||||||
|
- actual.files[2].lastaccesstime == 1477984205
|
||||||
|
- actual.files[2].lastwritetime == 1477984205
|
||||||
|
- actual.files[2].lnk_source == None
|
||||||
|
- actual.files[2].lnk_target == None
|
||||||
|
- actual.files[2].nlink == 1
|
||||||
|
- actual.files[2].owner == 'BUILTIN\\Administrators'
|
||||||
|
- actual.files[2].path == win_find_dir + '\\nested\\sub-nest\\test.ps1'
|
||||||
|
- actual.files[2].sharename == None
|
||||||
|
- actual.files[2].size == 14
|
||||||
|
- actual.files[3].attributes == 'Archive'
|
||||||
|
- actual.files[3].checksum == '8df33cee3325596517df5bb5aa980cf9c5c1fda3'
|
||||||
|
- actual.files[3].creationtime == 1477984205
|
||||||
|
- actual.files[3].exists == True
|
||||||
|
- actual.files[3].extension == '.ps1'
|
||||||
|
- actual.files[3].filename == 'test.ps1'
|
||||||
|
- actual.files[3].hlnk_targets == []
|
||||||
|
- actual.files[3].isarchive == True
|
||||||
|
- actual.files[3].isdir == False
|
||||||
|
- actual.files[3].ishidden == False
|
||||||
|
- actual.files[3].isjunction == False
|
||||||
|
- actual.files[3].islnk == False
|
||||||
|
- actual.files[3].isreadonly == False
|
||||||
|
- actual.files[3].isreg == True
|
||||||
|
- actual.files[3].isshared == False
|
||||||
|
- actual.files[3].lastaccesstime == 1477984205
|
||||||
|
- actual.files[3].lastwritetime == 1477984205
|
||||||
|
- actual.files[3].lnk_source == None
|
||||||
|
- actual.files[3].lnk_target == None
|
||||||
|
- actual.files[3].nlink == 1
|
||||||
|
- actual.files[3].owner == 'BUILTIN\\Administrators'
|
||||||
|
- actual.files[3].path == win_find_dir + '\\nested\\test.ps1'
|
||||||
|
- actual.files[3].sharename == None
|
||||||
|
- actual.files[3].size == 14
|
||||||
|
|
||||||
- name: find directories
|
- name: find directories
|
||||||
win_find:
|
win_find:
|
||||||
|
@ -337,32 +420,36 @@
|
||||||
file_type: directory
|
file_type: directory
|
||||||
register: actual
|
register: actual
|
||||||
|
|
||||||
- name: set expected fact for directories with recurse and follow
|
- name: assert find directories
|
||||||
set_fact:
|
|
||||||
expected:
|
|
||||||
changed: False
|
|
||||||
examined: 2
|
|
||||||
failed: False
|
|
||||||
files:
|
|
||||||
- { isarchive: False,
|
|
||||||
attributes: Directory,
|
|
||||||
creationtime: 1477984205,
|
|
||||||
filename: sub-link,
|
|
||||||
ishidden: False,
|
|
||||||
isdir: True,
|
|
||||||
islnk: False,
|
|
||||||
lastaccesstime: 1477984205,
|
|
||||||
lastwritetime: 1477984205,
|
|
||||||
owner: BUILTIN\Administrators,
|
|
||||||
path: "{{win_find_dir}}\\link-dest\\sub-link",
|
|
||||||
isreadonly: False,
|
|
||||||
isshared: False,
|
|
||||||
size: 0 }
|
|
||||||
matched: 1
|
|
||||||
|
|
||||||
- name: assert actual == expected
|
|
||||||
assert:
|
assert:
|
||||||
that: actual == expected
|
that:
|
||||||
|
- not actual is changed
|
||||||
|
- actual.examined == 2
|
||||||
|
- actual.matched == 1
|
||||||
|
- actual.files[0].attributes == 'Directory'
|
||||||
|
- actual.files[0].checksum == None
|
||||||
|
- actual.files[0].creationtime == 1477984205
|
||||||
|
- actual.files[0].exists == True
|
||||||
|
- actual.files[0].extension == None
|
||||||
|
- actual.files[0].filename == 'sub-link'
|
||||||
|
- actual.files[0].hlnk_targets == []
|
||||||
|
- actual.files[0].isarchive == False
|
||||||
|
- actual.files[0].isdir == True
|
||||||
|
- actual.files[0].ishidden == False
|
||||||
|
- actual.files[0].isjunction == False
|
||||||
|
- actual.files[0].islnk == False
|
||||||
|
- actual.files[0].isreadonly == False
|
||||||
|
- actual.files[0].isreg == False
|
||||||
|
- actual.files[0].isshared == False
|
||||||
|
- actual.files[0].lastaccesstime == 1477984205
|
||||||
|
- actual.files[0].lastwritetime == 1477984205
|
||||||
|
- actual.files[0].lnk_source == None
|
||||||
|
- actual.files[0].lnk_target == None
|
||||||
|
- actual.files[0].nlink == 1
|
||||||
|
- actual.files[0].owner == 'BUILTIN\\Administrators'
|
||||||
|
- actual.files[0].path == win_find_dir + '\\link-dest\\sub-link'
|
||||||
|
- actual.files[0].sharename == None
|
||||||
|
- actual.files[0].size == None
|
||||||
|
|
||||||
- name: find directories recurse and follow with a broken link
|
- name: find directories recurse and follow with a broken link
|
||||||
win_find:
|
win_find:
|
||||||
|
@ -375,12 +462,15 @@
|
||||||
- name: check directory count with recurse and follow is correct
|
- name: check directory count with recurse and follow is correct
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
|
- not actual is changed
|
||||||
- actual.examined == 37
|
- actual.examined == 37
|
||||||
- actual.matched == 17
|
- actual.matched == 17
|
||||||
- actual.files[0].filename == 'broken-link'
|
- actual.files[0].filename == 'broken-link'
|
||||||
|
- actual.files[0].isjunction == False
|
||||||
- actual.files[0].islnk == True
|
- actual.files[0].islnk == True
|
||||||
- actual.files[6].filename == 'junction-link'
|
- actual.files[6].filename == 'junction-link'
|
||||||
- actual.files[6].islnk == True
|
- actual.files[6].isjunction == True
|
||||||
|
- actual.files[6].islnk == False
|
||||||
- actual.files[6].lnk_source == win_find_dir + '\\junction-link-dest'
|
- actual.files[6].lnk_source == win_find_dir + '\\junction-link-dest'
|
||||||
- actual.files[11].filename == 'link'
|
- actual.files[11].filename == 'link'
|
||||||
- actual.files[11].islnk == True
|
- actual.files[11].islnk == True
|
||||||
|
@ -402,36 +492,37 @@
|
||||||
size: 253k
|
size: 253k
|
||||||
register: actual_with_byte
|
register: actual_with_byte
|
||||||
|
|
||||||
- name: set expected fact for files by size
|
- name: assert filter files by size
|
||||||
set_fact:
|
|
||||||
expected:
|
|
||||||
changed: False
|
|
||||||
examined: 5
|
|
||||||
failed: False
|
|
||||||
files:
|
|
||||||
- { isarchive: True,
|
|
||||||
attributes: Archive,
|
|
||||||
checksum: f8d100cdcf0e6c1007db2f8dd0b7ee2884df89af,
|
|
||||||
creationtime: 1477984205,
|
|
||||||
extension: ".ps1",
|
|
||||||
filename: large.ps1,
|
|
||||||
ishidden: False,
|
|
||||||
isdir: False,
|
|
||||||
islnk: False,
|
|
||||||
lastaccesstime: 1477984205,
|
|
||||||
lastwritetime: 1477984205,
|
|
||||||
owner: BUILTIN\Administrators,
|
|
||||||
path: "{{win_find_dir}}\\single\\large.ps1",
|
|
||||||
isreadonly: False,
|
|
||||||
isshared: False,
|
|
||||||
size: 260002 }
|
|
||||||
matched: 1
|
|
||||||
|
|
||||||
- name: assert actual == expected
|
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- actual_without_byte == expected
|
- not actual_without_byte is changed
|
||||||
- actual_with_byte == expected
|
- actual_without_byte.examined == 5
|
||||||
|
- actual_without_byte.matched == 1
|
||||||
|
- actual_without_byte.files[0].attributes == 'Archive'
|
||||||
|
- actual_without_byte.files[0].checksum == 'f8d100cdcf0e6c1007db2f8dd0b7ee2884df89af'
|
||||||
|
- actual_without_byte.files[0].creationtime == 1477984205
|
||||||
|
- actual_without_byte.files[0].exists == True
|
||||||
|
- actual_without_byte.files[0].extension == '.ps1'
|
||||||
|
- actual_without_byte.files[0].filename == 'large.ps1'
|
||||||
|
- actual_without_byte.files[0].hlnk_targets == []
|
||||||
|
- actual_without_byte.files[0].isarchive == True
|
||||||
|
- actual_without_byte.files[0].isdir == False
|
||||||
|
- actual_without_byte.files[0].ishidden == False
|
||||||
|
- actual_without_byte.files[0].isjunction == False
|
||||||
|
- actual_without_byte.files[0].islnk == False
|
||||||
|
- actual_without_byte.files[0].isreadonly == False
|
||||||
|
- actual_without_byte.files[0].isreg == True
|
||||||
|
- actual_without_byte.files[0].isshared == False
|
||||||
|
- actual_without_byte.files[0].lastaccesstime == 1477984205
|
||||||
|
- actual_without_byte.files[0].lastwritetime == 1477984205
|
||||||
|
- actual_without_byte.files[0].lnk_source == None
|
||||||
|
- actual_without_byte.files[0].lnk_target == None
|
||||||
|
- actual_without_byte.files[0].nlink == 1
|
||||||
|
- actual_without_byte.files[0].owner == 'BUILTIN\\Administrators'
|
||||||
|
- actual_without_byte.files[0].path == win_find_dir + '\\single\\large.ps1'
|
||||||
|
- actual_without_byte.files[0].sharename == None
|
||||||
|
- actual_without_byte.files[0].size == 260002
|
||||||
|
- actual_without_byte == actual_with_byte
|
||||||
|
|
||||||
- name: filter files by size (less than) without byte specified
|
- name: filter files by size (less than) without byte specified
|
||||||
win_find:
|
win_find:
|
||||||
|
@ -445,36 +536,37 @@
|
||||||
size: -4b
|
size: -4b
|
||||||
register: actual_with_byte
|
register: actual_with_byte
|
||||||
|
|
||||||
- name: set expected fact for files by size (less than)
|
- name: assert filter files by size (less than) without byte specified
|
||||||
set_fact:
|
|
||||||
expected:
|
|
||||||
changed: False
|
|
||||||
examined: 5
|
|
||||||
failed: False
|
|
||||||
files:
|
|
||||||
- { isarchive: True,
|
|
||||||
attributes: Archive,
|
|
||||||
checksum: 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8,
|
|
||||||
creationtime: 1477984205,
|
|
||||||
extension: ".ps1",
|
|
||||||
filename: small.ps1,
|
|
||||||
ishidden: False,
|
|
||||||
isdir: False,
|
|
||||||
islnk: False,
|
|
||||||
lastaccesstime: 1477984205,
|
|
||||||
lastwritetime: 1477984205,
|
|
||||||
owner: BUILTIN\Administrators,
|
|
||||||
path: "{{win_find_dir}}\\single\\small.ps1",
|
|
||||||
isreadonly: False,
|
|
||||||
isshared: False,
|
|
||||||
size: 1 }
|
|
||||||
matched: 1
|
|
||||||
|
|
||||||
- name: assert actual == expected
|
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- actual_without_byte == expected
|
- not actual_without_byte is changed
|
||||||
- actual_with_byte == expected
|
- actual_without_byte.examined == 5
|
||||||
|
- actual_without_byte.matched == 1
|
||||||
|
- actual_without_byte.files[0].attributes == 'Archive'
|
||||||
|
- actual_without_byte.files[0].checksum == '86f7e437faa5a7fce15d1ddcb9eaeaea377667b8'
|
||||||
|
- actual_without_byte.files[0].creationtime == 1477984205
|
||||||
|
- actual_without_byte.files[0].exists == True
|
||||||
|
- actual_without_byte.files[0].extension == '.ps1'
|
||||||
|
- actual_without_byte.files[0].filename == 'small.ps1'
|
||||||
|
- actual_without_byte.files[0].hlnk_targets == []
|
||||||
|
- actual_without_byte.files[0].isarchive == True
|
||||||
|
- actual_without_byte.files[0].isdir == False
|
||||||
|
- actual_without_byte.files[0].ishidden == False
|
||||||
|
- actual_without_byte.files[0].isjunction == False
|
||||||
|
- actual_without_byte.files[0].islnk == False
|
||||||
|
- actual_without_byte.files[0].isreadonly == False
|
||||||
|
- actual_without_byte.files[0].isreg == True
|
||||||
|
- actual_without_byte.files[0].isshared == False
|
||||||
|
- actual_without_byte.files[0].lastaccesstime == 1477984205
|
||||||
|
- actual_without_byte.files[0].lastwritetime == 1477984205
|
||||||
|
- actual_without_byte.files[0].lnk_source == None
|
||||||
|
- actual_without_byte.files[0].lnk_target == None
|
||||||
|
- actual_without_byte.files[0].nlink == 1
|
||||||
|
- actual_without_byte.files[0].owner == 'BUILTIN\\Administrators'
|
||||||
|
- actual_without_byte.files[0].path == win_find_dir + '\\single\\small.ps1'
|
||||||
|
- actual_without_byte.files[0].sharename == None
|
||||||
|
- actual_without_byte.files[0].size == 1
|
||||||
|
- actual_without_byte == actual_with_byte
|
||||||
|
|
||||||
# For dates we cannot assert against expected as the times change, this is a poor mans attempt at testing
|
# For dates we cannot assert against expected as the times change, this is a poor mans attempt at testing
|
||||||
- name: filter files by age without unit specified
|
- name: filter files by age without unit specified
|
||||||
|
@ -587,7 +679,7 @@
|
||||||
- name: assert no checksum is returned
|
- name: assert no checksum is returned
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- actual_no_checksum.files[0].checksum is undefined
|
- actual_no_checksum.files[0].checksum == None
|
||||||
|
|
||||||
# https://github.com/ansible/ansible/issues/26158
|
# https://github.com/ansible/ansible/issues/26158
|
||||||
- name: get list of files in an empty nested directory
|
- name: get list of files in an empty nested directory
|
||||||
|
@ -656,7 +748,8 @@
|
||||||
- name: assert win_find only examined 2 files with under-privileged account
|
- name: assert win_find only examined 2 files with under-privileged account
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- secure_result.examined == 2
|
- secure_result.examined == 3
|
||||||
- secure_result.matched == 2
|
- secure_result.matched == 3
|
||||||
- secure_result.files[0].path == win_find_dir + "\secure-tests\open"
|
- secure_result.files[0].path == win_find_dir + "\secure-tests\open"
|
||||||
- secure_result.files[1].path == win_find_dir + "\secure-tests\open\internal-folder"
|
- secure_result.files[1].path == win_find_dir + "\secure-tests\open\internal-folder"
|
||||||
|
- secure_result.files[2].path == win_find_dir + "\secure-tests\secure"
|
||||||
|
|
Loading…
Reference in a new issue