0
votes

I want a list of URLs that will download artifacts from Artifactory. The list of URLs should come from a REST query.

I am successfully calling the Artifactory (3.2.2) REST API for various data I need. In one case, I am doing a property search, searching for artifacts with an "application_name" and "release_version". These properties were added by TeamCity when the artifacts were deployed. I can successfully search Artifactory using the Artifactory Property Search tool in the web console, and I can successfully search with those same terms from my python script.

The REST call returns json. Within that json is an array of dicts, and each of those is a {uri: url}. All good, but not quite.

The URL returns a 404 when pasted into a web browser. By walking thru the url, I discover that the /api/storage part is what's throwing off the browser. I suspect that's because this URI is not meant for browsers, but for another REST query. Sheesh.

The documentation is not clear on this. It sure seems like I should be able to get a proper browser URL from a REST call.

Example URL: "http://ourserver.org:8081/artifactory/api/storage/our-releases/com/companyname/Training/1.7.4/Training.ipa"

It's easy to replace "/api/storage" with "/simple" in that URL string and that makes the URL work in a browser. I just think it's an ugly solution. I mostly think I'm missing something, perhaps obvious.

Suggestions welcome!

2

2 Answers

0
votes

OK, got it figured.

The Artifactory REST call for Property Search does indeed return REST like URIs. There's a different REST call for File Info. The results from the File Info call include a downloadUri.

So, I first have to use the Property Search REST call, take the results from that, massage the resulting URI a bit to get the file path. That path is like "com/companyname/appgroup/artifactname/version/filename". I used urllib.parse to help with that, but still had to massage the result a bit as it still included "artifactory/repo-key".

I use the repo key and file path to make another REST call for File Info. The results of that include the downloadUri.

This seems like the long way around, but it works. It's still not as elegant as I'd like. Two REST calls take some time to finish.

0
votes

As explained in the Artifactory REST API, optional headers can be used to add extra information of the found artifact. For instance, you could try adding the header 'X-Result-Detail: info' , which will return the downloadUri property as well:

$ wget --header 'X-Result-Detail: info' 'http://<URL>/artifactory/api/search/artifact?name=dracut-fips' -O /dev/stdout
$ curl -X GET -H 'X-Result-Detail: info' 'http://<URL>/artifactory/api/search/artifact?name=dracut-fips'

Using any of the above command you can get the downloadUri and you could even easily parse it with python:

$ read -r -d '' py_get_rpm_packages << EOF
import sys, json

for obj in json.load(sys.stdin)["results"]:
    print obj["downloadUri"]
EOF
export py_get_rpm_packages

$ wget --header 'X-Result-Detail: info' 'http://<URL>/artifactory/api/search/artifact?name=dracut-fips' -O /dev/stdout | python -c "$py_get_rpm_packages"
https://<URL>/artifactory/centos7/7.1-os/dracut-fips-aesni-033-240.el7.x86_64.rpm
https://<URL>/artifactory/centos63-dvd/dracut-fips-aesni-004-283.el6.noarch.rpm

Artifactory REST API: https://www.jfrog.com/confluence/display/RTF/Artifactory+REST+API