Skip to content

Commit be6ddc3

Browse files
authored
Merge pull request #538 from vrtdev/feature/support-all-uri-schemas-in-checksum-url
Feature/support all uri schemas in checksum url
2 parents e472132 + 1109095 commit be6ddc3

File tree

11 files changed

+266
-187
lines changed

11 files changed

+266
-187
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,8 @@ archive { '/tmp/staging/master.zip':
480480
* `ensure`: whether archive file should be present/absent (default: present)
481481
* `path`: namevar, archive file fully qualified file path.
482482
* `filename`: archive file name (derived from path).
483-
* `source`: archive file source, supports http|https|ftp|file|s3|gs uri.
483+
* `source`: archive file source,
484+
supports puppet|http|https|ftp|file|s3|gs|abspath uri.
484485
* `headers`: array of headers to pass source, like an authentication token
485486
* `username`: username to download source file.
486487
* `password`: password to download source file.
@@ -489,7 +490,8 @@ archive { '/tmp/staging/master.zip':
489490
* `checksum_type`: archive file checksum type (none|md5|sha1|sha2|sha256|sha384|
490491
sha512). (default: none)
491492
* `checksum`: archive file checksum (match checksum_type)
492-
* `checksum_url`: archive file checksum source (instead of specify checksum)
493+
* `checksum_url`: archive file checksum source (instead of specify checksum),
494+
supports puppet|http|https|ftp|file|s3|gs|abspath uri.
493495
* `checksum_verify`: whether checksum will be verified (true|false). (default: true)
494496
* `extract`: whether archive will be extracted after download (true|false).
495497
(default: false)

REFERENCE.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -953,7 +953,8 @@ Default value: `none`
953953

954954
##### <a name="-archive--checksum_url"></a>`checksum_url`
955955

956-
archive file checksum source (instead of specifying checksum)
956+
archive file checksum source (instead of specifying checksum),
957+
supports puppet|http|https|ftp|file|s3|gs|abspath uri.
957958

958959
##### <a name="-archive--checksum_verify"></a>`checksum_verify`
959960

@@ -991,7 +992,8 @@ archive file checksum type (none|md5|sha1|sha2|sha256|sha384|sha512)
991992

992993
##### <a name="-archive--digest_url"></a>`digest_url`
993994

994-
archive file checksum source (instead of specifying checksum)
995+
archive file checksum source (instead of specifying checksum),
996+
supports puppet|http|https|ftp|file|s3|gs|abspath uri.
995997
(this parameter is for camptocamp/archive compatibility)
996998

997999
##### <a name="-archive--download_options"></a>`download_options`
@@ -1061,7 +1063,7 @@ proxy type (none|ftp|http|https)
10611063

10621064
##### <a name="-archive--source"></a>`source`
10631065

1064-
archive file source, supports puppet|http|https|ftp|file|s3|gs uri.
1066+
archive file source, supports puppet|http|https|ftp|file|s3|gs|abspath uri.
10651067

10661068
##### <a name="-archive--target"></a>`target`
10671069

@@ -1074,7 +1076,7 @@ used.
10741076

10751077
##### <a name="-archive--url"></a>`url`
10761078

1077-
archive file source, supports http|https|ftp|file uri.
1079+
archive file source, supports puppet|http|https|ftp|file|s3|gs|abspath uri.
10781080
(for camptocamp/archive compatibility)
10791081

10801082
##### <a name="-archive--user"></a>`user`

lib/puppet/provider/archive/curl.rb

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
require 'tempfile'
55

66
Puppet::Type.type(:archive).provide(:curl, parent: :ruby) do
7+
desc 'Curl-based implementation of the Archive resource type for http(s)/ftp-based urls.'
78
commands curl: 'curl'
89
defaultfor feature: :posix
910

10-
def curl_params(params)
11+
def curl_params(location, params)
1112
params_ordered = []
1213
params_ordered += optional_switch(resource[:headers], ['--header', '%s']) if resource[:headers]
14+
params_ordered += [location]
1315
params_ordered += params
1416

1517
if resource[:username]
@@ -18,7 +20,7 @@ def curl_params(params)
1820
account = [resource[:username], resource[:password]].compact.join(':')
1921
params_ordered += optional_switch(account, ['--user', '%s'])
2022
else
21-
create_netrcfile
23+
create_netrcfile(location)
2224
params_ordered += ['--netrc-file', @netrc_file.path]
2325
end
2426
end
@@ -30,9 +32,9 @@ def curl_params(params)
3032
params_ordered
3133
end
3234

33-
def create_netrcfile
35+
def create_netrcfile(location)
3436
@netrc_file = Tempfile.new('.puppet_archive_curl')
35-
machine = URI.parse(resource[:source]).host
37+
machine = URI.parse(location).host
3638
@netrc_file.write("machine #{machine}\nlogin #{resource[:username]}\npassword #{resource[:password]}\n")
3739
@netrc_file.close
3840
end
@@ -44,10 +46,10 @@ def delete_netrcfile
4446
@netrc_file = nil
4547
end
4648

47-
def download(filepath)
49+
def download(location, filepath)
4850
params = curl_params(
51+
location,
4952
[
50-
resource[:source],
5153
'-o',
5254
filepath,
5355
'-fsSLg',
@@ -62,21 +64,4 @@ def download(filepath)
6264
delete_netrcfile
6365
end
6466
end
65-
66-
def remote_checksum
67-
params = curl_params(
68-
[
69-
resource[:checksum_url],
70-
'-fsSLg',
71-
'--max-redirs',
72-
5
73-
]
74-
)
75-
76-
begin
77-
curl(params)[%r{\b[\da-f]{32,128}\b}i]
78-
ensure
79-
delete_netrcfile
80-
end
81-
end
8267
end

lib/puppet/provider/archive/ruby.rb

Lines changed: 45 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
#
6060

6161
Puppet::Type.type(:archive).provide(:ruby) do
62+
desc 'Archive resource type for Puppet.'
6263
optional_commands aws: 'aws'
6364
optional_commands gsutil: 'gsutil'
6465
defaultfor feature: :microsoft_windows
@@ -112,15 +113,12 @@ def checksum
112113
end
113114

114115
def remote_checksum
115-
PuppetX::Bodeco::Util.content(
116-
resource[:checksum_url],
117-
username: resource[:username],
118-
password: resource[:password],
119-
cookie: resource[:cookie],
120-
proxy_server: resource[:proxy_server],
121-
proxy_type: resource[:proxy_type],
122-
insecure: resource[:allow_insecure]
123-
)[%r{\b[\da-f]{32,128}\b}i]
116+
temp_path = download_file(resource[:checksum_url])
117+
raise(Puppet::Error, 'Unable to create temporary checksum file.') if temp_path.nil?
118+
119+
File.read(temp_path)[%r{\b[\da-f]{32,128}\b}i]
120+
ensure
121+
FileUtils.rm_f(temp_path) if temp_path && File.exist?(temp_path)
124122
end
125123

126124
# Private: See if local archive checksum matches.
@@ -160,46 +158,48 @@ def extracted?
160158
end
161159

162160
def transfer_download(archive_filepath)
163-
raise Puppet::Error, "Temporary directory #{resource[:temp_dir]} doesn't exist" if resource[:temp_dir] && !File.directory?(resource[:temp_dir])
161+
raise(Puppet::Error, 'Unable to fetch archive, the source parameter is nil.') if resource[:source].nil?
164162

165-
tempfile = Tempfile.new(tempfile_name, resource[:temp_dir])
166-
167-
temppath = tempfile.path
168-
tempfile.close!
169-
170-
case resource[:source]
171-
when %r{^(puppet)}
172-
puppet_download(temppath)
173-
when %r{^(http|ftp)}
174-
download(temppath)
175-
when %r{^file}
176-
uri = URI(resource[:source])
177-
FileUtils.copy(Puppet::Util.uri_to_path(uri), temppath)
178-
when %r{^s3}
179-
s3_download(temppath)
180-
when %r{^gs}
181-
gs_download(temppath)
182-
when nil
183-
raise(Puppet::Error, 'Unable to fetch archive, the source parameter is nil.')
184-
else
185-
raise(Puppet::Error, "Source file: #{resource[:source]} does not exists.") unless File.exist?(resource[:source])
186-
187-
FileUtils.copy(resource[:source], temppath)
188-
end
163+
temp_path = download_file(resource[:source])
164+
raise(Puppet::Error, 'Unable to create temporary file.') if temp_path.nil?
189165

190166
# conditionally verify checksum:
191167
if resource[:checksum_verify] == :true && resource[:checksum_type] != :none
192-
archive = PuppetX::Bodeco::Archive.new(temppath)
168+
archive = PuppetX::Bodeco::Archive.new(temp_path)
193169
actual_checksum = archive.checksum(resource[:checksum_type])
194170
if actual_checksum != checksum
195171
destroy
196172
raise(Puppet::Error, "Download file checksum mismatch (expected: #{checksum} actual: #{actual_checksum})")
197173
end
198174
end
199175

200-
move_file_in_place(temppath, archive_filepath)
176+
move_file_in_place(temp_path, archive_filepath)
201177
ensure
202-
FileUtils.rm_f(temppath) if File.exist?(temppath)
178+
FileUtils.rm_f(temp_path) if temp_path && File.exist?(temp_path)
179+
end
180+
181+
def download_file(location)
182+
raise Puppet::Error, "Temporary directory #{resource[:temp_dir]} doesn't exist" if resource[:temp_dir] && !File.directory?(resource[:temp_dir])
183+
184+
Dir::Tmpname.create(tempfile_name, resource[:temp_dir]) do |temp_path|
185+
case location
186+
when %r{^(puppet)}
187+
puppet_download(location, temp_path)
188+
when %r{^(http|ftp)}
189+
download(location, temp_path)
190+
when %r{^file}
191+
uri = URI(location)
192+
FileUtils.copy(Puppet::Util.uri_to_path(uri), temp_path)
193+
when %r{^s3}
194+
s3_download(location, temp_path)
195+
when %r{^gs}
196+
gs_download(location, temp_path)
197+
else
198+
raise(Puppet::Error, "Source file: #{location} does not exists.") unless File.exist?(location)
199+
200+
FileUtils.copy(location, temp_path)
201+
end
202+
end
203203
end
204204

205205
def move_file_in_place(from, to)
@@ -208,9 +208,9 @@ def move_file_in_place(from, to)
208208
FileUtils.mv(from, to)
209209
end
210210

211-
def download(filepath)
211+
def download(location, filepath)
212212
PuppetX::Bodeco::Util.download(
213-
resource[:source],
213+
location,
214214
filepath,
215215
username: resource[:username],
216216
password: resource[:password],
@@ -221,29 +221,29 @@ def download(filepath)
221221
)
222222
end
223223

224-
def puppet_download(filepath)
224+
def puppet_download(location, filepath)
225225
PuppetX::Bodeco::Util.puppet_download(
226-
resource[:source],
226+
location,
227227
filepath
228228
)
229229
end
230230

231-
def s3_download(path)
231+
def s3_download(location, path)
232232
params = [
233233
's3',
234234
'cp',
235-
resource[:source],
235+
location,
236236
path
237237
]
238238
params += resource[:download_options] if resource[:download_options]
239239

240240
aws(params)
241241
end
242242

243-
def gs_download(path)
243+
def gs_download(location, path)
244244
params = [
245245
'cp',
246-
resource[:source],
246+
location,
247247
path
248248
]
249249
params += resource[:download_options] if resource[:download_options]
Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# frozen_string_literal: true
22

33
Puppet::Type.type(:archive).provide(:wget, parent: :ruby) do
4+
desc 'Wget-based implementation of the Archive resource type for http(s)/ftp-based urls.'
45
commands wget: 'wget'
56

67
def wget_params(params)
@@ -16,31 +17,18 @@ def wget_params(params)
1617
params
1718
end
1819

19-
def download(filepath)
20-
params = wget_params(
20+
def download(location, filepath)
21+
command = wget_params(
2122
[
22-
Shellwords.shellescape(resource[:source]),
23+
'wget',
24+
Shellwords.shellescape(location),
2325
'-O',
2426
filepath,
2527
'--max-redirect=5'
2628
]
2729
)
2830

2931
# NOTE: Do NOT use wget(params) until https://tickets.puppetlabs.com/browse/PUP-6066 is resolved.
30-
command = "wget #{params.join(' ')}"
3132
Puppet::Util::Execution.execute(command)
3233
end
33-
34-
def remote_checksum
35-
params = wget_params(
36-
[
37-
'-qO-',
38-
Shellwords.shellescape(resource[:checksum_url]),
39-
'--max-redirect=5'
40-
]
41-
)
42-
43-
command = "wget #{params.join(' ')}"
44-
Puppet::Util::Execution.execute(command)[%r{\b[\da-f]{32,128}\b}i]
45-
end
4634
end

lib/puppet/type/archive.rb

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -118,17 +118,17 @@ def should_to_s(value)
118118
end
119119

120120
newparam(:source) do
121-
desc 'archive file source, supports puppet|http|https|ftp|file|s3|gs uri.'
121+
desc 'archive file source, supports puppet|http|https|ftp|file|s3|gs|abspath uri.'
122122
validate do |value|
123123
raise ArgumentError, "invalid source url: #{value}" unless value =~ %r{puppet|http|https|ftp|file|s3|gs} || Puppet::Util.absolute_path?(value)
124124
end
125125
end
126126

127127
newparam(:url) do
128-
desc 'archive file source, supports http|https|ftp|file uri.
128+
desc 'archive file source, supports puppet|http|https|ftp|file|s3|gs|abspath uri.
129129
(for camptocamp/archive compatibility)'
130130
validate do |value|
131-
raise ArgumentError, "invalid source url: #{value}" unless value =~ %r{http|https|file|ftp}
131+
raise ArgumentError, "invalid source url: #{value}" unless value =~ %r{puppet|http|https|ftp|file|s3|gs} || Puppet::Util.absolute_path?(value)
132132
end
133133
munge do |val|
134134
resource[:source] = val
@@ -166,11 +166,19 @@ def should_to_s(value)
166166
end
167167

168168
newparam(:checksum_url) do
169-
desc 'archive file checksum source (instead of specifying checksum)'
169+
desc 'archive file checksum source (instead of specifying checksum),
170+
supports puppet|http|https|ftp|file|s3|gs|abspath uri.'
171+
validate do |value|
172+
raise ArgumentError, "invalid checksum url: #{value}" unless value =~ %r{puppet|http|https|ftp|file|s3|gs} || Puppet::Util.absolute_path?(value)
173+
end
170174
end
171175
newparam(:digest_url) do
172-
desc 'archive file checksum source (instead of specifying checksum)
176+
desc 'archive file checksum source (instead of specifying checksum),
177+
supports puppet|http|https|ftp|file|s3|gs|abspath uri.
173178
(this parameter is for camptocamp/archive compatibility)'
179+
validate do |value|
180+
raise ArgumentError, "invalid digest url: #{value}" unless value =~ %r{puppet|http|https|ftp|file|s3|gs} || Puppet::Util.absolute_path?(value)
181+
end
174182
munge do |val|
175183
resource[:checksum_url] = val
176184
end

spec/acceptance/authentication_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
context 'authenticated download' do
77
let(:source) do
88
parser = URI::RFC2396_Parser.new
9-
parser.escape("http://httpbin.org/basic-auth/user/#{password}")
9+
parser.escape("http://httpbin.io/basic-auth/user/#{password}")
1010
end
1111
let(:pp) do
1212
<<-EOS
@@ -48,7 +48,7 @@
4848

4949
describe file('/tmp/testfile') do
5050
it { is_expected.to be_file }
51-
its(:content_as_json) { is_expected.to include('authenticated' => true, 'user' => 'user') }
51+
its(:content_as_json) { is_expected.to include('authorized' => true, 'user' => 'user') }
5252
end
5353
end
5454
end

0 commit comments

Comments
 (0)