Skip to content

Commit

Permalink
Support fetching latest artifactory SNAPSHOT artifacts
Browse files Browse the repository at this point in the history
Fixes #282
  • Loading branch information
alexjfisher committed Jan 4, 2018
1 parent abafe6b commit 2358b23
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 3 deletions.
45 changes: 45 additions & 0 deletions lib/puppet/functions/archive/artifactory_latest_url.rb
@@ -0,0 +1,45 @@
require 'json'
require 'puppet_x/bodeco/util'

Puppet::Functions.create_function(:'archive::artifactory_latest_url') do
dispatch :artifactory_latest_url do
param 'Variant[Stdlib::HTTPUrl, Stdlib::HTTPSUrl]', :url
param 'Hash', :maven_data
end

def artifactory_latest_url(url, maven_data)
# Turn provided artifactory URL into the fileinfo API endpoint of the parent directory
uri = URI(url.sub('/artifactory/', '/artifactory/api/storage/')[%r{^(.*)/.*$}, 1])

response = PuppetX::Bodeco::Util.content(uri)
content = JSON.parse(response)

uris = if maven_data['classifier']
content['children'].select do |child|
child['uri'] =~ %r{^/#{maven_data['module']}-#{maven_data['base_rev']}-(SNAPSHOT|(?:(?:[0-9]{8}.[0-9]{6})-(?:[0-9]+)))-#{maven_data['classifier']}\.#{maven_data['ext']}$} && !child['folder']
end
else
content['children'].select do |child|
child['uri'] =~ %r{^/#{maven_data['module']}-#{maven_data['base_rev']}-(SNAPSHOT|(?:(?:[0-9]{8}.[0-9]{6})-(?:[0-9]+)))\.#{maven_data['ext']}$} && !child['folder']
end
end

raise("Couldn't find any Artifactory artifacts") if uris.empty?

latest = uris.sort_by { |x| x['uri'] }.last['uri']
Puppet.debug("Latest artifact found for #{url} was #{latest}")

# Now GET the fileinfo endpoint of the resolved latest version file
uri = URI("#{content['uri']}#{latest}")
response = PuppetX::Bodeco::Util.content(uri)
content = JSON.parse(response)

url = content['downloadUri']
sha1 = content['checksums'] && content['checksums']['sha1']

{
'url' => url,
'sha1' => sha1
}
end
end
30 changes: 30 additions & 0 deletions lib/puppet/functions/archive/parse_artifactory_url.rb
@@ -0,0 +1,30 @@
# A function to parse an Artifactory maven 2 repository URL
Puppet::Functions.create_function(:'archive::parse_artifactory_url') do
dispatch :parse_artifactory_url do
param 'Variant[Stdlib::HTTPUrl, Stdlib::HTTPSUrl]', :url
end

def parse_artifactory_url(url)
# Regex is for the 'maven-2-default Repository Layout'
matchdata = url.match(%r{
(?<base_url>.*/artifactory)
/
(?<repository>[^/]+)
/
(?<org_path>.+?)
/
(?<module>[^/]+)
/
(?<base_rev>[^/]+?)
(?:-(?<folder_iteg_rev>SNAPSHOT))?
/
\k<module>-\k<base_rev>
(?:-(?<file_iteg_rev>SNAPSHOT|(?:(?:[0-9]{8}.[0-9]{6})-(?:[0-9]+))))?
(?:-(?<classifier>[^/]+?))?
\.
(?<ext>(?:(?!\d))[^\-/]+|7z)
}x)
return nil unless matchdata
Hash[matchdata.names.zip(matchdata.captures)]
end
end
25 changes: 22 additions & 3 deletions manifests/artifactory.pp
Expand Up @@ -72,24 +72,43 @@
}

if $url {
$file_url = $url
$sha1_url = regsubst($url, '/artifactory/', '/artifactory/api/storage/')
$maven2_data = archive::parse_artifactory_url($url)
if $maven2_data and $maven2_data['folder_iteg_rev'] == 'SNAPSHOT'{
# URL represents a SNAPSHOT version. eg 'http://artifactory.example.com/artifactory/repo/com/example/artifact/0.0.1-SNAPSHOT/artifact-0.0.1-SNAPSHOT.zip'
# Only Artifactory Pro lets you download this directly but the corresponding fileinfo endpoint (where the sha1 checksum is published) doesn't exist.
# This means we can't use the artifactory_sha1 function

$latest_url_data = archive::artifactory_latest_url($url, $maven2_data)

$file_url = $latest_url_data['url']
$sha1 = $latest_url_data['sha1']
} else {
$file_url = $url
$sha1_url = regsubst($url, '/artifactory/', '/artifactory/api/storage/')
$sha1 = undef
}
} elsif $server and $port and $url_path {
warning('archive::artifactory attribute: server, port, url_path are deprecated')
$art_url = "http://${server}:${port}/artifactory"
$file_url = "${art_url}/${url_path}"
$sha1_url = "${art_url}/api/storage/${url_path}"
$sha1 = undef
} else {
fail('Please provide fully qualified url path for artifactory file.')
}

if $sha1 {
$_sha1 = $sha1
} else {
$_sha1 = artifactory_sha1($sha1_url)
}
archive { $file_path:
ensure => $ensure,
path => $file_path,
extract => $extract,
extract_path => $extract_path,
source => $file_url,
checksum => artifactory_sha1($sha1_url),
checksum => $_sha1,
checksum_type => 'sha1',
creates => $creates,
cleanup => $cleanup,
Expand Down
81 changes: 81 additions & 0 deletions spec/functions/parse_artifactory_url_spec.rb
@@ -0,0 +1,81 @@
require 'spec_helper'

describe 'archive::parse_artifactory_url' do
it { is_expected.not_to eq(nil) }
it { is_expected.to run.with_params.and_raise_error(ArgumentError) }
it { is_expected.to run.with_params('not_a_url').and_raise_error(ArgumentError) }

context 'releases' do
it do
is_expected.to run.with_params('https://repo.jfrog.org/artifactory/repo1-cache/maven-proxy/maven-proxy-webapp/0.2/maven-proxy-webapp-0.2.war').and_return(
'base_url' => 'https://repo.jfrog.org/artifactory',
'repository' => 'repo1-cache',
'org_path' => 'maven-proxy',
'module' => 'maven-proxy-webapp',
'base_rev' => '0.2',
'folder_iteg_rev' => nil,
'file_iteg_rev' => nil,
'classifier' => nil,
'ext' => 'war'
)
end
context 'with classifier' do
it do
is_expected.to run.with_params('https://repo.jfrog.org/artifactory/repo1-cache/maven-proxy/maven-proxy-standalone/0.2/maven-proxy-standalone-0.2-app.jar').and_return(
'base_url' => 'https://repo.jfrog.org/artifactory',
'repository' => 'repo1-cache',
'org_path' => 'maven-proxy',
'module' => 'maven-proxy-standalone',
'base_rev' => '0.2',
'folder_iteg_rev' => nil,
'file_iteg_rev' => nil,
'classifier' => 'app',
'ext' => 'jar'
)
end
end
end
context 'SNAPSHOTs' do
it do
is_expected.to run.with_params('https://repo.jfrog.org/artifactory/java.net-cache/com/sun/grizzly/grizzly-framework/2.0.0-SNAPSHOT/grizzly-framework-2.0.0-SNAPSHOT.jar').and_return(
'base_url' => 'https://repo.jfrog.org/artifactory',
'repository' => 'java.net-cache',
'org_path' => 'com/sun/grizzly',
'module' => 'grizzly-framework',
'base_rev' => '2.0.0',
'folder_iteg_rev' => 'SNAPSHOT',
'file_iteg_rev' => 'SNAPSHOT',
'classifier' => nil,
'ext' => 'jar'
)
end
context 'with classifiers' do
it do
is_expected.to run.with_params('https://repo.jfrog.org/artifactory/java.net-cache/com/sun/grizzly/grizzly-framework/2.0.0-SNAPSHOT/grizzly-framework-2.0.0-SNAPSHOT-javadoc.jar').and_return(
'base_url' => 'https://repo.jfrog.org/artifactory',
'repository' => 'java.net-cache',
'org_path' => 'com/sun/grizzly',
'module' => 'grizzly-framework',
'base_rev' => '2.0.0',
'folder_iteg_rev' => 'SNAPSHOT',
'file_iteg_rev' => 'SNAPSHOT',
'classifier' => 'javadoc',
'ext' => 'jar'
)
end
it do
is_expected.to run.with_params('https://repo.jfrog.org/artifactory/java.net-cache/com/sun/grizzly/grizzly-framework/2.0.0-SNAPSHOT/grizzly-framework-2.0.0-SNAPSHOT-tests.jar').and_return(
'base_url' => 'https://repo.jfrog.org/artifactory',
'repository' => 'java.net-cache',
'org_path' => 'com/sun/grizzly',
'module' => 'grizzly-framework',
'base_rev' => '2.0.0',
'folder_iteg_rev' => 'SNAPSHOT',
'file_iteg_rev' => 'SNAPSHOT',
'classifier' => 'tests',
'ext' => 'jar'
)
end
end
end
end

0 comments on commit 2358b23

Please sign in to comment.