Accessing Harbor registry through REST API
Install the registry ref: Setting up Basic Harbor Registry in a Kubernetes Cluster
01. Setup
# check and change these values if needed
cat<< EOF > config.sh
export HARBOR_URL="registry.127.0.0.1.nip.io"
export ADMIN_USER=admin
export ADMIN_PASSWORD="Harbor12345"
OUTDIR=$PWD/out
EOF
source config.sh
Getting stats about the registry
rm -rf $PWD/out
export HARBOR_URL=registry.127.0.0.1.nip.io
git clone https://github.com/naren4b/harbor-registry.git
cd harbor-registry/harbor-api
bash 01_getProjects.sh
cp out/projects.txt .
bash run.sh projects.txt
02. Create a Project
project=$1 #demo
cat<<EOF >$project.json
{
"project_name": "$project",
"public": false,
"metadata": {
"public": "false"
}
}
EOF
curl -k -s \
-X POST \
-u ${ADMIN_USER}:${ADMIN_PASSWORD} \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
"https://${HARBOR_URL}/api/v2.0/projects" \
-d @$project.json
docker login $HARBOR_URL -u $ADMIN_USER -p $ADMIN_PASSWORD
docker pull nginx:latest
docker tag nginx:latest $HARBOR_URL/library/nginx:latest
docker push $HARBOR_URL/library/nginx:latest
03. Get Projects in the Harbor Registry
page=1
while :; do
response=$(curl -k -s \
-X GET \
-u ${ADMIN_USER}:${ADMIN_PASSWORD} \
-H 'accept: application/json' \
"https://${HARBOR_URL}/api/v2.0/projects?page=$page&page_size=100")
if [[ "$response" == "[]" ]]; then
break
fi
echo $response >>out/projects.json
page=$((page + 1))
done
echo "Find projects list at out/projects.txt"
cat out/projects.json | jq -r '.[].name' >out/projects.txt
04. Get Project Repositories in a Project
project=$1
echo "Get info for $project"
rm -rf out/$project
mkdir -p out/$project
page=1
while :; do
response=$(curl -k -s \
-X GET \
-u ${ADMIN_USER}:${ADMIN_PASSWORD} \
-H 'accept: application/json' \
"https://${HARBOR_URL}/api/v2.0/projects/${project}/repositories?page=$page&page_size=100")
if [[ "$response" == "[]" ]]; then
break
fi
echo $response >>out/$project/repositories.json
page=$((page + 1))
done
# cat out/$project/repositories.json | jq .
05. Get Details of Repository
cat out/$1/repositories.json | jq -r '.[].name' >out/repos.txt
while IFS= read -r line; do
project=$(echo "$line" | cut -d'/' -f1)
repo=$(echo "$line" | cut -d'/' -f2-)
echo "$project,$repo" >>out/$1/repositories.csv
done <out/repos.txt
06. Get Image Details of a repository
file=out/$1/repositories.csv
getRepoDetails() {
project=$1
repo=$2
rm -rf out/$project/$repo
mkdir -p out/$project/$repo
page=1
while :; do
URL="""https://${HARBOR_URL}/api/v2.0/projects/${project}/repositories/${repo}/artifacts?page_size=100&page=${page}"""
response=$(curl -k -s \
-X GET \
-u ${ADMIN_USER}:${ADMIN_PASSWORD} \
-H 'accept: application/json' \
$URL)
if [[ "$response" == "[]" ]]; then
break
fi
echo $response | jq . >out/$project/$repo/response.json
cat out/$project/$repo/response.json | jq -r '.[] | "\(.addition_links.build_history.href),\(.tags[0].name),\(.size)"' | sed 's,/additions/build_history,,g' | sed 's,/api/v2.0/projects/,,g' >>out/$HARBOR_URL-size.csv
cat out/$project/$repo/response.json | jq -r '.[] | "\(.addition_links.build_history.href),\(.tags[0].name),\(.size)"' | sed 's,/additions/build_history,,g' | sed 's,/api/v2.0/projects/,,g' >>out/$project/$repo/size.csv
page=$((page + 1))
done
}
if [ -e "$file" ] && [ -s "$file" ]; then
while IFS=, read -r project repo; do
echo "Fetching for $project/$repo"
getRepoDetails $project "${repo//\//%2F}"
done <"$file"
else
if [ ! -e "$file" ]; then
echo "Error: $file does not exist."
elif [ ! -s "$file" ]; then
echo "Error: $file is empty."
fi
fi
07. Create a remote registry
url=REMOTE-Harbor.todo.com
access_key=TODO
access_secret=TODO
cat<<EOF >my-registry.json
{
"id": 0,
"url": "demo.goharbor.io",
"name": "goharbor",
"credential": {
"type": "basic",
"access_key": "$access_key",
"access_secret": "$access_secret"
},
"type": "harbor",
"insecure": true,
"description": "Demo harbor account",
"status": "string",
"creation_time": "2024-01-28T02:10:19.389Z",
"update_time": "2024-01-28T02:10:19.389Z"
}
EOF
curl -k -s \
-X POST \
-u ${ADMIN_USER}:${ADMIN_PASSWORD} \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
"https://${HARBOR_URL}/api/v2.0/registries" \
-d @my-registry.json
Integrating with Skopeo
URL=<url>
REGISTRY_ADMIN_USER=<user-id>
REGISTRY_PASSWORD=<token>
CRED="$REGISTRY_ADMIN_USER:$REGISTRY_PASSWORD"
out_file_name=$URL-image-tags-list.csv
out_file_name_summary=$URL-repository-summary-report.csv
touch $out_file_name
touch $out_file_name_summary
echo Repository ,No of Tags,Latest Image Version, Latest Image Size >$out_file_name_summary
echo URL,IMAGE_PATH,Tag,Image> $out_file_name
page=1
while true;do
response=$(curl -ks -u $CRED -H 'accept: application/json' "https://$URL/api/v2.0/repositories?page=${page}&page_size=100&with_detail=true")
for repository in $(echo $response | jq -r '.[].name'); do
echo $repository
IMAGE_PATH=$repository
tags=$(docker run quay.io/skopeo/stable:latest list-tags docker://$URL/$IMAGE_PATH --tls-verify=false --creds=$CRED | jq -r '.Tags[]')
latest_image_tag=$(echo $tags | awk '{print $NF}')
no_of_Tags=$(echo $tags | wc | awk '{print $2}')
latest_image_size=$(docker run quay.io/skopeo/stable:latest inspect docker://$URL/$IMAGE_PATH:$latest_image_tag --tls-verify=false --creds=$CRED --raw | jq -r '.layers[] | .size' | paste -sd+ | bc | awk '{printf "%.2f\n", $1 / 1024 / 1024 / 1024}')
echo $repository ,$no_of_Tags,$latest_image_tag,$latest_image_size >>$out_file_name_summary
for tag in $tags;do
image=$URL/$IMAGE_PATH:$tag
echo $image
echo $URL,$IMAGE_PATH,$tag,$image >>$out_file_name
done
done
if [[ "$response" == "[]" ]]; then
break
fi
page=$((page + 1))
done