List all artifacts for a package version using the Artifactory API

3.7k views Asked by At

I want to list all assets for a given package (specific to the package version) via the Artifactory API.

I'm trying to write a script to get the assets for a package and I'd like for it to work with multiple repository types, like Maven and PyPI. I know I could use the Folder Info API to get what I need, but that relies on the repository layout, so it wouldn't work across repository types.

I'm currently using this AQL search:

curl -u user:password -X POST http://<artifactory_url>/artifactory/api/search/aql \
-H "Content-Type: text/plain" \
-d 'items.find({"repo": "libs-release-local"}, {"artifact.module.name": "com.foo.bar:fizz-buzz:1.2"})'

The response is almost what I want, but it seems to be including some assets from a different version of the package I'm searching for:

{
"results" : [ {
  "repo" : "libs-release-local",
  "path" : "com/foo/bar/fizz-buzz/1.0",
  "name" : "fizz-buzz-1.0.properties",
  "type" : "file",
  "size" : 790,
  "created" : "2020-09-29T15:35:59.233Z",
  "created_by" : "user",
  "modified" : "2020-09-29T15:35:59.181Z",
  "modified_by" : "user",
  "updated" : "2020-09-29T15:35:59.233Z"
},{
  "repo" : "libs-release-local",
  "path" : "com/foo/bar/fizz-buzz/1.1",
  "name" : "fizz-buzz-1.1.properties",
  "type" : "file",
  "size" : 790,
  "created" : "2020-09-29T15:42:34.982Z",
  "created_by" : "user",
  "modified" : "2020-09-29T15:42:34.931Z",
  "modified_by" : "user",
  "updated" : "2020-09-29T15:42:34.983Z"
},{
  "repo" : "libs-release-local",
  "path" : "com/foo/bar/fizz-buzz/1.2",
  "name" : "fizz-buzz-1.2-javadoc.jar",
  "type" : "file",
  "size" : 391843,
  "created" : "2020-09-30T18:54:41.599Z",
  "created_by" : "user",
  "modified" : "2020-09-30T18:54:40.650Z",
  "modified_by" : "user",
  "updated" : "2020-09-30T18:54:41.600Z"
},{
  "repo" : "libs-release-local",
  "path" : "com/foo/bar/fizz-buzz/1.2",
  "name" : "fizz-buzz-1.2-sources.jar",
  "type" : "file",
  "size" : 1089,
  "created" : "2020-09-30T18:54:41.764Z",
  "created_by" : "user",
  "modified" : "2020-09-30T18:54:41.710Z",
  "modified_by" : "user",
  "updated" : "2020-09-30T18:54:41.765Z"
},{
  "repo" : "libs-release-local",
  "path" : "com/foo/bar/fizz-buzz/1.2",
  "name" : "fizz-buzz-1.2.jar",
  "type" : "file",
  "size" : 1410,
  "created" : "2020-09-30T18:54:41.902Z",
  "created_by" : "user",
  "modified" : "2020-09-30T18:54:41.844Z",
  "modified_by" : "user",
  "updated" : "2020-09-30T18:54:41.903Z"
},{
  "repo" : "libs-release-local",
  "path" : "com/foo/bar/fizz-buzz/1.2",
  "name" : "fizz-buzz-1.2.module",
  "type" : "file",
  "size" : 3481,
  "created" : "2020-09-30T18:54:42.015Z",
  "created_by" : "user",
  "modified" : "2020-09-30T18:54:41.962Z",
  "modified_by" : "user",
  "updated" : "2020-09-30T18:54:42.015Z"
},{
  "repo" : "libs-release-local",
  "path" : "com/foo/bar/fizz-buzz/1.2",
  "name" : "fizz-buzz-1.2.pom",
  "type" : "file",
  "size" : 781,
  "created" : "2020-09-30T18:54:42.238Z",
  "created_by" : "user",
  "modified" : "2020-09-30T18:54:42.190Z",
  "modified_by" : "user",
  "updated" : "2020-09-30T18:54:42.238Z"
},{
  "repo" : "libs-release-local",
  "path" : "com/foo/bar/fizz-buzz/1.2",
  "name" : "fizz-buzz-1.2.properties",
  "type" : "file",
  "size" : 790,
  "created" : "2020-09-30T18:54:42.124Z",
  "created_by" : "user",
  "modified" : "2020-09-30T18:54:42.078Z",
  "modified_by" : "user",
  "updated" : "2020-09-30T18:54:42.125Z"
} ],
"range" : {
  "start_pos" : 0,
  "end_pos" : 8,
  "total" : 8
}
}

Notice how it's including the properties file for fizz-buzz 1.0 and 1.1, even though I specified 1.2 in my search.

Is there a way to get the information I'm looking for without extra version info?

2

There are 2 answers

0
Dror Bereznitsky On BEST ANSWER

You can use the new GraphQL capability which was added in Artifactory 7.9.
This new capability allows you to query the rich metadata Artifactory holds about packages, version, artifacts and more using the GraphQL query language.

You can use the metadata REST API for queries. Please notice you need to use an admin access token for authentication. For example:

curl -H "Authorization: Bearer <Your Token>" -XPOST http://localhost:8082/metadata/api/v1/query -d '{"query":"..." }'

The following query, as an example, is fetching all the files which are part of versions 1.0* of a package named hello-world. This query will work for any type of package which can be managed in Artifactory.

query {
    packages(
        filter: {
            name: "hello-world"
        }
    ) {
        edges {
            node {
                name
                packageType
                versions (filter: {name : "1.0*"}) {
                    name
                    repos {
                        name
                        leadFilePath
                    }
                    files {
                        name
                    }
                }
            }
        }
    }
}

The result would look something like

{
    "data": {
        "packages": {
            "edges": [
                {
                    "node": {
                        "name": "hello-world",
                        "packageType": "maven",
                        "versions": [
                            {
                                "name": "1.0-SNAPSHOT",
                                "repos": [
                                    {
                                        "name": "kotlin-local-snapshots",
                                        "leadFilePath": "org/jetbrains/kotlin/hello-world/1.0-SNAPSHOT/hello-world-1.0-20171225.112927-1.pom"
                                    }
                                ],
                                "files": [
                                    {
                                        "name": "hello-world-1.0-20171225.112927-1.jar"
                                    },
                                    {
                                        "name": "hello-world-1.0-20171225.112927-1.pom"
                                    }
                                ]
                            }
                        ]
                    }
                },
                {
                    "node": {
                        "name": "hello-world",
                        "packageType": "maven",
                        "versions": [
                            {
                                "name": "1.0-SNAPSHOT",
                                "repos": [
                                    {
                                        "name": "kotlin-local-snapshots",
                                        "leadFilePath": "org/jetbrains/kotlin/examples/hello-world/1.0-SNAPSHOT/hello-world-1.0-20171225.112138-1.pom"
                                    }
                                ],
                                "files": [
                                    {
                                        "name": "hello-world-1.0-20171225.112138-1.jar"
                                    },
                                    {
                                        "name": "hello-world-1.0-20171225.112138-1.pom"
                                    }
                                ]
                            }
                        ]
                    }
                }
            ]
        }
    }
}
1
John Peterson On

Try the below its using the path to only find artifacts that match com/foo/bar/fizz-buzz in the repo libs-release-local and then some jq at the end to make the output better. Noticed also the type : file which eliminates some noise in terms of metdata.

You will need to define or replace USER, API_KEY, and ARTIFACTORY_URL.

curl -su "${USER}:${API_KEY}" -X POST "${ARTIFACTORY_URL}/artifactory/api/search/aql" \
   -H "content-type: text/plain" \
   -d "items.find({\"type\" : \"file\",\"\$and\":[{\"path\" : {\"\$match\" : \"com/foo/bar/fizz-buzz*\"}, \"repo\" : {\"\$match\" : \"libs-release-local\"} }]}).include(\"name\",\"repo\",\"path\",\"size\").sort({\"\$desc\": [\"size\"]})" \
|  jq -r "to_entries|map(\"\(.key)=\(.value|tostring)\")|.[]" | grep results | cut -f 2 -d = | jq .