实战使用harborAPI批量删除镜像

简介: 实战使用harborAPI批量删除镜像

起因


公司在推kubernetes,搭建了私有镜像仓库harbor,开发每天会提交多次代码,构建的镜像增多,仓库上的镜像也逐渐增多,而harbor所在服务器磁盘空间有限,且很多镜像不再需要,在harborUI上进行手工删除比较耗费时间和精力。所以,打算下一个脚本来代替手工操作,之前是使用的shell脚本,存在一些问题,没有深究。最近学习python,所以就打算用python来解决。


思路


因为我们的镜像标签都是以时间的方式,如20190411.11.23 20181212.12.12,也就是年月日.时.分。每次删除的时候都是删除一整个月的,而且是时间久远的。通过交互选择项目 仓库以及镜像的类型,来删除镜像,而镜像的类型是以标签的前6位来算的,比如201904 201812。


删除过程


选择项目→选择项目下的仓库→选择镜像的类型→删除


不足


该脚本是初始版本,还有很多功能没有完成,也没有进行丝毫的优化,完全是为了达到结果。期待各位提出相关意见。


以下是脚本具体内容,分两个脚本,一起使用,我用的是python3.6:


clean_harbor_image.py,使用时改为自己的harbor地址


#!/usr/bin/env python#--coding:utf-8--import requests# import ast# import configimport sys,json,reimport testclass Harbor_API:
    def __init__(self):
        self.login_user = 'admin'
        self.login_password = 'Harbor12345'
        ## Harbor相关登录配置
        self.login_url = 'https://xxx.xx.x.xxx/login'
        self.projects_url = 'https://xxx.xx.x.xxx/api/projects'
        self.repo_url = "https://xxx.xx.x.xxx/api/repositories?project_id="
        self.image_url = "https://xxx.xx.x.xxx/api/repositories/"
        # "https://192.168.0.1/api/repositories/testrepo%2Fcentos/tags/
        self.headers = {            'Host':'xxx.xx.x.xxx',            'Origin':'https://xxx.xx.x.xxx',            'Referer':'https://xxx.xx.x.xxx/harbor/sign-in',            'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
        }
        self.data = { 'principal': self.login_user, 'password': self.login_password }
        self.s = requests.Session()    # 获取仓库
    def get_repo(self,project_id):
        # 用join
        url = self.repo_url + str(project_id)        # print(url)
        res = self.s.get(url)
        all_repo = json.loads(res.text)
        repo_data = []        for repo in all_repo:
            data = {}
            data["id"] = repo["id"]
            data["name"] = repo["name"]
            repo_data.append(data)        return repo_data    # 获取镜像数量
    def get_image(self,project_id,repo_name):
        # 用join
        url = self.repo_url+str(project_id)+("&q=%s") % repo_name        # print(url)
        res = self.s.get(url)
        count = json.loads(res.text)[0]["tags_count"]        return count    # 获取镜像标签
    def get_image_tags(self,project_name,repo_name):
        # 用join
        url = self.image_url+project_name+"%2F"+repo_name+"/tags/"
        # print(url)
        res = self.s.get(url)
        all_tags = json.loads(res.text)
        tags_data = []        for tag in all_tags:
            tags_data.append(tag["name"])        #print("tags_data",tags_data)
        # 获取类型
        tags_seri1 = []        for i in tags_data:
            tags_seri1.append(i[0:6])        # 类型去重
        tags_seri2 = []
        [tags_seri2.append(i) for i in tags_seri1 if not i in tags_seri2]        # 根绝类型统计个数
        tags_seri3 = []        for i in tags_seri2:
            data = {}
            data["name"] = i
            data["count"] = tags_seri1.count(i)
            tags_seri3.append(data)        return tags_seri3    # 获取项目
    def get_projects(self):
        #res = self.s.get(self.projects_url)
        # res = self.s.get(self.projects_url)
        res = self.s.get(self.projects_url)        # repo_project = ast.literal_eval(res.text.encode("utf-8"))
        repo_project = json.loads(res.text)
        project_data = []        for project in repo_project:
            data = {}            # project_data[str(project['project_id']] = project['project_id']
            data["id"] = project["project_id"]
            data["name"] = project["name"]
            project_data.append(data)        return project_data    # 删除镜像
    def delete_image(self,all_tags,project_name,repo_name,seri):
        url = self.image_url+project_name+"%2F"+repo_name+"/tags/"
        # print(url)
        res = self.s.get(url)
        all_tags = json.loads(res.text)
        tags_data = []        for tag in all_tags:
            tags_data.append(tag["name"])        #print("tags_data",tags_data)
        # 用join
        url2 = self.image_url + project_name + "%2F" + repo_name + "/tags/"
        # all_tags = self.get_image_tags(project_name,repo_name)
        tag = []        for i in tags_data:
            ret = re.findall(r"%s.*" % seri,i)            #print(ret)
            if not ret:                continue
            else:
                tag.append(ret[0])        #print(tag)
        for i in tag:
            url2 = url + i
            print(url2)
            ret = self.s.delete(url2)        return ret    def login(self):
        ## 创建Session登录
        res = self.s.post(self.login_url, headers=self.headers, data=self.data,verify=False)        return res.status_codedef run():
    ss = Harbor_API()
    status_code = ss.login()    #print(status_code)
    if status_code == 200:
        all_projects = ss.get_projects()        # print(all_projects)
        print("--------当前harbor下以下项目-------")
        id_list = []        for i in all_projects: 
            print("id:%s-----项目名:%s" % (i["id"],i["name"]))
            id_list.append(i["id"])        while True:
            project_id = input("请输入上面的项目id,查看该项目下的镜像仓库:")
            project_id = int(project_id.strip())
            flag = project_id in id_list            if flag:
                all_repo = ss.get_repo(project_id)
                print("--------当前项目下有以下镜像仓库-------")
                repo_id_list = []                for i in all_repo:
                    print("id:%s-----仓库名:%s" % (i["id"],i["name"]))
                    repo_id_list.append(i["id"])                # print(repo_id_list)
                while True:
                    repo_id = input("请输入上面的仓库id,查看该项目下的镜像类别和数量:")
                    repo_id = repo_id.strip()                    # print(repo_id)
                    # print(repo_id_list)
                    # print(all_repo)
                    # flag = repo_id in repo_id_list
                    if int(repo_id) in repo_id_list:                        for i in all_repo:                            if i["id"] == int(repo_id):
                                repo_name = i["name"]
                                count = ss.get_image(project_id,repo_name)
                                repo_name = test.tt(repo_name)                        # print(repo_name)
                        # print(count)
                        for i in all_projects:                            if i["id"] == project_id:
                                project_name = i["name"]                        # print(project_name)
                        all_tags = ss.get_image_tags(project_name,repo_name)                        #print(all_tags)
                        for i in all_tags:
                            print("项目为%s,仓库为%s的镜像类型有%s,数量为%s" %(project_name,repo_name,i["name"],i["count"]))
                        seri_name = []                        for i in all_tags:
                            seri_name.append(i["name"])                        while True:
                            seri = input("请输入要删除的镜像类型,如201805:").strip()
                            flag = seri in seri_name                            if flag:                                for i in all_tags:                                    if i["name"] == seri:
                                        print("类型为%s,其数量为%s个" %(seri,i["count"]))
                                        print("project %s  repo %s seri %s" %(project_name,repo_name,seri))                                        #print(all_tags)
                                        ret = ss.delete_image(all_tags,project_name,repo_name,seri)                                        if ret:
                                            print("删除成功")
                                            quit()                            else:
                                print("false")                    else:
                        print("该仓库id不存在,请重新输入。")
            else:
                print("该id不存在,请重新输入。")
## 入口if __name__ == '__main__':
    run()


for-clean_harbor_image.py,为了获取仓库


#! /usr/bin/env pythonimport redef tt(str):
    ret = re.findall("\w{1,20}/(\w{1,20}[-_]?\w{1,20}[-_]?\w{1,20
相关文章
|
Java 测试技术 API
解决harbor上删除镜像不释放空间,无需停止harbor
解决harbor上删除镜像不释放空间 docker镜像仓库中镜像的清理,一直是个比较麻烦的事情。尤其是在测试环境当中,每天都会有大量的构建。由此会产生大量的历史镜像,而这些镜像,大多数都没有用。
3055 0
|
SQL 关系型数据库 MySQL
mysql的binlog恢复数据
mysql的binlog恢复数据
240 0
|
SQL JSON Prometheus
14-TDengine安装报警模块实现报警监测Webhook回调与邮件推送
14-TDengine安装报警模块实现报警监测Webhook回调与邮件推送
749 0
14-TDengine安装报警模块实现报警监测Webhook回调与邮件推送
|
缓存 运维 负载均衡
阿里云运维架构实践秘籍
1. 中国互联网发展编年史 2. 运维 3. 不同云盘单路随机写访问响应时间对比 4. 常见数据库性能对比 5. 常见衡量业务量级别指标 6. 如何根据PV估算服务器数量? 7. 不同业务特性计算模型 8. PV量和服务器配置/RDS配置对应表 9. 服务器CPU/内存配置模型 10. 云盘空间选择 11. 宽带的选择 12. 共享文件存储的方法 13. OSS文件管理 14. OSS数据迁移 15. 缓存 16. Session管理六种策略 17. 分库分表 18. 云迁移步骤 19. 监控方案 20. 云端安全 21. 架构阶段
1202 0
阿里云运维架构实践秘籍
|
Kubernetes 持续交付 容器
在K8S中,镜像的拉取策略有哪些?
在K8S中,镜像的拉取策略有哪些?
|
Kubernetes 监控 负载均衡
Istio:微服务开发的终极利器,你还在为繁琐的通信和部署流程烦恼吗?
本文介绍了服务网格(Service Mesh)的概念及其在微服务架构中的重要性。微服务强调围绕业务构建团队和去中心化的数据管理,带来更高的灵活性和扩展性。然而,随着服务数量增加,网络通信成为挑战,包括服务发现、路由和安全等问题。 Service Mesh如Istio应运而生,通过边车代理解决服务间通信,提供服务发现、负载均衡、智能路由、安全和监控等功能。它与Kubernetes结合,增强了容器环境的服务管理能力。Istio的bookinfo示例展示了其在多语言微服务中的应用,简化了代码中的服务调用逻辑,使开发更专注于业务本身。
1079 3
Istio:微服务开发的终极利器,你还在为繁琐的通信和部署流程烦恼吗?
|
关系型数据库 MySQL 数据库
mysql下的max_allowed_packet参数设置
mysql下的max_allowed_packet参数设置
1539 0
|
存储 缓存 NoSQL
Redis深度解析:部署模式、数据类型、存储模型与实战问题解决
Redis深度解析:部署模式、数据类型、存储模型与实战问题解决
|
索引 Python
离线安装Python依赖:以six和websocket-client为例
离线安装Python依赖:以six和websocket-client为例
642 0
|
消息中间件 关系型数据库 MySQL
实时计算 Flink版产品使用合集之CDCPipelineConnectors支持哪些数据库的采集
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStreamAPI、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。