# -*- coding: utf-8 -*-
# author: yuhaohao
import requests
from requests.auth import HTTPBasicAuth
from openpyxl import Workbook
from datetime import datetime
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
# Harbor服务器信息
HARBOR_URL = "https://registry.test.com"
USERNAME = "test"
PASSWORD = "1345566"
PROJECT_NAME = "test"
# 关闭SSL验证(如果是自签名证书)
VERIFY_SSL = False
def get_all_repositories():
repos = []
page = 1
while True:
url = f"{HARBOR_URL}/api/v2.0/projects/{PROJECT_NAME}/repositories?page={page}&page_size=100"
response = requests.get(url, auth=HTTPBasicAuth(USERNAME, PASSWORD), verify=VERIFY_SSL)
response.raise_for_status()
data = response.json()
if not data:
break
repos.extend(data)
page += 1
return repos
def get_all_artifacts(repository_name):
artifacts = []
page = 1
while True:
url = f"{HARBOR_URL}/api/v2.0/projects/{PROJECT_NAME}/repositories/{repository_name}/artifacts?page={page}&page_size=100"
response = requests.get(url, auth=HTTPBasicAuth(USERNAME, PASSWORD), verify=VERIFY_SSL)
response.raise_for_status()
data = response.json()
if not data:
break
artifacts.extend(data)
page += 1
return artifacts
def format_pull_time(pull_time_str):
if not pull_time_str:
return ''
try:
dt = datetime.fromisoformat(pull_time_str.replace('Z', '+00:00'))
return dt.strftime("%Y-%m-%d %H:%M:%S")
except Exception:
return ''
def main():
repositories = get_all_repositories()
all_data = []
for repo in repositories:
full_repo_name = repo['name'] # project_name/repo_name
repo_name_only = full_repo_name.split('/')[1] # 仓库名
artifacts = get_all_artifacts(repo_name_only)
for artifact in artifacts:
size_bytes = artifact.get('size', 0)
size_gb = size_bytes / (1024 * 1024 * 1024)
last_pull_time = artifact.get('pull_time', '')
formatted_pull_time = format_pull_time(last_pull_time)
tags = artifact.get('tags', [])
if tags:
for tag in tags:
all_data.append({
'镜像名称': full_repo_name,
'镜像标签': tag['name'],
'镜像大小(GB)': round(size_gb, 2),
'最后拉取时间': formatted_pull_time
})
else:
all_data.append({
'镜像名称': full_repo_name,
'镜像标签': '',
'镜像大小(GB)': round(size_gb, 2),
'最后拉取时间': formatted_pull_time
})
# 根据 镜像名称 排序,保证同名镜像连在一起
all_data.sort(key=lambda x: x['镜像名称'])
# 写入Excel
wb = Workbook()
ws = wb.active
ws.title = "Harbor镜像信息"
# 写表头
headers = ['镜像名称', '镜像标签', '镜像大小(GB)', '最后拉取时间']
ws.append(headers)
# 写数据
for item in all_data:
ws.append([
item['镜像名称'],
item['镜像标签'],
item['镜像大小(GB)'],
item['最后拉取时间']
])
# 保存文件
excel_file = "harbor镜像信息.xlsx"
wb.save(excel_file)
print(f"✅ 导出完成,文件保存为:{excel_file}")
if __name__ == "__main__":
main()