新事物,网上没有看到同等的实现,我借鉴了几篇文章,使用http basic auth搞定。因为在API的swagger文档中,有写明认证的方式。

上代码,加注释
import requests
from requests.auth import HTTPBasicAuth
import json
# 从harborV1版本,可以想办法迁移到V2版本
class HarborReposV2:
def __init__(self, harbor_domain, username, password, schema='http'):
self.schema = schema
self.harbor_domain = harbor_domain
self.harbor_url = self.schema + '://' + harbor_domain
# 新版harbor 2版本的api地址
self.harbor_api_url = self.harbor_url + '/api/v2.0'
self.harbor_pro_url = self.harbor_api_url + '/projects'
self.username = username
self.password = password
# 使用HTTPBasicAuth认证,这也是避免那些CSRF Token Invalid的最佳办法
# 是从harbor API里看认证方式获得的启发。
self.auth = HTTPBasicAuth(self.username, self.password)
self.pros_obj = ''
self.pros_id = []
self.pro_name = ''
# fetch_pros_id和fetch_pro_name都会调用__fetch_pros_obj这个内部方法
def __fetch_pros_obj(self):
self.pros_obj = requests.get(self.harbor_pro_url, auth=self.auth).json()
return self.pros_obj
def fetch_pros_id(self):
pro_res = self.__fetch_pros_obj()
for i in pro_res:
self.pros_id.append(i['project_id'])
return self.pros_id
def fetch_pro_name(self, pro_id):
pro_res = self.__fetch_pros_obj()
for i in pro_res:
if i['project_id'] == pro_id:
self.pro_name = i['name']
pro_public = i['metadata']['public']
return self.pro_name, pro_public
def create_pros(self, pro_name, is_public):
# 好像只要三个要素,就可以新建一个project了。细节待完善。
pro_obj = dict()
pro_obj['project_name'] = pro_name
pro_obj["metadata"] = dict()
pro_obj["metadata"]["public"] = is_public
# pro_obj["metadata"]["enable_content_trust"] = i["enable_content_trust"]
# pro_obj["metadata"]["prevent_vul"] = i["prevent_vulnerable_images_from_running"]
# pro_obj["metadata"]["severity"] = i["prevent_vulnerable_images_from_running_severity"]
# pro_obj["metadata"]["auto_scan"] = i["automatically_scan_images_on_push"]
headers = {"content-type": "application/json"}
res = requests.post(self.harbor_pro_url,
auth=self.auth,
headers=headers,
data=json.dumps(pro_obj))
if res.status_code == 409:
print("\033[32m 项目 %s 已经存在!\033[0m" % pro_name)
return True
elif res.status_code == 201:
# print(res.status_code)
print("\033[33m 创建项目%s成功!\033[0m" % pro_name)
return True
else:
print("\033[35m 创建项目%s失败!\033[0m" % pro_name)
return False
# 根据project name 获取其下所有repository name。
def fetch_repos_name(self, pro_name):
repos_name = list()
harbor_repos_url = '{}/{}/repositories'.format(self.harbor_pro_url, pro_name)
repos_res = requests.get(harbor_repos_url, auth=self.auth)
for repo in repos_res.json():
repos_name.append(repo['name'])
return repos_name
# 根据project name和repository name,获取这个repo下所有tag。如果只要tag,从artifacts这个ep里就行。
def fetch_repos_tags(self, pro_name, repo_name):
repos = list()
print(repo_name)
# 官方API的说明里有,要先去除repo里包含的project名称,再使用%252F代替repo里的/
repo_name_format = '%252F'.join(repo_name.split('/')[1:])
harbor_artifacts_url = '{}/{}/repositories/{}/artifacts'.format(self.harbor_pro_url, pro_name, repo_name_format)
res_artifacts = requests.get(harbor_artifacts_url, auth=self.auth)
for item in res_artifacts.json():
for i in item['tags']:
# print(i['push_time'])
# 拼接完整的docker镜像,方便用于之后的tag更改和迁移
full_repo_name = '{}/{}:{}'.format(self.harbor_domain, repo_name, i['name'])
repos.append(full_repo_name)
return repos
if __name__ == '__main__':
# 定义常量
harbor_domain_v2 = 'harbor.demo.com.cn'
res_v2 = HarborReposV2(harbor_domain_v2, 'admin', 'Harbor12345')
# 先获取所有project的id
for pro_id in res_v2.fetch_pros_id():
pro_name, is_public = res_v2.fetch_pro_name(pro_id)
repos_name = res_v2.fetch_repos_name(pro_name=pro_name)
# 再使用project name获取其下所有repository name
for repo_name in repos_name:
# 最后,从repository name中,获取其下所有tag
repos = res_v2.fetch_repos_tags(pro_name=pro_name, repo_name=repo_name)
for full_repo_name in repos:
print('full_repo_name:', full_repo_name)
# res_v2.create_pros(pro_name, is_public)
可能输出:
3rd/nginx
full_repo_name: harbor.demo.com.cn/3rd/nginx:1.14-alpine
full_repo_name: harbor.demo.com.cn/3rd/nginx:1.13-alpine
xxx/baseos/alpine
full_repo_name: harbor.demo.com.cn/xxx/baseos/alpine:3.6
细节参考:
上面这种http basic auth,起码能解决使用/c/login登陆,出错的下面这个403错误
{
"errors": [
{
"code": "FORBIDDEN",
"message": "CSRF token invalid"
}
]
}
参考URL:
https://blog.csdn.net/qq_24794401/article/details/108068067
https://www.cnblogs.com/st12345/p/10309474.html
https://www.cnblogs.com/breezey/p/10615242.html
网友评论