Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

win_get_url - Make checksum work more like ansible.builtin.get_url #718

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions changelogs/fragments/717-win_get_url-checksum.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
minor_changes:
- win_get_url - if checksum is passed and destination file exists with
identical checksum no download is done unless force=yes
(https://github.com/ansible-collections/ansible.windows/issues/717)
- win_get_url - if checksum is passed and destination file exists with
different checksum file is always downloaded
(https://github.com/ansible-collections/ansible.windows/issues/717)
31 changes: 23 additions & 8 deletions plugins/modules/win_get_url.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ Function Invoke-DownloadFile {
[Parameter(Mandatory = $true)][Uri]$Uri,
[Parameter(Mandatory = $true)][String]$Dest,
[String]$Checksum,
[String]$DestChecksum,
[String]$ChecksumAlgorithm
)

Expand Down Expand Up @@ -187,14 +188,12 @@ Function Invoke-DownloadFile {

$download = $true
if (Test-Path -LiteralPath $Dest) {
# Validate the remote checksum against the existing downloaded file
$dest_checksum = Get-Checksum -Path $Dest -Algorithm $ChecksumAlgorithm

# Validate the remote checksum against the existing downloaded file.
# If we don't need to download anything, save the dest checksum so we don't waste time calculating it
# again at the end of the script
if ($dest_checksum -eq $tmp_checksum) {
if ($DestChecksum -eq $tmp_checksum) {
$download = $false
$Module.Result.checksum_dest = $dest_checksum
$Module.Result.checksum_dest = $DestChecksum
$Module.Result.size = (Get-AnsibleItem -Path $Dest).Length
}
}
Expand Down Expand Up @@ -260,17 +259,33 @@ if ($checksum_url) {
$checksum = Get-ChecksumFromUri -Module $Module -Uri $checksum_uri -SourceUri $url
}

if ($force -or -not (Test-Path -LiteralPath $dest)) {
$dest_checksum = $null
if (Test-Path -LiteralPath $dest) {
$dest_checksum = Get-Checksum -Path $dest -Algorithm $checksum_algorithm
if ($dest_checksum -ne $checksum) {
# Destination does not match checksum, force fetching
$force = $true
}
}

if ($dest_checksum -and $checksum -and $dest_checksum -eq $checksum -and -not $force) {
# No need to do any requests, the file is already as expected
$module.Result.checksum_dest = $dest_checksum
$module.Result.size = (Get-AnsibleItem -Path $dest).Length
}
elseif ($force -or -not (Test-Path -LiteralPath $dest)) {
# force=yes or dest does not exist, download the file
# Note: Invoke-DownloadFile will compare the checksums internally if dest exists
Invoke-DownloadFile -Module $module -Uri $url -Dest $dest -Checksum $checksum `
Invoke-DownloadFile -Module $module -Uri $url -Checksum $checksum `
-Dest $dest -DestChecksum $dest_checksum `
-ChecksumAlgorithm $checksum_algorithm
}
else {
# force=no, we want to check the last modified dates and only download if they don't match
$is_modified = Compare-ModifiedFile -Module $module -Uri $url -Dest $dest
if ($is_modified) {
Invoke-DownloadFile -Module $module -Uri $url -Dest $dest -Checksum $checksum `
Invoke-DownloadFile -Module $module -Uri $url -Checksum $checksum `
-Dest $dest -DestChecksum $dest_checksum `
-ChecksumAlgorithm $checksum_algorithm
}
}
Expand Down
6 changes: 6 additions & 0 deletions plugins/modules/win_get_url.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@
- If a I(checksum) is passed to this parameter, the digest of the
destination file will be calculated after it is downloaded to ensure
its integrity and verify that the transfer completed successfully.
- If a checksum is passed in this parameter or via C(checksum_url) and the
file in C(dest) exists then C(checksum_dest) is calculated.
If C(checksum_dest) equals the checksum no download is done unless
C(force) is C(true). If the checksum does not match the file is always
downloaded, as if C(force) was set. This behaviour was added in the
C(2.7.0) release of this collection.
- This option cannot be set with I(checksum_url).
type: str
checksum_algorithm:
Expand Down
10 changes: 10 additions & 0 deletions tests/integration/targets/win_get_url/tasks/tests_checksum.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,15 @@
checksum_algorithm: sha256
register: download_sha256_value

- name: re-downloading file with matching checksum should not do any downloads if force=no
win_get_url:
url: https://{{ httpbin_host }}/base64/cHR1eA==
dest: '{{ testing_dir }}\sha256.txt'
checksum: b1b6ce5073c8fac263a8fc5edfffdbd5dec1980c784e09c5bc69f8fb6056f006
checksum_algorithm: sha256
force: false
register: redownload_sha256

- name: assert download file with sha256 checksum
assert:
that:
Expand All @@ -71,6 +80,7 @@
- not download_sha256_value is changed
- download_sha256_value.status_code == 200
- download_sha256_value.checksum_dest == 'b1b6ce5073c8fac263a8fc5edfffdbd5dec1980c784e09c5bc69f8fb6056f006'
- "'status_code' not in redownload_sha256"

- name: fail download with invalid checksum and force=no
win_get_url:
Expand Down
Loading