From 7d1b4be13ac0f2ba0cebc6a6164d8c4831112d9e Mon Sep 17 00:00:00 2001 From: irwinsun Date: Mon, 4 Sep 2023 17:12:12 +0800 Subject: [PATCH] =?UTF-8?q?=E8=93=9D=E7=9B=BEDevOps=E4=BD=93=E7=B3=BB?= =?UTF-8?q?=E4=B8=8B=E5=AD=B5=E5=8C=96=E9=A1=B9=E7=9B=AE=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=E4=BA=8B=E9=A1=B9=20#8042=20=E5=88=A0=E9=99=A4=E6=97=A0?= =?UTF-8?q?=E7=94=A8=E7=9A=84=E7=9B=AE=E5=BD=95=E5=8F=8A=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/storage/README.md | 38 - docs/storage/_coverpage.md | 4 - docs/storage/_navbar.md | 2 - docs/storage/apidoc/README.md | 38 - docs/storage/apidoc/_sidebar.md | 30 - docs/storage/apidoc/auth/account.md | 620 -- docs/storage/apidoc/auth/common.md | 22 - docs/storage/apidoc/auth/ext.md | 72 - docs/storage/apidoc/auth/key.md | 139 - docs/storage/apidoc/auth/permission.md | 745 --- docs/storage/apidoc/auth/role.md | 258 - docs/storage/apidoc/auth/token.md | 273 - docs/storage/apidoc/auth/user.md | 642 -- docs/storage/apidoc/common/common.md | 93 - docs/storage/apidoc/common/search.md | 125 - docs/storage/apidoc/generic/block.md | 224 - docs/storage/apidoc/generic/simple.md | 221 - .../apidoc/generic/temporary-access.md | 169 - docs/storage/apidoc/node/metadata.md | 110 - docs/storage/apidoc/node/node.md | 661 -- docs/storage/apidoc/node/share.md | 182 - docs/storage/apidoc/package/package.md | 394 -- docs/storage/apidoc/package/stage.md | 34 - docs/storage/apidoc/registry/docker.md | 518 -- docs/storage/apidoc/registry/git.md | 67 - docs/storage/apidoc/registry/maven.md | 222 - docs/storage/apidoc/registry/npm.md | 220 - docs/storage/apidoc/registry/rds.md | 487 -- docs/storage/apidoc/registry/rpm.md | 64 - .../apidoc/replication/cluster-node.md | 458 -- docs/storage/apidoc/replication/record.md | 322 - .../storage/apidoc/replication/replication.md | 594 -- docs/storage/apidoc/repo/project.md | 81 - docs/storage/apidoc/repo/proxy-channel.md | 46 - docs/storage/apidoc/repo/repository.md | 556 -- docs/storage/apidoc/scanner/report.md | 171 - docs/storage/apidoc/scanner/scan.md | 256 - docs/storage/apidoc/scanner/scanner.md | 242 - .../apidoc/scanner/supported-scanner.md | 122 - docs/storage/apidoc/webhook/payload.md | 574 -- docs/storage/apidoc/webhook/webhook.md | 347 - docs/storage/index.html | 34 - docs/storage/install/README.md | 11 - docs/storage/install/_sidebar.md | 9 - docs/storage/install/binary/README.md | 108 - docs/storage/install/binary/backend.md | 59 - docs/storage/install/binary/consul.md | 51 - docs/storage/install/binary/frontend.md | 22 - docs/storage/install/compile.md | 2 - docs/storage/install/env.md | 158 - docs/storage/install/helm.md | 419 -- docs/storage/repository/client.md | 6 - docs/storage/repository/composer.md | 98 - docs/storage/repository/helm.md | 60 - docs/storage/repository/maven-ext.md | 69 - docs/storage/repository/maven.md | 56 - docs/storage/repository/npm.md | 48 - docs/storage/repository/oci.md | 46 - docs/storage/repository/pypi.md | 100 - docs/storage/repository/rpm.md | 201 - docs/storage/resource/bkrepo.png | Bin 62399 -> 0 bytes docs/storage/scanner/deployment.md | 41 - docs/storage/scanner/overview.md | 61 - support-files/storage/README.md | 1 - .../storage/grafana/dashboard-bkrepo.json | 1213 ---- .../storage/grafana/dashboard-jvm.json | 5647 ----------------- .../storage/grafana/dashboard-transfer.json | 658 -- support-files/storage/kubernetes/README.md | 1 - .../kubernetes/charts/bkrepo/.helmignore | 23 - .../kubernetes/charts/bkrepo/Chart.lock | 12 - .../kubernetes/charts/bkrepo/Chart.yaml | 19 - .../kubernetes/charts/bkrepo/README.md | 419 -- .../charts/bkrepo/charts/common-1.4.1.tgz | Bin 12484 -> 0 bytes .../charts/bkrepo/charts/mongodb-10.10.2.tgz | Bin 55452 -> 0 bytes .../charts/nginx-ingress-controller-7.4.8.tgz | Bin 32922 -> 0 bytes .../kubernetes/charts/bkrepo/questions.yaml | 103 - .../charts/bkrepo/templates/NOTES.txt | 59 - .../charts/bkrepo/templates/_helpers.tpl | 90 - .../bkrepo/templates/auth/configmap.yaml | 18 - .../bkrepo/templates/auth/deployment.yaml | 107 - .../charts/bkrepo/templates/auth/service.yaml | 22 - .../charts/bkrepo/templates/bklog.yaml | 58 - .../charts/bkrepo/templates/bkmonitor.yaml | 34 - .../bkrepo/templates/configmap-common.yaml | 29 - .../bkrepo/templates/docker/configmap.yaml | 32 - .../bkrepo/templates/docker/deployment.yaml | 112 - .../bkrepo/templates/docker/service.yaml | 24 - .../bkrepo/templates/gateway/deployment.yaml | 116 - .../bkrepo/templates/gateway/service.yaml | 33 - .../bkrepo/templates/generic/configmap.yaml | 21 - .../bkrepo/templates/generic/deployment.yaml | 112 - .../bkrepo/templates/generic/service.yaml | 24 - .../bkrepo/templates/helm/configmap.yaml | 21 - .../bkrepo/templates/helm/deployment.yaml | 112 - .../charts/bkrepo/templates/helm/service.yaml | 24 - .../charts/bkrepo/templates/ingress.yaml | 51 - .../bkrepo/templates/job/init-mongodb.yaml | 53 - .../bkrepo/templates/npm/configmap.yaml | 21 - .../bkrepo/templates/npm/deployment.yaml | 112 - .../charts/bkrepo/templates/npm/service.yaml | 24 - .../bkrepo/templates/opdata/configmap.yaml | 23 - .../bkrepo/templates/opdata/deployment.yaml | 112 - .../bkrepo/templates/opdata/service.yaml | 24 - .../charts/bkrepo/templates/pvc-storage.yaml | 20 - .../bkrepo/templates/pypi/configmap.yaml | 21 - .../bkrepo/templates/pypi/deployment.yaml | 112 - .../charts/bkrepo/templates/pypi/service.yaml | 24 - .../charts/bkrepo/templates/rbac/role.yaml | 26 - .../bkrepo/templates/rbac/rolebinding.yaml | 20 - .../bkrepo/templates/rbac/serviceaccount.yaml | 15 - .../templates/replication/configmap.yaml | 23 - .../templates/replication/deployment.yaml | 112 - .../bkrepo/templates/replication/service.yaml | 24 - .../templates/repository/configmap.yaml | 18 - .../templates/repository/deployment.yaml | 126 - .../bkrepo/templates/repository/service.yaml | 22 - .../charts/bkrepo/templates/tls-secret.yaml | 10 - .../charts/bkrepo/values.schema.json | 194 - .../kubernetes/charts/bkrepo/values.yaml | 595 -- .../storage/kubernetes/charts/build.sh | 99 - .../images/backend/backend.Dockerfile | 15 - .../kubernetes/images/backend/startup.sh | 19 - .../storage/kubernetes/images/build.sh | 172 - .../images/gateway/gateway.Dockerfile | 19 - .../kubernetes/images/gateway/startup.sh | 12 - .../kubernetes/images/init/init-mongodb.sh | 8 - .../kubernetes/images/init/init.Dockerfile | 8 - support-files/storage/sql/init-data.js | 194 - .../templates/#etc#bkrepo#application.yaml | 39 - .../storage/templates/#etc#bkrepo#auth.yaml | 27 - .../storage/templates/#etc#bkrepo#docker.yaml | 8 - .../templates/#etc#bkrepo#generic.yaml | 4 - .../storage/templates/#etc#bkrepo#git.yaml | 2 - .../storage/templates/#etc#bkrepo#helm.yaml | 5 - .../storage/templates/#etc#bkrepo#maven.yaml | 2 - .../storage/templates/#etc#bkrepo#npm.yaml | 6 - .../storage/templates/#etc#bkrepo#oci.yaml | 5 - .../storage/templates/#etc#bkrepo#opdata.yaml | 4 - .../templates/#etc#bkrepo#repository.yaml | 2 - .../#etc#bkrepo#scanner-executor.yaml | 9 - .../templates/#etc#bkrepo#scanner.yaml | 7 - .../storage/templates/gateway#lua#init.lua | 64 - .../templates/gateway#server.common.conf | 26 - .../gateway#vhosts#bkrepo.docker.server.conf | 43 - .../gateway#vhosts#bkrepo.helm.server.conf | 35 - .../gateway#vhosts#bkrepo.server.conf | 46 - 146 files changed, 23908 deletions(-) delete mode 100644 docs/storage/README.md delete mode 100644 docs/storage/_coverpage.md delete mode 100644 docs/storage/_navbar.md delete mode 100644 docs/storage/apidoc/README.md delete mode 100644 docs/storage/apidoc/_sidebar.md delete mode 100644 docs/storage/apidoc/auth/account.md delete mode 100644 docs/storage/apidoc/auth/common.md delete mode 100644 docs/storage/apidoc/auth/ext.md delete mode 100644 docs/storage/apidoc/auth/key.md delete mode 100644 docs/storage/apidoc/auth/permission.md delete mode 100644 docs/storage/apidoc/auth/role.md delete mode 100644 docs/storage/apidoc/auth/token.md delete mode 100644 docs/storage/apidoc/auth/user.md delete mode 100644 docs/storage/apidoc/common/common.md delete mode 100644 docs/storage/apidoc/common/search.md delete mode 100644 docs/storage/apidoc/generic/block.md delete mode 100644 docs/storage/apidoc/generic/simple.md delete mode 100644 docs/storage/apidoc/generic/temporary-access.md delete mode 100644 docs/storage/apidoc/node/metadata.md delete mode 100644 docs/storage/apidoc/node/node.md delete mode 100644 docs/storage/apidoc/node/share.md delete mode 100644 docs/storage/apidoc/package/package.md delete mode 100644 docs/storage/apidoc/package/stage.md delete mode 100644 docs/storage/apidoc/registry/docker.md delete mode 100644 docs/storage/apidoc/registry/git.md delete mode 100644 docs/storage/apidoc/registry/maven.md delete mode 100644 docs/storage/apidoc/registry/npm.md delete mode 100644 docs/storage/apidoc/registry/rds.md delete mode 100644 docs/storage/apidoc/registry/rpm.md delete mode 100644 docs/storage/apidoc/replication/cluster-node.md delete mode 100644 docs/storage/apidoc/replication/record.md delete mode 100644 docs/storage/apidoc/replication/replication.md delete mode 100644 docs/storage/apidoc/repo/project.md delete mode 100644 docs/storage/apidoc/repo/proxy-channel.md delete mode 100644 docs/storage/apidoc/repo/repository.md delete mode 100644 docs/storage/apidoc/scanner/report.md delete mode 100644 docs/storage/apidoc/scanner/scan.md delete mode 100644 docs/storage/apidoc/scanner/scanner.md delete mode 100644 docs/storage/apidoc/scanner/supported-scanner.md delete mode 100644 docs/storage/apidoc/webhook/payload.md delete mode 100644 docs/storage/apidoc/webhook/webhook.md delete mode 100644 docs/storage/index.html delete mode 100644 docs/storage/install/README.md delete mode 100644 docs/storage/install/_sidebar.md delete mode 100644 docs/storage/install/binary/README.md delete mode 100644 docs/storage/install/binary/backend.md delete mode 100644 docs/storage/install/binary/consul.md delete mode 100644 docs/storage/install/binary/frontend.md delete mode 100644 docs/storage/install/compile.md delete mode 100644 docs/storage/install/env.md delete mode 100644 docs/storage/install/helm.md delete mode 100644 docs/storage/repository/client.md delete mode 100644 docs/storage/repository/composer.md delete mode 100644 docs/storage/repository/helm.md delete mode 100644 docs/storage/repository/maven-ext.md delete mode 100644 docs/storage/repository/maven.md delete mode 100644 docs/storage/repository/npm.md delete mode 100644 docs/storage/repository/oci.md delete mode 100644 docs/storage/repository/pypi.md delete mode 100644 docs/storage/repository/rpm.md delete mode 100644 docs/storage/resource/bkrepo.png delete mode 100644 docs/storage/scanner/deployment.md delete mode 100644 docs/storage/scanner/overview.md delete mode 100644 support-files/storage/README.md delete mode 100644 support-files/storage/grafana/dashboard-bkrepo.json delete mode 100644 support-files/storage/grafana/dashboard-jvm.json delete mode 100644 support-files/storage/grafana/dashboard-transfer.json delete mode 100644 support-files/storage/kubernetes/README.md delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/.helmignore delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/Chart.lock delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/Chart.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/README.md delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/charts/common-1.4.1.tgz delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/charts/mongodb-10.10.2.tgz delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/charts/nginx-ingress-controller-7.4.8.tgz delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/questions.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/NOTES.txt delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/_helpers.tpl delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/auth/configmap.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/auth/deployment.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/auth/service.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/bklog.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/bkmonitor.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/configmap-common.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/docker/configmap.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/docker/deployment.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/docker/service.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/gateway/deployment.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/gateway/service.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/generic/configmap.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/generic/deployment.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/generic/service.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/helm/configmap.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/helm/deployment.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/helm/service.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/ingress.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/job/init-mongodb.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/npm/configmap.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/npm/deployment.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/npm/service.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/opdata/configmap.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/opdata/deployment.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/opdata/service.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/pvc-storage.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/pypi/configmap.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/pypi/deployment.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/pypi/service.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/rbac/role.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/rbac/rolebinding.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/rbac/serviceaccount.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/replication/configmap.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/replication/deployment.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/replication/service.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/repository/configmap.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/repository/deployment.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/repository/service.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/templates/tls-secret.yaml delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/values.schema.json delete mode 100644 support-files/storage/kubernetes/charts/bkrepo/values.yaml delete mode 100755 support-files/storage/kubernetes/charts/build.sh delete mode 100644 support-files/storage/kubernetes/images/backend/backend.Dockerfile delete mode 100755 support-files/storage/kubernetes/images/backend/startup.sh delete mode 100755 support-files/storage/kubernetes/images/build.sh delete mode 100644 support-files/storage/kubernetes/images/gateway/gateway.Dockerfile delete mode 100644 support-files/storage/kubernetes/images/gateway/startup.sh delete mode 100644 support-files/storage/kubernetes/images/init/init-mongodb.sh delete mode 100644 support-files/storage/kubernetes/images/init/init.Dockerfile delete mode 100644 support-files/storage/sql/init-data.js delete mode 100644 support-files/storage/templates/#etc#bkrepo#application.yaml delete mode 100644 support-files/storage/templates/#etc#bkrepo#auth.yaml delete mode 100644 support-files/storage/templates/#etc#bkrepo#docker.yaml delete mode 100644 support-files/storage/templates/#etc#bkrepo#generic.yaml delete mode 100644 support-files/storage/templates/#etc#bkrepo#git.yaml delete mode 100644 support-files/storage/templates/#etc#bkrepo#helm.yaml delete mode 100644 support-files/storage/templates/#etc#bkrepo#maven.yaml delete mode 100644 support-files/storage/templates/#etc#bkrepo#npm.yaml delete mode 100644 support-files/storage/templates/#etc#bkrepo#oci.yaml delete mode 100644 support-files/storage/templates/#etc#bkrepo#opdata.yaml delete mode 100644 support-files/storage/templates/#etc#bkrepo#repository.yaml delete mode 100644 support-files/storage/templates/#etc#bkrepo#scanner-executor.yaml delete mode 100644 support-files/storage/templates/#etc#bkrepo#scanner.yaml delete mode 100644 support-files/storage/templates/gateway#lua#init.lua delete mode 100644 support-files/storage/templates/gateway#server.common.conf delete mode 100644 support-files/storage/templates/gateway#vhosts#bkrepo.docker.server.conf delete mode 100644 support-files/storage/templates/gateway#vhosts#bkrepo.helm.server.conf delete mode 100644 support-files/storage/templates/gateway#vhosts#bkrepo.server.conf diff --git a/docs/storage/README.md b/docs/storage/README.md deleted file mode 100644 index 9fc101cb5e2..00000000000 --- a/docs/storage/README.md +++ /dev/null @@ -1,38 +0,0 @@ -# bk-repo 蓝盾制品库 - -## Overview - -蓝盾制品库是一个基于微服务架构设计的平台 -- 架构层面使用spring boot+ spring cloud的技术栈,是一个kotlin作为主要的开发语言的gradle工程,微服务网关基于openresty。 -- 功能层面提供各种类型的制品存储协议、制品代理、分发、晋级、扫描、包管理等。 -- 存储层面制品库采用多级分层的策略去接收制品文件,使用对象存储去永久的存储制品文件,使用mongodb去存储节点信息与元数据信息,对外提供高于4个9的可用性。 - - -制品库架构图![制品库架构图](resource/bkrepo.png) - -- 应用场景层 -- oss(运营支撑)层 -- 接入协议层 -- 存储与调度层 - - -## Features -- auth 统一账号、权限管理,对接bk-user、bk-iam等账号权限体系 -- repository 项目、仓库、节点管理 -- metadata 元数据管理 -- generic 通用制品管理 -- rpm rpm包管理 -- docker image、helm chart、oci 云原生镜像仓库 -- npm、composer、pypi、maven、nuget依赖源微服务 -- opdata 制品库admin服务 -- replication 制品分发微服务 -- webhook服务 webhook的订阅与推送 -- scanner scanner-executor 制品扫描 - -## Getting started -* [下载与编译](install/compile.md) -* [安装部署](install/binary/README.md) -* [API使用说明见这里](apidoc/) -* [使用Helm部署BKREPO到K8S环境](../../support-files/storage/kubernetes/README.md) - - diff --git a/docs/storage/_coverpage.md b/docs/storage/_coverpage.md deleted file mode 100644 index be178183b5a..00000000000 --- a/docs/storage/_coverpage.md +++ /dev/null @@ -1,4 +0,0 @@ -# 蓝盾制品库文档 - -[部署文档](/install/) -[接口文档](/apidoc/) diff --git a/docs/storage/_navbar.md b/docs/storage/_navbar.md deleted file mode 100644 index 2630a917943..00000000000 --- a/docs/storage/_navbar.md +++ /dev/null @@ -1,2 +0,0 @@ -- [部署文档](/install/) -- [接口文档](/apidoc/) \ No newline at end of file diff --git a/docs/storage/apidoc/README.md b/docs/storage/apidoc/README.md deleted file mode 100644 index ca5abe17674..00000000000 --- a/docs/storage/apidoc/README.md +++ /dev/null @@ -1,38 +0,0 @@ -# 蓝鲸制品库接口文档 -- **接口公共说明** - - [通用接口协议](/apidoc/common/common.md) - - [自定义搜索协议](/apidoc/common/search.md) -- **项目/仓库** - - [项目接口](/apidoc/repo/project.md) - - [仓库接口](/apidoc/repo/repository.md) - - [代理源接口](/apidoc/repo/proxy-channel.md) - - [仓库同步接口](/apidoc/repo/replication.md) -- **节点** - - [节点操作接口](/apidoc/node/node.md) - - [分享链接接口](/apidoc/node/share.md) - - [元数据接口](/apidoc/node/metadata.md) -- **制品包/版本** - - [制品包版本接口](/apidoc/package/package.md) - - [制品stage接口](/apidoc/package/stage.md) -- **Generic通用制品仓库** - - [简单文件操作](/apidoc/generic/simple.md) - - [分块文件操作](/apidoc/generic/block.md) - - [临时访问凭证](/apidoc/generic/temporary-access.md) -- **认证服务** - - [用户相关](/apidoc/auth/user.md) - - [用户token相关](/apidoc/auth/token.md) - - [角色相关](/apidoc/auth/role.md) - - [权限相关](/apidoc/auth/permission.md) - - [平台账号相关](/apidoc/auth/account.md) - - [前端相关](/apidoc/auth/ext.md) -- **依赖源扩展接口** - - [docker扩展接口](/apidoc/registry/docker.md) - - [npm扩展接口](/apidoc/registry/npm.md) - - [rpm扩展接口](/apidoc/registry/rpm.md) - - [git扩展接口](/apidoc/registry/git.md) -- **仓库操作指引** - - [oci仓库](/repository/oci.md) -- **制品扫描** - - [扫描器](/apidoc/scanner/scanner.md) - - [扫描](/apidoc/scanner/scan.md) - - [扫描报告](/apidoc/scanner/scan-report.md) diff --git a/docs/storage/apidoc/_sidebar.md b/docs/storage/apidoc/_sidebar.md deleted file mode 100644 index ee4d128a218..00000000000 --- a/docs/storage/apidoc/_sidebar.md +++ /dev/null @@ -1,30 +0,0 @@ -- **接口公共说明** - - [通用接口协议](/apidoc/common/common.md) - - [自定义搜索协议](/apidoc/common/search.md) -- **项目/仓库** - - [项目接口](/apidoc/repo/project.md) - - [仓库接口](/apidoc/repo/repository.md) - - [代理源接口](/apidoc/repo/proxy-channel.md) - - [仓库同步接口](/apidoc/repo/replication.md) -- **节点** - - [节点操作接口](/apidoc/node/node.md) - - [分享链接接口](/apidoc/node/share.md) - - [元数据接口](/apidoc/node/metadata.md) -- **制品包/版本** - - [制品包版本接口](/apidoc/package/package.md) - - [制品stage接口](/apidoc/package/stage.md) -- **Generic通用制品仓库** - - [简单文件操作](/apidoc/generic/simple.md) - - [分块文件操作](/apidoc/generic/block.md) - - [临时访问凭证](/apidoc/generic/temporary-access.md) -- **认证服务** - - [用户相关](/apidoc/auth/user.md) - - [用户token相关](/apidoc/auth/token.md) - - [角色相关](/apidoc/auth/role.md) - - [权限相关](/apidoc/auth/permission.md) - - [平台账号相关](/apidoc/auth/account.md) - - [前端相关](/apidoc/auth/ext.md) -- **依赖源扩展接口** - - [docker扩展接口](/apidoc/registry/docker.md) - - [npm扩展接口](/apidoc/registry/npm.md) - - [rpm扩展接口](/apidoc/registry/rpm.md) diff --git a/docs/storage/apidoc/auth/account.md b/docs/storage/apidoc/auth/account.md deleted file mode 100644 index 43d3a8fba30..00000000000 --- a/docs/storage/apidoc/auth/account.md +++ /dev/null @@ -1,620 +0,0 @@ -## bkrepo 平台账号相关接口 - -### 创建访问账号 - -- API: POST /auth/api/account/create -- API 名称: create_account -- 功能说明: - - 中文:创建访问账号 - - English:create account - -- input body: - -``` json -{ - "appId": "string", - "locked": false, - "authorizationGrantTypes": ["PLATFORM","AUTHORIZATION_CODE"], - "homepageUrl":"http://localhost", - "redirectUri":"http://localhost/redirect", - "scope": ["PROJECT","REPO","NODE"], - "avatarUrl": "string", - "description": "string" -} -``` -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|appId|string|是|无|应用ID|the application id| -|locked|bool|否|false|是否锁定|the account status| -|authorizationGrantTypes|set|是|无|认证授权方式,[PLATFORM,AUTHORIZATION_CODE]|the account authorization grant types| -|homepageUrl|string|授权码模式时必须|无|账号主页地址|the account homepage url| -|redirectUri|string|授权码模式时必须|无|回调地址|the redirect uri| -|avatarUrl|string|否|无|账号图标地址|the avatar url| -|scope|set|授权码模式时必须|无|权限范围[SYSTEM,PROJECT,REPO,NODE]|the account permission scope| -|description|string|否|无|账号描述信息|the account description| - -- output: - -```json -{ - "code": 0, - "message": null, - "data": { - "id": "string", - "appId": "string", - "locked": false, - "credentials": [ - { - "accessKey": "string", - "secretKey": "string", - "createdAt": "2021-08-30T18:28:49.365", - "status": "ENABLE", - "authorizationGrantType": "PLATFORM" - }, - { - "accessKey": "string", - "secretKey": "string", - "createdAt": "2021-08-30T18:28:49.365", - "status": "ENABLE", - "authorizationGrantType": "AUTHORIZATION_CODE" - } - ], - "owner": "string", - "authorizationGrantTypes": [ - "PLATFORM", - "AUTHORIZATION_CODE" - ], - "homepageUrl": "http://localhost", - "redirectUri": "http://localhost/redirect", - "avatarUrl": "string", - "scope": [ - "PROJECT", - "REPO", - "NODE" - ], - "description": "string", - "createdDate": "2021-08-30T18:28:49.366", - "lastModifiedDate": "2021-08-30T18:28:49.366" - }, - "traceId": "" -} - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | object | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - -- credentials字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|accessKey|string|accessKey |accessKey| -|secretKey|string|secretKey|secretKey | -|createdAt | date time | 创建时间 |the create time| -|status|ENUM|[ENABLE,DISABLE]|[ENABLE,DISABLE]| -|authorizationGrantType|ENUM|[PLATFORM,AUTHORIZATION_CODE]|[PLATFORM,AUTHORIZATION_CODE]| - - -### 删除访问账号 - -- API: DELETE /auth/api/account/delete/{appId} -- API 名称: delete_account -- 功能说明: - - 中文:删除访问账号 - - English:delete account - -- input body: - -``` json - -``` - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|appId|string|是|无|应用ID|the application id| - -- output: - -```json -{ - "code":0, - "data":true, - "message":"", - "traceId":"" -} -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | object | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - -### 卸载访问账号 - -- API: DELETE /auth/api/account/uninstall/{appId} -- API 名称: uninstall_account -- 功能说明: - - 中文:卸载访问账号 - - English:uninstall account - -- input body: - -``` json - -``` - -- input 字段说明 - -| 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | -| ----- | ------ | -------- | ------ | ------ | ------------------ | -| appId | string | 是 | 无 | 应用ID | the application id | - -- output: - -```json -{ - "code":0, - "data":true, - "message":"", - "traceId":"" -} -``` - -- output 字段说明 - -| 字段 | 类型 | 说明 | Description | -| ------- | -------------- | --------------------------------------- | ------------------------- | -| code | bool | 错误编码。 0表示success,>0表示失败错误 | 0:success, other: failure | -| message | result message | 错误消息 | the failure message | -| data | object | result data | the data for response | -| traceId | string | 请求跟踪id | the trace id | - -### - -### 更新访问账号 - -- API: PUT /auth/api/account/update -- API 名称: update_account -- 功能说明: - - 中文:更新访问账号 - - English:update account - -- input body: - -``` json -{ - "appId": "string", - "locked": false, - "authorizationGrantTypes": ["PLATFORM","AUTHORIZATION_CODE"], - "homepageUrl":"http://localhost", - "redirectUri":"http://localhost/redirect", - "scope": ["PROJECT","REPO","NODE"], - "avatarUrl": "string", - "description": "string" -} -``` -- input 字段说明 - - | 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | - | ----------------------- | --------- | -------------------- | ------ | ------------------------------------------- | ------------------------------------- | - | appId | string | 是 | 无 | 应用ID | the application id | - | locked | bool | 否 | false | 是否锁定 | the account status | - | authorizationGrantTypes | set | 是 | 无 | 认证授权方式,[PLATFORM,AUTHORIZATION_CODE] | the account authorization grant types | - | homepageUrl | string | 新增授权码模式时必须 | 无 | 账号主页地址 | the account homepage url | - | redirectUri | string | 新增授权码模式时必须 | 无 | 回调地址 | the redirect uri | - | avatarUrl | string | 否 | 无 | 账号图标地址 | the avatar url | - | scope | set | 新增授权码模式时必须 | 无 | 权限范围[SYSTEM,PROJECT,REPO,NODE] | the account permission scope | - | description | string | 否 | 无 | 账号描述信息 | the account description | - -- output: - -```json -{ - "code":0, - "data":true, - "message":"", - "traceId":"" -} - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | object | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - -### 查询所有访问账号(管理员权限) - -- API: GET /auth/api/account/list -- API 名称: list_account -- 功能说明: - - 中文:查询所有访问账号 - - English:list account - -- input body: - -``` json - -``` -- input 字段说明 - - -- output: - -```json -{ - "code":0, - "data":[ - { - "appId":"bkdevops", - "credentials":[ - { - "accessKey":"aaaassveee", - "createdAt":"2019-12-22T10:33:11.957Z", - "secretKey":"ssdverrrr", - "status":"ENABLE" - } - ], - "locked":true - } - ], - "message":"", - "traceId":"" -} - - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | object array| result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - -### 查询所有拥有的访问账号 - -- API: GET /auth/api/account/own/list -- API 名称: list_own_account -- 功能说明: - - 中文:查询所有拥有的访问账号 - - English:list own account - -- input body: - -``` json - -``` - -- input 字段说明 - - -- output: - -```json -{ - "code":0, - "data":[ - { - "appId":"bkdevops", - "credentials":[ - { - "accessKey":"aaaassveee", - "createdAt":"2019-12-22T10:33:11.957Z", - "secretKey":"ssdverrrr", - "status":"ENABLE" - } - ], - "locked":true - } - ], - "message":"", - "traceId":"" -} - - -``` - -- output 字段说明 - -| 字段 | 类型 | 说明 | Description | -| ------- | -------------- | --------------------------------------- | ------------------------- | -| code | bool | 错误编码。 0表示success,>0表示失败错误 | 0:success, other: failure | -| message | result message | 错误消息 | the failure message | -| data | object array | result data | the data for response | -| traceId | string | 请求跟踪id | the trace id | - -### 查询所有已授权的访问账号 - -- API: GET /auth/api/account/authorized/list -- API 名称: list_authorized_account -- 功能说明: - - 中文:查询所有已授权的访问账号 - - English:list authorized account - -- input body: - -``` json - -``` - -- input 字段说明 - - -- output: - -```json -{ - "code":0, - "data":[ - { - "appId":"bkdevops", - "credentials":[ - { - "accessKey":"aaaassveee", - "createdAt":"2019-12-22T10:33:11.957Z", - "secretKey":"ssdverrrr", - "status":"ENABLE" - } - ], - "locked":true - } - ], - "message":"", - "traceId":"" -} - - -``` - -- output 字段说明 - -| 字段 | 类型 | 说明 | Description | -| ------- | -------------- | --------------------------------------- | ------------------------- | -| code | bool | 错误编码。 0表示success,>0表示失败错误 | 0:success, other: failure | -| message | result message | 错误消息 | the failure message | -| data | object array | result data | the data for response | -| traceId | string | 请求跟踪id | the trace id | - -### - -### 获取账号下的ak/sk对 - -- API: GET /auth/api/account/credential/list/{appId} -- API 名称: list_account_credential -- 功能说明: - - 中文:查询账号的认证方式 - - English:list account credential - -- input body: - -``` json - -``` - -- input 字段说明 - -- output: - -``` -{ - "code":0, - "data":[ - { - "accessKey":"aaaa", - "createdAt":"2019-12-22T10:33:11.929Z", - "secretKey":"vbbbbb", - "status":"ENABLE" - } - ], - "message":"", - "traceId":"" -} - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | object array| result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - -### 创建账号下的ak/sk对 - -- API: POST /auth/api/account/credential/{appId}/{type} -- API 名称: create_account_credential -- 功能说明: - - 中文:查询账号的认证方式 - - English:create account credential - -- input body: - -``` json - -``` -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|appId|string|是|无|应用ID|the application id| -|Type|enum|是|无|认证授权方式[PLATFORM,AUTHORIZATION_CODE]|the authorization grant type| - -- output: - -```json -{ - "code":0, - "data":[ - { - "accessKey":"aaaaa", - "createdAt":"2019-12-22T10:50:37.073Z", - "secretKey":"cccccc", - "status":"ENABLE", - "authorizationGrantType": "PLATFORM" - } - ], - "message":"", - "traceId":"" -} - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | object array| result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - -### 删除账号下的ak/sk对 - -- API: DELETE /auth/api/account/credential/{appId}/{accessKey} -- API 名称: delete_account_credential -- 功能说明: - - 中文:删除账号下的ak/sk对 - - English:delete account credential - -- input body: - -``` json - -``` -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|appId|string|是|无|应用ID|the application id| -|accessKey|string|是|无|accessKey|accessKey| - -- output: - -```json -{ - "code":0, - "data": true, - "message":"", - "traceId":"" -} - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | object array| result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - -### 校验账号下的ak/sk对 - -- API: GET /auth/api/account/credential/{appId}/{accessKey}/{secretKey} -- API 名称: check_account_credential -- 功能说明: - - 中文:校验账号下的ak/sk对 - - English:check account credential - -- input body: - -``` json - -``` -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|appId|string|是|无|应用ID|the application id| -|accessKey|string|是|无|accessKey|accessKey| -|secretKey|string|是|无|secretKey|secretKey| - -- output: - -``` -{ - "code":0, - "data":true, - "message":"", - "traceId":"" -} - - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | object array| result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - -### 更新账号下的ak/sk对状态 - -- API: PUT /auth/api/account/credential/{appId}/{accessKey}/{status} -- API 名称: update_account_credential_status -- 功能说明: - - 中文:更新账号下的ak/sk对状态 - - English:update account credential status - -- input body: - -``` json - -``` -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|appId|string|是|无|应用ID|the application id| -|accessKey|string|是|无|accessKey|accessKey| -|status|ENUM|是|无|[ ENABLE, DISABLE]|[ ENABLE, DISABLE]| - -- output: - -``` -{ - "code":0, - "data":true, - "message":"", - "traceId":"" -} - - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | object array| result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - diff --git a/docs/storage/apidoc/auth/common.md b/docs/storage/apidoc/auth/common.md deleted file mode 100644 index 00248bfcc71..00000000000 --- a/docs/storage/apidoc/auth/common.md +++ /dev/null @@ -1,22 +0,0 @@ -# auth服务api调用认证 - - auth服务认证有提级,区别于通用协议。 - - -## 公共请求头 - -### 平台账号,优先 -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|Authorization|string|是|无|自定义Auth认证头,Platform base64(accessKey:secretKey)|Platform Auth header| -|X-BKREPO-UID|string|是|无|实际操作用户|operate user| - -### 系统admin账号 -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|Authorization|string|是|无|Basic Auth认证头,Basic base64(username:password)|Basic Auth header| - - - - - diff --git a/docs/storage/apidoc/auth/ext.md b/docs/storage/apidoc/auth/ext.md deleted file mode 100644 index f6fe0f3b9ca..00000000000 --- a/docs/storage/apidoc/auth/ext.md +++ /dev/null @@ -1,72 +0,0 @@ -## bkrepo 权限扩展接口 - - -### 部门列表 - -- API:GET /auth/api/department/list -- API 名称: list_department -- 功能说明: - - 中文:用户列表 - - English:list department - -- input body: - -``` json - -``` - -- input 字段说明 - -- output: - -``` -{ - "code":0, - "data":[ - { - "name":"研发部", - "id":"4" - } - ], - "message":"", - "traceId":"" -} - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | object | user data info |the info of user| -|traceId|string|请求跟踪id|the trace id| - - -- data 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|id | string | 用户id |the department id| -|name|string|用户名|the department name| - - - - - - - - - - - - - - - - - - - - diff --git a/docs/storage/apidoc/auth/key.md b/docs/storage/apidoc/auth/key.md deleted file mode 100644 index f5788efe749..00000000000 --- a/docs/storage/apidoc/auth/key.md +++ /dev/null @@ -1,139 +0,0 @@ -## bkrepo 平台密钥相关接口 - -### 创建密钥 - -- API: POST /auth/api/key/create -- API 名称: create_key -- 功能说明: - - 中文:创建密钥 - - English:create key - -- input body: - -``` -name: string -key: string -``` - -- input 字段说明 - -| 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | -| ---- | ------ | -------- | ------ | -------- | ------------- | -| name | string | 是 | 无 | 密钥名称 | the key name | -| key | string | 是 | 无 | 密钥 | the key value | - -- output: - -``` -{ - "code":0, - "data": null, - "message":"string", - "traceId":"string" -} - - -``` - -- output 字段说明 - -| 字段 | 类型 | 说明 | Description | -| ------- | -------------- | --------------------------------------- | ------------------------- | -| code | bool | 错误编码。 0表示success,>0表示失败错误 | 0:success, other: failure | -| message | result message | 错误消息 | the failure message | -| data | object | result data | the data for response | -| traceId | string | 请求跟踪id | the trace id | - - -### 删除密钥 - -- API: DELETE /auth/api/key/delete/{id} -- API 名称: delete_key -- 功能说明: - - 中文:删除密钥 - - English:delete key - -- input body: - -``` json - -``` - -- input 字段说明 - -| 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | -| ---- | ------ | -------- | ------ | ------ | ----------- | -| id | string | 是 | 无 | 密钥ID | the key id | - -- output: - -``` -{ - "code":0, - "data":null, - "message":"", - "traceId":"" -} - -``` - -- output 字段说明 - -| 字段 | 类型 | 说明 | Description | -| ------- | -------------- | --------------------------------------- | ------------------------- | -| code | bool | 错误编码。 0表示success,>0表示失败错误 | 0:success, other: failure | -| message | result message | 错误消息 | the failure message | -| data | object | result data | the data for response | -| traceId | string | 请求跟踪id | the trace id | - -### 查询密钥列表 - -- API: GET /auth/api/key/list -- API 名称: list_key -- 功能说明: - - 中文:查询所有访问账号 - - English:list key - -- input body: - -``` json - -``` - -- input 字段说明 - - -- output: - -``` -{ - "code": 0, - "message": null, - "data": [ - { - "id": "string", - "name": "string", - "fingerprint": "6d:3c:a7:52:ec:4d:ef:ef:6d:23:15:43:c6:ff:25:27", - "createAt": "2021-09-03T15:55:01.643" - }, - { - "id": "string", - "name": "string", - "fingerprint": "af:f6:f4:f8:38:a1:1c:8d:af:56:25:ee:b0:15:93:bc", - "createAt": "2021-09-03T15:57:27.554" - } - ], - "traceId": "" -} - -``` - -- output 字段说明 - -| 字段 | 类型 | 说明 | Description | -| ------- | -------------- | --------------------------------------- | ------------------------- | -| code | bool | 错误编码。 0表示success,>0表示失败错误 | 0:success, other: failure | -| message | result message | 错误消息 | the failure message | -| data | object array | result data | the data for response | -| traceId | string | 请求跟踪id | the trace id | - diff --git a/docs/storage/apidoc/auth/permission.md b/docs/storage/apidoc/auth/permission.md deleted file mode 100644 index b89e920b2e1..00000000000 --- a/docs/storage/apidoc/auth/permission.md +++ /dev/null @@ -1,745 +0,0 @@ -## bkrepo 权限相关接口 - -### 创建权限 - -- API: POST /auth/api/permission/create -- API 名称: create_permission -- 功能说明: - - 中文:创建权限 - - English:create permission - -- input body: - -``` json -{ - "createBy":"owen", - "excludePattern":[ - "/index" - ], - "includePattern":[ - "/path1" - ], - "permName":"perm1", - "projectId":"ops", - "repos":[ - "owen" - ], - "resourceType":"PROJECT", - "roles":[ - "abcdef" - ], - "users":[ - "owen" - ], - "departments":[ - "1", - "2" - ], - "actions":"MANAGE" -} - -``` - - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|createBy|string|是|无|创建人|the man create it| -|excludePattern|string array|否|empty array|排除路径|the exclude path| -|includePattern|string array|否|empty array|包含路径|the include path| -|projectId|string|否|null|项目ID|the project id| -|repos|string array|否|empty array|关联仓库列表|the associate repo list| -|resourceType|ENUM|是|REPO|权限类型[REPO,PROJECT,SYSTEM,NODE]|permission type [REPO,PROJECT,SYSTEM,NODE]| -|users|string array|否|empty array|权限授权用户|the auth user| -|roles|string array|否|empty array|权限授权角色|the auth role| -|departments|string array|否|empty array|权限授权角色|the auth department| - - -- output: - -``` -{ - "code":0, - "message":null, - "data":true, - "traceId":"" -} - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | bool | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - -### 删除权限 - -- API: DELETE /auth/api/permission/delete/{id} -- API 名称: delete_permission -- 功能说明: - - 中文:删除权限 - - English:delete permission - -- input body: - -``` json - - -``` - - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|id|string|是|无|权限主键ID|the permission key id| - - -- output: - -``` -{ - "code":0, - "message":null, - "data":true, - "traceId":"" -} - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | bool | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - -### 校验权限 - -- API: POST /auth/api/permission/check -- API 名称: check_permission -- 功能说明: - - 中文:校验权限 - - English:check permission - -- input body: - -``` json -{ - "action":"MANAGE", - "path":"/index", - "projectId":"ops", - "repoName":"docker-local", - "resourceType":"PROJECT", - "uid":"owen" -} - - -``` - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|action|ENUM|是|无|动作|the action| -|path|string|否|无|路径|the path| -|projectId|string|是|无|项目ID|the project id | -|repoName|string|否|无|仓库名|the name of repo | -|resourceType|ENUM|是|REPO|权限类型[REPO,PROJECT,SYSTEM,NODE]|permission type [REPO,PROJECT,SYSTEM,NODE]| -|uid|string|是|无|用户ID|the user id| - -- output: - -``` -{ - "code":0, - "message":null, - "data":true, - "traceId":"" -} - -``` -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | bool | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - -### 校验管理员 - -- API: GET /auth/api/permission/checkAdmin/{uid} -- API 名称: check_admin -- 功能说明: - - 中文:校验管理员权限 - - English:check admin permission - -- input body: - -``` json - -``` - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|uid|string|是|无|用户ID|the user id| - -- output: - -``` -{ - "code":0, - "message":null, - "data":true, - "traceId":"" -} - -``` -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | bool | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - - - -### 仓库内置权限列表 - -- API: GET /auth/api/permission/list/inrepo?projectId=ops&repoName=repo -- API 名称: list_permission -- 功能说明: - - 中文:权限列表 - - English:the permission list -- input body: - -``` json - -``` - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|projectId|string|是|无|项目ID|the project id| -|repoName|string|是|无|仓库名称|the repo name| -|resourceType|ENUM|否|无|权限类型[REPO,PROJECT,SYSTEM,NODE]|permission type [REPO,PROJECT,SYSTEM,NODE]| - -- output: -``` -{ - "code": 0, - "message": null, - "data": [ - { - "id": "5fbcc9d85fe04f126a508a3a", - "resourceType": "REPO", - "projectId": "ops", - "permName": "repo_admin", - "repos": [ - "generic" - ], - "includePattern": [], - "excludePattern": [], - "users": [], - "roles": [], - "departments": [], - "actions": [], - "createBy": "admin", - "updatedBy": "admin", - "createAt": "2020-11-24T16:52:40.575", - "updateAt": "2020-11-24T16:52:40.575" - }, - { - "id": "5fbcc9d85fe04f126a508a3b", - "resourceType": "REPO", - "projectId": "ops", - "permName": "repo_user", - "repos": [ - "generic" - ], - "includePattern": [], - "excludePattern": [], - "users": [], - "roles": [], - "departments": [], - "actions": [], - "createBy": "admin", - "updatedBy": "admin", - "createAt": "2020-11-24T16:52:40.678", - "updateAt": "2020-11-24T16:52:40.678" - }, - { - "id": "5fbcc9d85fe04f126a508a3c", - "resourceType": "REPO", - "projectId": "ops", - "permName": "repo_viewer", - "repos": [ - "generic" - ], - "includePattern": [], - "excludePattern": [], - "users": [], - "roles": [], - "departments": [], - "actions": [], - "createBy": "admin", - "updatedBy": "admin", - "createAt": "2020-11-24T16:52:40.704", - "updateAt": "2020-11-24T16:52:40.704" - } - ], - "traceId": "" -} - - -``` -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | object array | result data,具体字段见创建请求 |the data for response| -|traceId|string|请求跟踪id|the trace id| - -- data 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|users|string array|用户id|the user id| -|roles|string array|用户组id|the role id| -|departments|string array|部门id|the department id| -|actions|string array|action id|the action id| - -### 权限列表 - -- API: GET /auth/api/permission/list?projectId=ops&repoName=repo -- API 名称: list_permission -- 功能说明: - - 中文:权限列表 - - English:the permission list -- input body: - -``` json - -``` - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|projectId|string|否|无|项目ID|the project id| -|repoName|string|否|无|仓库名称|the repo name| - -- output: -``` -{ - "code":0, - "data":[ - { - "createAt":"2019-12-21T09:46:37.792Z", - "createBy":"string", - "excludePattern":[ - "/index" - ], - "id":"5ea4f6608c165f702f5bd41e", - "includePattern":[ - "/path1" - ], - "permName":"perm1", - "projectId":"ops", - "repos":[ - "docker-local" - ], - "resourceType":"REPO", - "roles":[ - "owen", - "tt" - ], - "users":[ - "op", - "dev" - ], - "departments":[ - "1", - "2" - ], - "actions":[ - "MANAGE", - "READ" - ], - "updateAt":"2019-12-21T09:46:37.792Z", - "updatedBy":"string" - } - ], - "message":"string", - "traceId":"string" -} - - -``` -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | object array | result data,具体字段见创建请求 |the data for response| -|traceId|string|请求跟踪id|the trace id| - -- data 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|users|string array|用户id|the user id| -|roles|string array|用户组id|the role id| -|departments|string array|部门id|the department id| -|actions|string array|action id|the action id| - -### 更新权限绑定仓库 - -- API: PUT /auth/api/permission/repo -- 功能说明: - - 中文:更新权限绑定仓库 - - English:update permission repo -- input body: - -``` json -{ - "permissionId":"5ea4f6608c165f702f5bd41e", - "repos":[ - "owen", - "tt" - ] -} -``` -- input 字段说明 - - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|permissionId|string|是|无|角色主键id|the permission primary key| -|repos|string array|是|[]|仓库名称列表|the repo name array| - -- output: - -``` - -``` -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | object array | result data,具体字段见创建请求 |the data for response| -|traceId|string|请求跟踪id|the trace id| - -### 更新权限绑定用户 - -- API:PUT /auth/api/permission/user -- API 名称: update_permission_user -- 功能说明: - - 中文:更新权限绑定用户 - - English:update permission user - -- input body: - -``` json -{ - "permissionId":"5ea4f6608c165f702f5bd41e", - "userId":[ - "owen", - "tt" - ] -} -``` - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|permissionId|string|是|无|角色主键id|the permission primary key| -|userId|string array|是|[]|用户id列表|the user id array| - -- output: - -``` -{ - "code":0, - "data":true, - "message":"", - "traceId":"" -} - - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | bool | the request result |the request result| -|traceId|string|请求跟踪id|the trace id| - -### 更新权限绑定角色 - -- API:PUT /auth/api/permission/role -- API 名称: update_permission_role -- 功能说明: - - 中文:更新权限绑定角色 - - English:update permission role - -- input body: - -``` json -{ - "permissionId":"5ea4f6608c165f702f5bd41e", - "rId":[ - "ops", - "dev" - ] -} -``` - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|permissionId|string|是|无|角色主键id|the permission primary key| -|rId|string array|是|[]|角色主键id列表|the role id primary key array| - -- output: - -``` -{ - "code":0, - "data":true, - "message":"", - "traceId":"" -} - -``` -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | bool | the request result |the request result| -|traceId|string|请求跟踪id|the trace id| - - -### 更新权限绑定部门 - -- API:PUT /auth/api/permission/department -- API 名称: update_permission_department -- 功能说明: - - 中文:更新角色绑定部门 - - English:update permission department - -- input body: - -``` json -{ - "permissionId":"5ea4f6608c165f702f5bd41e", - "departmentId":[ - "ops", - "dev" - ] -} -``` - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|permissionId|string|是|无|角色主键id|the permission primary key| -|departmentId|string array|是|[]|部门id列表|the department id array| - -- output: - -``` -{ - "code":0, - "data":true, - "message":"", - "traceId":"" -} - -``` -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | bool | the request result |the request result| -|traceId|string|请求跟踪id|the trace id| - -### 更新权限绑定动作 - -- API:PUT /auth/api/permission/action -- API 名称: update_permission_action -- 功能说明: - - 中文:更新角色绑定动作 - - English:update permission department - -- input body: - -``` json -{ - "permissionId":"5ea4f6608c165f702f5bd41e", - "actions":[ - "ops", - "dev" - ] -} -``` - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|permissionId|string|是|无|角色主键id|the permission primary key| -|actions|string array|是|[]|动作列表|the action list| - -- output: - -``` -{ - "code":0, - "data":true, - "message":"", - "traceId":"" -} - -``` -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | bool | the request result |the request result| -|traceId|string|请求跟踪id|the trace id| - - -### 更新权限包含路径 - -- API: PUT /auth/api/permission/includePath -- API 名称: update_include_path -- 功能说明: - - 中文:更新权限包含路径 - - English:update permission include path -- input body: - -``` json -{ - "permissionId":"5ea4f6608c165f702f5bd41e", - "path":[ - "/path1", - "/path2" - ] -} -``` - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|permissionId|string|是|无|角色主键id|the permission primary key| -|path|string array|是|[]|路径列表|the path list| - -- output: -``` -{ - "code":0, - "message":null, - "data":true, - "traceId":"" -} - -``` -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | bool | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - - -### 更新权限排除路径 - -- API: PUT /auth/api/permission/excludePath - -- API 名称: update_exclude_path -- 功能说明: - - 中文:更新权限排除路径 - - English:update permission exclude path - -- input body: - -``` json -{ - "permissionId":"5ea4f6608c165f702f5bd41e", - "path":[ - "/path1", - "/path2" - ] -} -``` - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|permissionId|string|是|无|角色主键id|the permission primary key| -|path|string array|是|[]|路径列表|the path list| - -- output: - -``` -{ - "code":0, - "message":null, - "data":true, - "traceId":"" -} - -``` -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | bool | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - - - - - - - - - diff --git a/docs/storage/apidoc/auth/role.md b/docs/storage/apidoc/auth/role.md deleted file mode 100644 index f1a96feccde..00000000000 --- a/docs/storage/apidoc/auth/role.md +++ /dev/null @@ -1,258 +0,0 @@ -## bkrepo 角色相关接口 - -### 创建角色 - -- API: POST /auth/api/role/create -- API 名称: create_role -- 功能说明: - - 中文:创建角色 - - English:create role - -- input body: - - -``` json -{ - "name":"运维", - "projectId":"ops", - "rid":"operation", - "type":"PROJECT", - "admin":false -} -``` - - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|name|string|是|无|角色名|the role name| -|projectId|string|是|无|项目id|the project id| -|rid|string|是|无|角色id|the role id| -|type|ENUM|是|无|角色类型[REPO,PROJECT]|the type of role[REPO,PROJECT]| -|admin|bool|否|false|是否管理员|is admin| - - - -- output: - -``` -{ -"code": 0, -"message": null, -"data": true, -"traceId": "" -} - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | bool | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - - -### 删除角色 - -- API: DELETE /auth/api/role/delete/{id} - -- API 名称: delete_role -- 功能说明: - - 中文:删除角色 - - English:delete role - -- input body: - -``` json - -``` - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|id|string|是|无|角色主键id|the role key id| - -- output: - -``` -{ -"code": 0, -"message": null, -"data": true, -"traceId": "" -} - -``` -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | bool | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - -### 角色详情 - -- API: GET /auth/api/role/detail/{id} - -- API 名称: role_detail -- 功能说明: - - 中文:角色详情 - - English :role detail - -- input body: - -``` json - -``` - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|id|string|是|无|角色主键id|the role key id| - -- output: - -``` -{ - "code":0, - "message":null, - "data":{ - "admin":false, - "id":"aaaaaaaa", - "name":"运维", - "projectId":"ops", - "rid":"op", - "type":"PROJECT" - }, - "traceId":"" -} - - -``` -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | object | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - -### 角色列表 - -- API: GET /auth/api/role/list?projectId=ops&repoName=dockerlocal - -- API 名称: list_role -- 功能说明: - - 中文:角色列表 - - English:list role - -- input body: - -``` json - -``` - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|projectId|string|否|无|项目id|the project id| -|repoName|string|否|无|仓库名称|the name of repository| - -- output: - -``` -{ - "code":0, - "message":null, - "data":[ - { - "admin":false, - "id":"aaaaaaaa", - "name":"运维", - "projectId":"ops", - "roleId":"op", - "type":"PROJECT" - } - ], - "traceId":"" -} - - -``` -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | object array | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - - -### 查询角色下的用户 - -- API: GET /auth/api/role/users/{id} - -- API 名称: role_user_list -- 功能说明: - - 中文:角色绑定用户列表 - - English:role user list - -- input body: - -``` json - -``` - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|id|string|是|无|角色主键id|the role primary key| - -- output: - -``` -{ - "code":0, - "message":null, - "data":[ - { - "id":"owen", - "name":"owen" - } - ], - "traceId":"" -} - - -``` -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | object array | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - -- data 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|id | string | 用户id |the user id| -|name|string|用户名|the user name| - - - - diff --git a/docs/storage/apidoc/auth/token.md b/docs/storage/apidoc/auth/token.md deleted file mode 100644 index 66fcec04b2e..00000000000 --- a/docs/storage/apidoc/auth/token.md +++ /dev/null @@ -1,273 +0,0 @@ -## bkrepo token相关接口 - -### 新增用户token - -- API:POST /auth/api/user/token/{uid}/{name}?expiredAt=2019-12-21T09:46:37.877Z&projectId=aaa -- API 名称: add_user_token -- 功能说明: - - 中文:新增用户token - - English:add user token - -- input body: - -``` json - -``` - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|name|string|是|无|token名|the token name| -|uid|string|是|无|用户id|the user id| -|expiredAt|datetime|否|无|过期时间|expiredAt| -|projectId|aaa|否|无|项目ID|projectId| - -- output: - -``` -{ - "code":0, - "data":{ - "createdAt":"2019-12-21T09:46:37.877Z", - "expiredAt":"2019-12-21T09:46:37.877Z", - "id":"abcd", - "name":"abcd" - }, - "message":"string", - "traceId":"string" -} - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | bool | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - - -- data 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|createdAt|time|创建时间|create time| -|expiredAt|time|过期时间,null标识永久 |expired time | -|name | string | token name|the name of token| -|id|string|token id |the id of token| - -### 用户token列表 - -- API:POST /auth/api/user/list/token/{uid} -- API 名称: list_user_token -- 功能说明: - - 中文:新增用户token - - English:add user token - -- input body: - -``` json - -``` - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|uid|string|是|无|用户id|the user id| - -- output: - -``` -{ - "code":0, - "data":[ - { - "createdAt":"2019-12-21T09:46:37.877Z", - "expiredAt":"2019-12-21T09:46:37.877Z", - "name":"token1" - }, - { - "createdAt":"2019-12-21T09:46:37.877Z", - "expiredAt":null, - "name":"token2" - } - ], - "message":"string", - "traceId":"string" -} -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | bool | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - - -- data 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|createdAt|time|创建时间|create time| -|expiredAt|time|过期时间 |expired time | -|name | string | token name|the name of token| -|id|string|token id |the id of token| - -### 删除用户token - -- API:DELETE /auth/api/user/token/{uid}/{name} -- API 名称: delete_user_token -- 功能说明: - - 中文:删除用户token - - English:delete user token - -- input body: - -``` json - -``` - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|uid|string|是|无|用户id|the user id| -|name|string|是|无|用户token|the user token| - -- output: - -``` -{ - "code":0, - "data":{ - "admin":true, - "locked":true, - "name":"string", - "pwd":"string", - "roles":[ - "string" - ], - "tokens":[ - { - "createdAt":"2019-12-21T09:46:37.877Z", - "expiredAt":"2019-12-21T09:46:37.877Z", - "name":"string" - } - ], - "uid":"string" - }, - "message":"string", - "traceId":"string" -} - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | bool | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - -### 校验用户token - -- API:POST /auth/api/user/login?uid=owen&token=blueking -- API 名称: check_user_token -- 功能说明: - - 中文:校验用户token - - English:check user token - -- input body: - -``` json - -``` - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|uid|string|是|无|用户id|the user id| -|token|string|是|无|用户token|the user token| - -- output: - -``` -{ - "code":0, - "message":null, - "data":true, - "traceId":"" -} - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|string|错误消息,或者用户token |the failure message,or bkrepo token | -|data | bool | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - -### 获取用户信息 - -- API:GET /auth/api/user/info -- API 名称: check_user_token -- 功能说明: - - 中文:校验用户token - - English:check user token - -- input body: - -``` json - -``` - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|uid|string|是|无|用户id|the user id| -|bkrepo_ticket|cookie|是|无|用户token|the user token| - -- output: - -``` -{ - "code":0, - "message":null, - "data":{ - "userId":"owenlxu2" - }, - "traceId":"" -} - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|string|错误消息,或者用户token |the failure message,or bkrepo token | -|data | bool | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - - -- data字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|userId | string | 用户id |the user Id| -|bkrepo_ticket|string|请求跟踪id|the bkrepo ticket| diff --git a/docs/storage/apidoc/auth/user.md b/docs/storage/apidoc/auth/user.md deleted file mode 100644 index 38ca7b76957..00000000000 --- a/docs/storage/apidoc/auth/user.md +++ /dev/null @@ -1,642 +0,0 @@ -## bkrepo 用户相关接口 - -### 创建用户 - -- API: POST /auth/api/user/create -- API 名称: create_user -- 功能说明: - - 中文:创建用户 - - English:create user - -- input body: - -``` json -{ - "userId":"public", - "name":"public", - "pwd":"blueking", - "group":true, - "asstUsers":["tt"] -} - -``` - - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|name|string|是|无|用户名|the name| -|pwd|string|是|无|用户密码|the user password| -|userId|string|是|无|用户id|the user id| -|asstUsers|string array|否|[]|关联用户|association user| -|group|boot |否|false|是否群组账号|is group user| -- output: - -``` -{ - "code":0, - "message":null, - "data":true, - "traceId":"" -} -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | bool | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - - -### 创建用户到项目管理员 - -- API: POST /auth/api/user/create/project -- API 名称: create_user_to_project -- 功能说明: - - 中文:创建用户 - - English:create user to project - -- input body: - -``` json -{ - "name":"string", - "pwd":"string", - "userId":"string", - "asstUsers":[ - "owen", - "necr" - ], - "group":true, - "projectId":"test" -} -``` - - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|name|string|是|无|用户名|the name| -|pwd|string|是|无|用户密码|the user password| -|userId|string|是|无|用户id|the user id| -|admin|bool|否|false|是否管理员|is admin| -|asstUsers|string array|否|[]|关联用户|association user| -|group|boot |否|false|是否群组账号|is group user| -|projectId|string|是|无|关联到的项目|the association project| - -- output: - -``` -{ -"code": 0, -"message": null, -"data": true, -"traceId": "" -} - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | bool | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - - -### 创建用户到仓库管理员 - -- API: POST /auth/api/user/create/repo -- API 名称: create_user_to_repo -- 功能说明: - - 中文:创建用户为仓库管理员 - - English:create user to repo - -- input body: - -``` json -{ - "name":"string", - "pwd":"string", - "userId":"string", - "asstUsers":[ - "owen", - "necr" - ], - "group":true, - "projectId":"test", - "repoName":"generic" -} -``` - - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|name|string|是|无|用户名|the name| -|pwd|string|是|无|用户密码|the user password| -|userId|string|是|无|用户id|the user id| -|asstUsers|string array|否|[]|关联用户|association user| -|group|boot |否|false|是否群组账号|is group user| -|projectId|string|是|无|关联到的项目|the association project| -|repoName|string|是|无|关联到的仓库|the association repo| - -- output: - -``` -{ -"code": 0, -"message": null, -"data": true, -"traceId": "" -} - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | bool | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - -### 用户列表 - -- API:GET /auth/api/user/list -- API 名称: list_user -- 功能说明: - - 中文:用户列表 - - English:list user - -- input body: - -``` json - -``` - -- input 字段说明 - -- output: - -``` -{ - "code":0, - "data":[ - { - "name":"owen", - "userId":"owen" - } - ], - "message":"", - "traceId":"" -} - - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | object | user data info |the info of user| -|traceId|string|请求跟踪id|the trace id| - - -- data 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|userId | string | 用户id |the user id| -|name|string|用户名|the department name| - - -### 用户详情 - -- API:GET /auth/api/user/detail/{uid} -- API 名称: user_detail -- 功能说明: - - 中文:用户详情 - - English:user detail - -- input body: - -``` json - - -``` - - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|uid|string|是|无|用户id|the user id| - - -- output: - -``` -{ - "code":0, - "data":{ - "admin":true, - "locked":true, - "name":"string", - "pwd":"string", - "roles":[ - "abcdegfffff" - ], - "tokens":[ - { - "createdAt":"2019-12-21T08:47:36.656Z", - "expiredAt":"2019-12-21T08:47:36.656Z", - "id":"ssss-deeedd" - } - ], - "uid":"owen" - }, - "message":"", - "traceId":"" -} - - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | object | user data info |the info of user| -|traceId|string|请求跟踪id|the trace id| - -- data 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|roles|string array|用户所属的角色列表 |the user role list| -|tokens|object array|用户创建的所有token |the tokens of user | - -- tokens 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|id|string |token id |the token id| -|createdAt|date time| token创建时间|create time | -|expiredAt|date time|token失效 |expire time | - -### 删除用户 - -- API:DELETE /auth/api/user/{uid} -- API 名称: delete_user -- 功能说明: - - 中文:删除用户 - - English:delete user - -- input body: - -``` json - -``` - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|uid|string|是|无|用户id|the user id| - -- output: - -``` -{ - "code":0, - "message":null, - "data":true, - "traceId":"" -} - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | bool | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - -### 更新用户信息 - -- API:PUT /auth/api/user/{uid} -- API 名称: update_user -- 功能说明: - - 中文:更新用户信息 - - English:update user - -- input body: - -``` json -{ - "admin":false, - "name":"string", - "pwd":"string", - "asstUsers":["owen"] -} -``` - - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|name|string|是|无|用户名|the name| -|pwd|string|是|无|用户密码|the user password| -|uid|string|是|无|用户id|the user id| -|admin|bool|否|false|是否管理员|is admin| -|asstUsers|string array|否|false|关联用户|asst users| - -- output: - -``` -{ - "code":0, - "message":null, - "data":true, - "traceId":"" -} - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | bool | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - - -### 删除用户所属角色 - -- API:DELETE /auth/api/user/role/{uid}/{rid} -- API 名称: delete_user_role -- 功能说明: - - 中文:删除用户所属角色 - - English:delete user role - -- input body: - -``` json - -``` - - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|uid|string|是|无|用户id|the user id| -|rid|string|是|无|角色主键ID|the role key id| - -- output: - -``` -{ - "code":0, - "data":{ - "admin":true, - "locked":true, - "name":"string", - "pwd":"string", - "roles":[ - "string" - ], - "tokens":[ - { - "createdAt":"2019-12-21T09:46:37.877Z", - "expiredAt":"2019-12-21T09:46:37.877Z", - "id":"string" - } - ], - "uid":"string" - }, - "message":"string", - "traceId":"string" -} - - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | bool | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - -### 新增用户所属角色 - -- API:POST /auth/api/user/role/{uid}/{rid} -- API 名称: add_user_role -- 功能说明: - - 中文:新增用户所属角色 - - English:add user role - -- input body: - -``` json - -``` - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|uid|string|是|无|用户id|the user id| -|rid|string|是|无|角色主键ID|the role key id| - -- output: - -``` -{ - "code":0, - "data":{ - "admin":true, - "locked":true, - "name":"string", - "pwd":"string", - "roles":[ - "string" - ], - "tokens":[ - { - "createdAt":"2019-12-21T09:46:37.877Z", - "expiredAt":"2019-12-21T09:46:37.877Z", - "id":"string" - } - ], - "uid":"string" - }, - "message":"string", - "traceId":"string" -} - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | bool | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - - - -### 批量新增用户所属角色 - -- API:PATCH /auth/api/user/role/add/{rid} -- API 名称: patch_create_user_role -- 功能说明: - - 中文:批量新增用户所属角色 - - English:add user role patch - -- input body: - -``` json -[ - "owen", - "tt" -] -``` - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|uid|string array|是|无|用户id数组|the user id array| -|rid|string|是|无|角色主键ID|the role token| - -- output: - -``` -{ - "code":0, - "message":null, - "data":true, - "traceId":"" -} - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | bool | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - -### 批量删除用户所属角色 - -- API:PATCH /auth/api/user/role/add/{rid} -- API 名称: patch_delete_user_role -- 功能说明: - - 中文:批量删除用户所属角色 - - English:delete user role patch - -- input body: - -``` json -[ - "owen", - "tt" -] -``` - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|uid|string array|是|无|用户id数组|the user id array| -|rid|string|是|无|角色主键ID|the role token| - -- output: - -``` -{ -"code": 0, -"message": null, -"data": true, -"traceId": "" -} - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | bool | result data |the data for response| -|traceId|string|请求跟踪id|the trace id| - -### 判断用户是否为项目管理员 - -- API:GET /auth/api/user/admin/{projectId} -- API 名称: is_project_admin -- 功能说明: - - 中文:查询用户是否为项目管理员 - - English:query user is project admin or not - -- input body: - -``` json -``` - -- input 字段说明 - -| 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | -|-----------|--------|------|-----|------|-------------| -| projectId | string | 是 | 无 | 项目id | project id | - -- output: - -``` -{ -"code": 0, -"message": null, -"data": true, -"traceId": "" -} - -``` - -- output 字段说明 - -| 字段 | 类型 | 说明 | Description | -|---------|----------------|---------------------------|------------------------------------------------| -| code | bool | 错误编码。 0表示success,>0表示失败错误 | 0:success, other: failure | -| message | result message | 错误消息 | the failure message | -| data | bool | 是否为项目管理员 | true if user is project admin, false otherwise | -| traceId | string | 请求跟踪id | the trace id | \ No newline at end of file diff --git a/docs/storage/apidoc/common/common.md b/docs/storage/apidoc/common/common.md deleted file mode 100644 index 337c9fe7076..00000000000 --- a/docs/storage/apidoc/common/common.md +++ /dev/null @@ -1,93 +0,0 @@ -# 通用接口协议 - -各个依赖源有单独的服务接口协议,除了这类接口,系统其余接口使用统一的通用接口协议。 - -此部分对系统的通用接口协议作介绍。 - -## 公共请求头 - -### 对接个人账号(通用) -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|Authorization|string|是|无|Basic Auth认证头,Basic base64(username:password)|Basic Auth header| - -### 对接合作系统,需要先申请bkrepo appId -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|Authorization|string|是|无|自定义Auth认证头,Platform base64(accessKey:secretKey)|Platform Auth header| -|X-BKREPO-UID|string|是|无|实际操作用户,需要有对应资源的操作权限|operate user| - -## 统一响应格式 - -- 响应体格式 - - `application/json` - -- 响应体内容 - - ```json - { - "code" : 0, - "message" : null, - "data" : [object], - "traceId" : null - } - ``` - -- 响应字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |code|bool|错误编码。 0表示success,>0表示失败错误|0:success, other: failure| - |message|string|错误提示消息,请求成功此字段为null|the failure message| - |data|object|响应数据,允许为null|response data| - |traceId|string|请求跟踪id,允许为null|trace id| - - **TIPS: 无特殊说明,后文的接口响应体说明只介绍data字段** - -## 统一分页接口响应格式 - -|字段|类型|说明|Description| -|---|---|---|---| -|totalRecords|long|节点信息|total count| -|pageNumber|int|当前页|page number| -|pageSize|int|每页记录数|page size| -|totalPages|long|总页数|total pages| -|records|list|数据记录列表|record list| - -## 统一时间响应格式 - -接口返回的时间,使用`ISO_DATETIME`格式,如:`2011-12-03T10:15:30` - -## 通用概念 - -|名称|解释| -|---|---| -|project/projectId|项目id,全局唯一| -|repo/repoName|仓库名称,项目内唯一| -|fullPath|节点完整路径| -|path|节点目录,在restful格式的url中也可以表示fullPath,后台会自动处理| - -## 统一错误码 - -|错误码|错误原因| -|---|---| -|250102|系统错误| -|250103|请求参数缺失| -|250104|请求参数非法| -|250105|请求参数无效| -|250106|请求内容无效| -|250107|请求资源已经存在| -|250108|请求资源不存在| -|250109|请求资源过期| -|250110|不支持的操作| -|250111|访问被拒绝| -|250112|认证失败| -|250113|内部依赖服务被熔断| -|250114|内部依赖服务调用异常| -|250115|服务认证失败| -|250116|请求头缺失| -|250117|不支持的Media Type| -|250118|请求range格式无效| -|250119|修改密码失败| -|...|待补充| diff --git a/docs/storage/apidoc/common/search.md b/docs/storage/apidoc/common/search.md deleted file mode 100644 index 5721b20dbf1..00000000000 --- a/docs/storage/apidoc/common/search.md +++ /dev/null @@ -1,125 +0,0 @@ -# 自定义搜索协议 - -> 自定义搜索协议用于数据搜索接口,支持前端自定义查询条件、筛选字段、排序规则、分页参数等信息。 - -[toc] - -## 请求体格式 - -```json -{ - "select": ["xxx", "yyy", "xxx"], - "page": { - "pageNumber": 0, - "pageSize": 20 - }, - "sort": { - "properties": ["name"], - "direction": "ASC" - }, - "rule": { - "rules": [ - { - "field": "projectId", - "value": "test", - "operation": "EQ" - }, - { - "field": "repoName", - "value": ["generic-local1", "generic-local2"], - "operation": "IN" - } - ], - "relation": "AND" - } -} -``` - -### 请求字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|select|list|否|无,代表查询所有字段|筛选字段列表。支持的字段列表请参照对应数据的列表接口响应字段。|select fields list| -|page|PageLimit|否|pageNumber=1, pageSize=20|分页参数|page limit| -|sort|Sort|否|无|排序规则|sort rule| -|rule|Rule|是|无|自定义查询规则|custom query rule| - -### PageLimit参数说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|pageNumber|int|否|1|当前页(第1页开始)|page number| -|pageSize|int|否|20|每页数量|page size| - -### Sort参数说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|properties|[string]|是|无|排序字段|sort properties| -|direction|string|否|ASC|排序方向。支持ASC升序和DESC降序|sort direction| - -### Rule参数说明 - -> Rule包含两种格式,一种用于表示嵌套规则NestedRule,另一种用于表示条件规则QueryRule - -- **嵌套规则NestedRule** - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|rules|[Rule]|是|无|规则列表,可以任意嵌套NestedRule和QueryRule|rule list| -|relation|string|否|AND|规则列表rules的关系。支持AND、OR、NOR|rule relation| - -- **条件规则QueryRule** - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|field|string|是|无|查询字段|filed| -|value|any|否|无|查询值。数据类型和查询操作类型相关|value| -|operation|enum|否|EQ|查询操作类型。枚举类型见下文|operation| - - -### OperationType查询操作类型 - -|枚举值|对应查询值类型|Description| -|---|---|---| -|EQ|string/boolean/number/date|等于| -|NE|number/date|不等于| -|LTE|number/date|小于或者等于| -|LT|number/date|小于| -|GTE|number/date|大于或者等于| -|GT|number/date|大于| -|BEFORE|date|在某个时间之间,不包含等于| -|AFTER|date|在某个时间之后,不包含等于| -|IN|list|包含于| -|NIN|list|不包含于| -|PREFIX|string|以xxx为前缀| -|SUFFIX|string|以xxx为后缀| -|MATCH|string|通配符匹配,\*表示匹配任意字符。如\*test\*表示包含test的字符串| -|NULL|null|匹配查询字段为空,filed == null| -|NOT_NULL|null|匹配查询字段不为空,filed != null| - -## 响应体格式 - -响应体参考[分页接口响应格式](../common/common.md?id=统一分页接口响应格式) - -``` json -{ - "code": 0, - "message": null, - "data": { - "pageNumber": 0, - "pageSize": 1, - "totalRecords": 18, - "totalPages": 18, - "records": [ - { - "xxx": "", - "yyy": "" - } - ] - }, - "traceId": null -} -``` - -`records`字段根据`select`筛选字段条件决定 \ No newline at end of file diff --git a/docs/storage/apidoc/generic/block.md b/docs/storage/apidoc/generic/block.md deleted file mode 100644 index dcb472fc54b..00000000000 --- a/docs/storage/apidoc/generic/block.md +++ /dev/null @@ -1,224 +0,0 @@ -# Generic通用制品仓库分块文件操作 - -[toc] - -## 初始化分块上传 - -- API: POST /generic/block/{project}/{repo}/{path} -- API 名称: start_block_upload -- 功能说明: - - 中文:初始化分块上传 - - English:start block upload - -- 请求体 -此接口请求体为空 - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |project|string|是|无|项目名称|project name| - |repo|string|是|无|仓库名称|repo name| - |path|string|是|无|完整路径|full path| - -- 请求头 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |X-BKREPO-MD5|string|否|无|文件md5|file md5| - |X-BKREPO-OVERWRITE|boolean|否|false|是否覆盖已存在文件|overwrite exist file| - |X-BKREPO-EXPIRES|long|否|0|过期时间,单位天(0代表永久保存)|file expired days| - -- 响应体 - -``` json -{ - "code" : 0, - "message" : null, - "data" : { - "uploadId" : "8be31384f82a45b0aafb6c6add29e94f", - "expireSeconds" : 43200 - }, - "traceId" : null -} -``` - -- data字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |uploadId|string|分块上传id|block upload id| - |expireSeconds|string|上传有效期(秒)|expire time(seconds)| - -## 上传分块文件 - -- API: PUT /{project}/{repo}/{path} -- API 名称: block_upload -- 功能说明: - - 中文:分块上传通用制品文件 - - English:upload generic artifact file block - -- 请求体 -[文件流] - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |project|string|是|无|项目名称|project name| - |repo|string|是|无|仓库名称|repo name| - |path|string|是|无|完整路径|full path| - -- 请求头 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |X-BKREPO-UPLOAD-ID|string|否|无|分块上传id|block upload id| - |X-BKREPO-SEQUENCE|int|否|无|分块序号(从1开始)|block sequence(start from 1)| - |X-BKREPO-SHA256|string|否|无|文件sha256|file sha256| - |X-BKREPO-MD5|string|否|无|文件md5|file md5| - -- 响应体 - - ``` json - { - "code" : 0, - "message" : null, - "data" : null, - "traceId" : null - } - ``` - -## 完成分块上传 - -- API: PUT /generic/block/{project}/{repo}/{path} -- API 名称: complete_block_upload -- 功能说明: - - 中文:完成化分块上传 - - English:complete block upload - -- 请求体 -此接口请求体为空 - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |project|string|是|无|项目名称|project name| - |repo|string|是|无|仓库名称|repo name| - |path|string|是|无|完整路径|full path| - -- 请求头 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |X-BKREPO-UPLOAD-ID|string|是|无|分块上传ID|block upload id| - -- 响应体 - - ``` json - { - "code" : 0, - "message" : null, - "data" : null, - "traceId" : "" - } - ``` - -## 终止(取消)分块上传 - -- API: DELETE /generic/block/{project}/{repo}/{path} -- API 名称: abort_block_upload -- 功能说明: - - 中文:终止(取消)分块上传 - - English:abort block upload - -- 请求体 -此接口请求体为空 - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |project|string|是|无|项目名称|project name| - |repo|string|是|无|仓库名称|repo name| - |path|string|是|无|完整路径|full path| - -- 请求头 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |X-BKREPO-UPLOAD-ID|string|是|无|分块上传ID|block upload id| - -- 响应体 - - ``` json - { - "code" : 0, - "message" : null, - "data" : null, - "traceId" : null - } - ``` - -## 查询已上传的分块列表 - -- API: GET /generic/block/{project}/{repo}/{path} -- API 名称: list_upload_block -- 功能说明: - - 中文:查询已上传的分块列表 - - English:list upload block - -- 请求体 - 此接口请求体为空 - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |project|string|是|无|项目名称|project name| - |repo|string|是|无|仓库名称|repo name| - |path|string|是|无|完整路径|full path| - -- 请求头 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |Authorization|string|否|无|Basic Auth认证头,Basic base64(username:password)|Basic Auth header| - |X-BKREPO-UPLOAD-ID|string|是|无|分块上传ID|block upload id| - -- 响应体 - - ``` json - { - "code" : 0, - "message" : null, - "data" : [ { - "size" : 10240, - "sha256" : "d17f25ecfbcc7857f7bebea469308be0b2580943e96d13a3ad98a13675c4bfc2", - "sequence" : 1 - }, { - "size" : 10240, - "sha256" : "cc399d73903f06ee694032ab0538f05634ff7e1ce5e8e50ac330a871484f34cf", - "sequence" : 2 - } ], - "traceId" : null - } - ``` - -- 响应字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |code|bool|错误编码。 0表示success,>0表示失败错误|0:success, other: failure| - |message|string|错误消息|the failure message| - |data|list|分块列表|block list| - |traceId|string|请求跟踪id|trace id| - -- 分块信息字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |size|long|分块大小|block size| - |sha256|string|分块sha256|block sha256 checksum| - |sequence|int|分块序号|block sequence| \ No newline at end of file diff --git a/docs/storage/apidoc/generic/simple.md b/docs/storage/apidoc/generic/simple.md deleted file mode 100644 index 887f9bf9ae3..00000000000 --- a/docs/storage/apidoc/generic/simple.md +++ /dev/null @@ -1,221 +0,0 @@ -# Generic通用制品仓库简单文件操作 - -[toc] - -## 上传文件 - -- API: PUT /generic/{project}/{repo}/{path} -- API 名称: upload -- 功能说明: - - 中文:上传通用制品文件 - - English:upload generic artifact file - -- 请求体 -[文件流] - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |project|string|是|无|项目名称|project name| - |repo|string|是|无|仓库名称|repo name| - |path|string|是|无|完整路径|full path| - -- 请求头 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |X-BKREPO-SHA256|string|否|无|文件sha256|file sha256| - |X-BKREPO-MD5|string|否|无|文件md5|file md5| - |X-BKREPO-OVERWRITE|boolean|否|false|是否覆盖已存在文件|overwrite exist file| - |X-BKREPO-EXPIRES|long|否|0|过期时间,单位天(0代表永久保存)|file expired days| - |X-BKREPO-META-{key}|string|否|无|文件元数据,{key}表示元数据key,可以添加多个。key大小写不敏感,按小写存储|file metadata| - |X-BKREPO-META|string|否|无|文件元数据,格式为base64(key1=value1&key2=value2)。key大小写敏感。当`X-BKREPO-META-{key}`不能满足需求时可用此字段代替|file metadata| - - -- 响应体 - - ``` json - { - "code" : 0, - "message" : null, - "data" : { - "createdBy" : "admin", - "createdDate" : "2020-07-27T16:02:31.394", - "lastModifiedBy" : "admin", - "lastModifiedDate" : "2020-07-27T16:02:31.394", - "folder" : false, - "path" : "/", - "name" : "test.json", - "fullPath" : "/test.json", - "size" : 34, - "sha256" : "6a7983009447ecc725d2bb73a60b55d0ef5886884df0ffe3199f84b6df919895", - "md5" : "2947b3932900d4534175d73964ec22ef", - "metadata": {}, - "projectId" : "test", - "repoName" : "generic-local" - }, - "traceId" : null - } - ``` - -- data字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |createdBy|string|创建者|create user| - |createdDate|string|创建时间|create time| - |lastModifiedBy|string|上次修改者|last modify user| - |lastModifiedDate|string|上次修改时间|last modify time| - |folder|bool|是否为文件夹|is folder| - |path|string|节点目录|node path| - |name|string|节点名称|node name| - |fullPath|string|节点完整路径|node full path| - |size|long|文件大小|file size| - |sha256|string|文件sha256|file sha256| - |md5|string|文件md5|file md5 checksum| - |metadata|object|节点元数据|node metadata| - |projectId|string|节点所属项目|node project id| - |repoName|string|节点所属仓库|node repository name| - -## 下载文件 - -- API: GET /generic/{project}/{repo}/{path}?download=true -- API 名称: download -- 功能说明: - - 中文:下载通用制品文件 - - English:download generic file - -- 请求体 - 此接口请求体为空 - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |project|string|是|无|项目名称|project name| - |repo|string|是|无|仓库名称|repo name| - |path|string|是|无|完整路径|full path| - |download|boolean|否|false|是否为下载请求。如果为true,响应体会添加Content-Disposition,强制浏览器进行下载;不加此参数,浏览器将根据情况展示文件预览 |is download request| - -- 请求头 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |Range|string|否|无|RFC 2616 中定义的字节范围,范围值必须使用 bytes=first-last 格式且仅支持单一范围,不支持多重范围。first 和 last 都是基于0开始的偏移量。例如 bytes=0-9,表示下载对象的开头10个字节的数据;bytes=5-9,表示下载对象的第6到第10个字节。此时返回 HTTP 状态码206(Partial Content)及 Content-Range 响应头部。如果 first 超过对象的大小,则返回 HTTP 状态码416(Requested Range Not Satisfiable)错误。如果不指定,则表示下载整个对象|bytes range| - -- 响应头 - - |字段|类型|说明|Description| - |---|---|---|---| - |Accept-Ranges|string|RFC 2616 中定义的服务器接收Range范围|RFC 2616 Accept-Ranges| - |Cache-Control|string|RFC 2616 中定义的缓存指令|RFC 2616 Cache-Control| - |Connection|string|RFC 2616 中定义,表明响应完成后是否会关闭网络连接。枚举值:keep-alive,close。|RFC 2616 Connection| - |Content-Disposition|string|RFC 2616 中定义的文件名称,当download=true才会添加此参数|RFC 2616 Content-Disposition| - |Content-Length|long|RFC 2616 中定义的 HTTP 响应内容长度(字节)|RFC 2616 Content Length| - |Content-Range|string|RFC 2616 中定义的返回内容的字节范围,仅当请求中指定了 Range 请求头部时才会返回该头部|RFC 2616 Content-Range| - |Content-Type|string|RFC 2616 中定义的 HTTP 响应内容类型(MIME)|RFC 2616 Content Length| - |Date|string|RFC 1123 中定义的 GMT 格式服务端响应时间,例如Mon, 27 Jul 2020 08:51:59 GMT|RFC 1123 Content Length| - |Etag|string|ETag 全称为 Entity Tag,是文件被创建时标识对象内容的信息标签,可用于检查对象的内容是否发生变化,通用制品文件会返回文件的sha256值|ETag, file sha256 checksum| - |Last-Modified|string|文件的最近一次上传的时间,例如Mon, 27 Jul 2020 08:51:58 GMT|file last modified time| - -- 响应体 - [文件流] - -## 获取文件头部信息 - -- API: HEAD /generic/{project}/{repo}/{path} -- API 名称: head -- 功能说明: - - 中文:获取通用制品文件头部信息 - - English:get generic file head info - -- 请求体 - 此接口请求体为空 - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |project|string|是|无|项目名称|project name| - |repo|string|是|无|仓库名称|repo name| - |path|string|是|无|完整路径|full path| - -- 请求头 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |Range|string|否|无|RFC 2616 中定义的字节范围,范围值必须使用 bytes=first-last 格式且仅支持单一范围,不支持多重范围。first 和 last 都是基于0开始的偏移量。例如 bytes=0-9,表示下载对象的开头10个字节的数据;bytes=5-9,表示下载对象的第6到第10个字节。此时返回 HTTP 状态码206(Partial Content)及 Content-Range 响应头部。如果 first 超过对象的大小,则返回 HTTP 状态码416(Requested Range Not Satisfiable)错误。如果不指定,则表示下载整个对象|bytes range| - -- 响应头 - - |字段|类型|说明|Description| - |---|---|---|---| - |Accept-Ranges|string|RFC 2616 中定义的服务器接收Range范围|RFC 2616 Accept-Ranges| - |Cache-Control|string|RFC 2616 中定义的缓存指令|RFC 2616 Cache-Control| - |Connection|string|RFC 2616 中定义,表明响应完成后是否会关闭网络连接。枚举值:keep-alive,close。|RFC 2616 Connection| - |Content-Disposition|string|RFC 2616 中定义的文件名称|RFC 2616 Content-Disposition| - |Content-Length|long|RFC 2616 中定义的 HTTP 响应内容长度(字节)|RFC 2616 Content Length| - |Content-Range|string|RFC 2616 中定义的返回内容的字节范围,仅当请求中指定了 Range 请求头部时才会返回该头部|RFC 2616 Content-Range| - |Content-Type|string|RFC 2616 中定义的 HTTP 响应内容类型(MIME)|RFC 2616 Content Length| - |Date|string|RFC 1123 中定义的 GMT 格式服务端响应时间,例如Mon, 27 Jul 2020 08:51:59 GMT|RFC 1123 Content Length| - |Etag|string|ETag 全称为 Entity Tag,是文件被创建时标识对象内容的信息标签,可用于检查对象的内容是否发生变化,通用制品文件会返回文件的sha256值|ETag, file sha256 checksum| - |Last-Modified|string|文件的最近一次上传的时间,例如Mon, 27 Jul 2020 08:51:58 GMT|file last modified time| - -- 响应体 - 此接口响应体为空 - -## 删除文件 - -- API: DELETE /generic/{project}/{repo}/{path} -- API 名称: delete -- 功能说明: - - 中文:删除通用制品文件 - - English:delete generic file - -- 请求体 - 此接口请求体为空 - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |project|string|是|无|项目名称|project name| - |repo|string|是|无|仓库名称|repo name| - |path|string|是|无|完整路径|full path| - -- 响应体 - - ``` json - { - "code" : 0, - "message" : null, - "data" : null, - "traceId" : null - } - ``` - -## 批量下载 -- API : GET /generic/batch/{project}/{repo} -- API名称: batch download -- 功能说明: - - 中文:批量下载通用制品文件 - - English:batch download generic file -- 请求body -``` json -{ - "paths": ["/dir/file1", "/file2"] -} -``` - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |project|string|是|无|项目名称|project name| - |repo|string|是|无|仓库名称|repo name| - |paths|list|是|无|文件完整路径,支持添加多个文件路径|full path list| - - -- 响应体 - [文件流] \ No newline at end of file diff --git a/docs/storage/apidoc/generic/temporary-access.md b/docs/storage/apidoc/generic/temporary-access.md deleted file mode 100644 index 5887027d4c7..00000000000 --- a/docs/storage/apidoc/generic/temporary-access.md +++ /dev/null @@ -1,169 +0,0 @@ -# Generic通用制品仓库临时访问凭证接口 - -[toc] - -## 创建临时访问token - -- API: POST /generic/temporary/token/create -- API 名称: create_temporary_access_token -- 功能说明: - - 中文:创建临时访问token - - English:create temporary access token - -- 请求体 - - ``` json - { - "projectId": "test", - "repoName": "generic-local", - "fullPathSet": ["/path/file"], - "authorizedUserSet": ["user1", "user2"], - "authorizedIpSet": ["127.0.0.1", "192.168.191.1"], - "expireSeconds": 3600, - "permits": 1, - "type": "DOWNLOAD" - } - ``` - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |repoName|string|是|无|仓库名称|repo name| - |fullPathSet|list|是|无|授权路径列表,支持批量创建|full path set| - |authorizedUserSet|list|否|无|授权访问用户,不传则任意用户可访问|authorized user set| - |authorizedIpSet|list|否|无|授权访问ip,不传则任意ip可访问|authorized ip set| - |expireSeconds|long|否|3600*24|token有效时间,单位秒,小于等于0则永久有效|expire seconds| - |permits|int|否|null|允许访问次数,null表示无限制|access permits| - |type|string|是|无|token类型。UPLOAD: 运行上传, DOWNLOAD: 允许下载, ALL: 同时运行上传和下载|token type| - -- 响应体 - -``` json -{ - "code" : 0, - "message" : null, - "data" : [{ - "projectId": "test", - "repoName": "generic-local", - "fullPath": "/path1", - "token": "xxx", - "authorizedUserSet": ["user1", "user2"], - "authorizedIpSet": ["127.0.0.1", "192.168.191.1"], - "expireDate": "2020-02-02T02:02:02.002", - "permits": 1, - "type": "DOWNLOAD" - }], - "traceId" : null -} -``` - -- data字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |projectId|string|项目名称|project name| - |repoName|string|仓库名称|repo name| - |fullPath|string|完整路径|node full path| - |token|string|临时访问token|temporary access token| - |authorizedUserSet|list|授权访问用户|authorized user set| - |authorizedIpSet|list|授权访问ip|authorized ip set| - |expireDate|string|过期时间,null表示永久token|expire date| - |permits|int|允许访问次数,null表示无限制|access permits| - |type|string|token类型|token type| - -## 创建临时访问url - -- API: POST /generic/temporary/url/create -- API 名称: create_temporary_access_url -- 功能说明: - - 中文:创建临时访问url - - English:create temporary access url - -- 请求体 - - ``` json - { - "projectId": "test", - "repoName": "generic-local", - "fullPathSet": ["/path/file"], - "authorizedUserSet": ["user1", "user2"], - "authorizedIpSet": ["127.0.0.1", "192.168.191.1"], - "expireSeconds": 3600, - "permits": 1, - "type": "DOWNLOAD", - "host": "http://custom-host.com/", - "needsNotify": false - } - ``` - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |repoName|string|是|无|仓库名称|repo name| - |fullPathSet|list|是|无|授权路径列表,支持批量创建|full path set| - |authorizedUserSet|list|否|无|授权访问用户,不传则任意用户可访问|authorized user set| - |authorizedIpSet|list|否|无|授权访问ip,不传则任意ip可访问|authorized ip set| - |expireSeconds|long|否|3600*24|token有效时间,单位秒,小于等于0则永久有效|expire seconds| - |permits|int|否|null|允许访问次数,null表示无限制|access permits| - |type|string|是|无|token类型。UPLOAD:允许上传, DOWNLOAD: 允许下载, ALL: 同时允许上传和下载|token type| - |host|string|否|无|自定义分享链接host,不指定则使用系统默认host|custom url host| - |needsNotify|boolean|否|false|是否通知授权访问用户|notify authorized users| - -- 响应体 - -``` json -{ - "code" : 0, - "message" : null, - "data" : [{ - "projectId": "test", - "repoName": "generic-local", - "fullPath": "/path/file", - "url": "http://bkrepo.example.com/generic/temporary/test/generic-local/path/file?token=xxx", - "authorizedUserSet": ["user1", "user2"], - "authorizedIpSet": ["127.0.0.1", "192.168.191.1"], - "expireDate": "2020-02-02T02:02:02.002", - "permits": 1, - "type": "DOWNLOAD" - }], - "traceId" : null -} -``` - -- data字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |projectId|string|项目名称|project name| - |repoName|string|仓库名称|repo name| - |fullPath|string|完整路径|node full path| - |url|string|临时访问url|temporary access url| - |authorizedUserSet|list|授权访问用户|authorized user set| - |authorizedIpSet|list|授权访问ip|authorized ip set| - |expireDate|string|过期时间,null表示永久token|expire date| - |permits|int|允许访问次数,null表示无限制|access permits| - |type|string|token类型|token type| - -## 临时token文件下载接口 - -- API: GET /generic/temporary/download/{project}/{repo}/{path}?token=xxx -- API 名称: temporary download -- 功能说明: - - 中文:临时token文件下载 - - English:temporary download -- 接口说明 - 除`token`参数外,其余参数和协议和[generic下载文件](./simple.md)一致 - -## 临时token文件上传接口 - -- API: PUT /generic/temporary/upload/{project}/{repo}/{path}?token=xxx -- API 名称: temporary upload -- 功能说明: - - 中文:临时token文件上传 - - English:temporary upload -- 接口说明 - 除`token`参数外,其余参数和协议和[generic上传文件](./simple.md)一致 diff --git a/docs/storage/apidoc/node/metadata.md b/docs/storage/apidoc/node/metadata.md deleted file mode 100644 index b984c44b4e1..00000000000 --- a/docs/storage/apidoc/node/metadata.md +++ /dev/null @@ -1,110 +0,0 @@ -# Metadata元数据接口 - -[toc] - -## 查询元数据 - -- API: GET /repository/api/metadata/{projectId}/{repoName}/{fullPath} -- API 名称: query_metadata -- 功能说明: - - 中文:查询元数据信息 - - English:query metadata info -- 请求体 - 此接口请求体为空 - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |repoName|string|是|无|仓库名称|repo name| - |fullPath|string|是|无|完整路径|full path| - -- 响应体 - - ``` json - { - "code": 0, - "message": null, - "data": { - "key1": "value1", - "key2": "value2" - }, - "traceId": null - } - ``` - -- data字段说明 - - 键值对,key为元数据名称,value为元数据值 - -### 保存(更新)元数据 - -- API: POST /repository/api/metadata/{projectId}/{repoName}/{fullPath} -- API 名称: save_metadata -- 功能说明: - - 中文:保存(更新)元数据信息,元数据不存在则保存,存在则更新 - - English:save metadata info -- 请求体 - - ```json - { - "key1": "value1", - "key2": "value2" - } - ``` - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |repoName|string|是|无|仓库名称|repo name| - |fullPath|string|是|无|完整路径|full path| - |key|string|否|无|元数据键值对|metadata key-value| - -- 响应体 - - ``` json - { - "code": 0, - "message": null, - "data": null, - "traceId": null - } - ``` - -### 删除元数据 - -- API: DELETE /repository/api/metadata/{projectId}/{repoName}/{fullPath} -- API 名称: delete_metadata -- 功能说明: - - 中文:根据提供的key列表删除元数据 - - English:delete metadata info -- 请求体 - - ```json - { - "keyList": ["key1", "key2"] - } - ``` - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |repoName|string|是|无|仓库名称|repo name| - |fullPath|string|是|无|完整路径|full path| - |keyList|[string]|是|无|待删除的元数据key列表|metadata key list| - -- 响应体 - - ``` json - { - "code": 0, - "message": null, - "data": null, - "traceId": null - } - ``` diff --git a/docs/storage/apidoc/node/node.md b/docs/storage/apidoc/node/node.md deleted file mode 100644 index e029bd474f8..00000000000 --- a/docs/storage/apidoc/node/node.md +++ /dev/null @@ -1,661 +0,0 @@ -# Node节点操作接口 - -[toc] - -## 查询节点详情 - -- API: GET /repository/api/node/detail/{projectId}/{repoName}/{fullPath} -- API 名称: query_node_detail -- 功能说明: - - 中文:查询节点详情 - - English:query node detail -- 请求体 - 此接口请求体为空 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |repoName|string|是|无|仓库名称|repo name| - |fullPath|string|是|无|完整路径|full path| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": { - "projectId" : "test", - "repoName" : "generic-local", - "path" : "/", - "name" : "test.json", - "fullPath" : "/test.json", - "folder" : false, - "size" : 34, - "sha256" : "6a7983009447ecc725d2bb73a60b55d0ef5886884df0ffe3199f84b6df919895", - "md5" : "2947b3932900d4534175d73964ec22ef", - "stageTag": "@release", - "metadata": { - "key": "value" - }, - "createdBy" : "admin", - "createdDate" : "2020-07-27T16:02:31.394", - "lastModifiedBy" : "admin", - "lastModifiedDate" : "2020-07-27T16:02:31.394" - }, - "traceId": null - } - ``` - -- data字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |projectId|string|节点所属项目|node project id| - |repoName|string|节点所属仓库|node repository name| - |path|string|节点目录|node path| - |name|string|节点名称|node name| - |fullPath|string|节点完整路径|node full path| - |folder|bool|是否为文件夹|is folder| - |size|long|节点大小|file size| - |sha256|string|节点sha256|file sha256| - |md5|string|节点md5|file md5 checksum| - |stageTag|string|晋级状态标签|stage status tag| - |metadata|object|节点元数据,key-value键值对|node metadata| - |createdBy|string|创建者|create user| - |createdDate|string|创建时间|create time| - |lastModifiedBy|string|上次修改者|last modify user| - |lastModifiedDate|string|上次修改时间|last modify time| - -## 分页查询节点 - -- API: GET /repository/api/node/page/{projectId}/{repoName}/{fullPath}?pageNumber=0&pageSize=20&includeFolder=true&includeMetadata=true&deep=false&sort=false&sortProperty=xx&direction=ASC&sortProperty=xx&direction=DESC -- API 名称: list_node_page -- 功能说明: - - 中文:分页查询节点,返回的结果列表中目录在前,文件在后,并按照文件名称排序, 同时支持自定义排序 - - English:list node page -- 请求体 - 此接口请求体为空 - -- 请求字段说明 - - |字段|类型|是否必须|默认值| 说明 |Description| - |---|---|---|---------------------------------------------------------------|---|---| - |projectId|string|是|无| 项目名称 |project name| - |repoName|string|是|无| 仓库名称 |repo name| - |fullPath|string|是|无| 完整路径 |full path| - |pageNumber|int|否|1| 当前页 |current page| - |pageSize|int|否|20| 分页大小 |page size| - |includeFolder|boolean|否|true| 是否包含目录 |include folder| - |includeMetadata|boolean|否|false| 是否包含元数据 |include metadata| - |deep|boolean|否|false| 是否查询子目录节点 |deep query| - |sort|boolean|否|false| 是否排序输出结果 |sort result| - |sortProperty|string|否|false| 自定义排序字段,可添加多个。自定义排序字段优先级高于sort=true时的排序规则。多个自定义排序字段优先级与参数顺序相同 |sort property| - |direction|string|否|false| 自定义排序方向,可添加多个,与排序字段一一对应 |sort direction| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": { - "pageNumber": 1, - "pageSize": 20, - "totalRecords": 18, - "totalPages": 18, - "records": [ - { - "projectId" : "test", - "repoName" : "generic-local", - "path" : "/", - "name" : "test.json", - "fullPath" : "/test.json", - "folder" : false, - "size" : 34, - "sha256" : "6a7983009447ecc725d2bb73a60b55d0ef5886884df0ffe3199f84b6df919895", - "md5" : "2947b3932900d4534175d73964ec22ef", - "stageTag": "@release", - "metadata": {}, - "createdBy" : "admin", - "createdDate" : "2020-07-27T16:02:31.394", - "lastModifiedBy" : "admin", - "lastModifiedDate" : "2020-07-27T16:02:31.394" - } - ] - }, - "traceId": null - } - ``` - -- record字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |projectId|string|节点所属项目|node project id| - |repoName|string|节点所属仓库|node repository name| - |path|string|节点目录|node path| - |name|string|节点名称|node name| - |fullPath|string|节点完整路径|node full path| - |folder|bool|是否为文件夹|is folder| - |size|long|节点大小|file size| - |sha256|string|节点sha256|file sha256| - |md5|string|节点md5|file md5 checksum| - |stageTag|string|晋级状态标签,includeMetadata=false将返回空|stage status tag| - |metadata|object|节点元数据,key-value键值对,includeMetadata=false将返回空|node metadata| - |createdBy|string|创建者|create user| - |createdDate|string|创建时间|create time| - |lastModifiedBy|string|上次修改者|last modify user| - |lastModifiedDate|string|上次修改时间|last modify time| - -## 创建目录 - -- API: POST /repository/api/node/mkdir/{projectId}/{repoName}/{path} -- API 名称: mkdir -- 功能说明: - - 中文:创建目录节点 - - English:create directory node -- 请求体 - 此接口请求体为空 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |repoName|string|是|无|仓库名称|repo name| - |path|string|是|无|完整路径|full path| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": null - } - ``` - -## 删除节点 - -- API: DELETE /repository/api/node/delete/{projectId}/{repoName}/{fullPath} -- API 名称: delete_node -- 功能说明: - - 中文:删除节点,同时支持删除目录和文件节点 - - English:delete node -- 请求体 - 此接口请求体为空 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |repoName|string|是|无|仓库名称|repo name| - |fullPath|string|是|无|完整路径|full path| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": null - } - ``` - -## 更新节点 - -- API: POST /repository/api/node/update/{projectId}/{repoName}/{fullPath} -- API 名称: update_node -- 功能说明: - - 中文:更新节点信息,目前支持修改文件过期时间 - - English:update node info -- 请求体 - - ```json - { - "expires": 0 - } - ``` - -- 请求字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|projectId|string|是|无|项目名称|project name| -|repoName|string|是|无|仓库名称|repo name| -|fullPath|string|是|无|完整路径|full path| -|expires|long|否|0|过期时间,单位天(0代表永久保存)|expires day| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": null - } - ``` - -## 重命名节点 - -- API: POST /repository/api/node/rename/{projectId}/{repoName}/{fullPath}?newFullPath=/data/new_name.text -- API 名称: rename_node -- 功能说明: - - 中文:重命名节点 - - English:rename node -- 请求体 - 此接口请求体为空 - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |repoName|string|是|无|仓库名称|repo name| - |fullPath|string|是|无|完整路径|full path| - |newFullPath|string|是|无|新的完整路径|new full path| - -- 响应体 - - ``` json - { - "code": 0, - "message": null, - "data": null, - "traceId": null - } - ``` - -## 移动节点 - -- API: POST /repository/api/node/move -- API 名称: move_node -- 功能说明: - - 中文:移动节点 - - English:move node - - 移动文件或者文件夹,采用fast-failed模式,移动过程中出现错误则立即返回错误,剩下的文件不会再移动。该接口行为类似linux mv命令: - - - mv 文件 文件 -> 将源文件改名为目标文件 - - mv 文件 目录 -> 将源文件移动到目标目录 - - mv 目录 目录 -> 如果目标目录已存在,将源目录(目录本身及子文件)移动到目标目录;目标目录不存在则改名 - - mv 目录 文件 -> 出错 - -- 请求体 - - ``` json - { - "srcProjectId": "", - "srcRepoName": "", - "srcFullPath": "", - "destProjectId": "", - "destRepoName": "", - "destFullPath": "", - "overwrite": false - } - ``` - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |srcProjectId|string|是|无|源项目名称|src project name| - |srcRepoName|string|是|无|源仓库名称|src repo name| - |srcFullPath|string|是|无|源完整路径|src full path| - |destProjectId|string|否|null|目的项目名称。传null表示源项目|dest project name| - |destRepoName|string|否|null|目的仓库名称。传null表示源仓库|dest repo name| - |destFullPath|string|是|无|目的完整路径|dest full path| - |overwrite|boolean|否|false|同名文件是否覆盖|overwrite same node| - -- 响应体 - - ``` json - { - "code": 0, - "message": null, - "data": null, - "traceId": null - } - ``` - -## 拷贝节点 - -- API: POST /repository/api/node/copy -- API 名称: copy_node -- 功能说明: - - 中文:拷贝节点 - - English:copy node - - 拷贝文件或者文件夹,采用fast-failed模式,拷贝过程中出现错误则立即返回错误,剩下的文件不会再拷贝。该接口行为类似linux cp命令: - - - cp 文件 文件 -> 将源文件拷贝到目标文件 - - cp 文件 目录 -> 将文件移动到目标目录下 - - cp 目录 目录 -> 如果目标目录已存在,将源目录(目录本身及子文件)拷贝到目标目录;否则将源目录下文件拷贝到目标目录 - - cp 目录 文件 -> 出错 - -- 请求体 - - ``` json - { - "srcProjectId": "", - "srcRepoName": "", - "srcFullPath": "", - "destProjectId": "", - "destRepoName": "", - "destFullPath": "", - "overwrite": false - } - ``` - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |srcProjectId|string|是|无|源项目名称|src project name| - |srcRepoName|string|是|无|源仓库名称|src repo name| - |srcFullPath|string|是|无|源完整路径|src full path| - |destProjectId|string|否|null|目的项目名称。传null表示源项目|dest project name| - |destRepoName|string|否|null|目的仓库名称。传null表示源仓库|dest repo name| - |destFullPath|string|是|无|目的完整路径|dest full path| - |overwrite|boolean|否|false|同名文件是否覆盖|overwrite same node| - -- 响应体 - - ``` json - { - "code": 0, - "message": null, - "data": null, - "traceId": null - } - ``` - -## 统计节点大小信息 - -- API: GET /repository/api/node/size/{projectId}/{repoName}/{fullPath} -- API 名称: compute_node_size -- 功能说明: - - 中文:统计节点大小信息 - - English:compute node size -- 请求体 - 此接口请求体为空 - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |repoName|string|是|无|仓库名称|repo name| - |fullPath|string|是|无|完整路径|full path| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": { - "subNodeCount": 32, - "size": 443022203 - }, - "traceId": null - } - ``` - -- data字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |subNodeCount|long|子节点数量(包括目录)|sub node count| - |size|long|目录/文件大小|directory/file size| - -## 查询节点删除点 - -- API: GET /repository/api/node/list-deleted/{projectId}/{repoName}/{fullPath} -- API 名称: list_node_deleted -- 功能说明: - - 中文:查询节点删除点 - - English:list node deleted point -- 请求体 - 此接口请求体为空 - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |repoName|string|是|无|仓库名称|repo name| - |fullPath|string|是|无|删除的节点路径,可以为目录,也可以为文件|full path| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": [ - { - "id": 1632451573064, - "fullPath": "/test.txt", - "size": 6, - "sha256": "a73ec2f6ed66564f5714ed3d02aa6b54a70f47f0ecc5348c72fbc804a4b5f61c", - "metadata": {}, - "deletedBy": "system", - "deletedTime": "2021-09-24T10:46:13.064" - } - ], - "traceId": "" - } - ``` - -- data字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |id|long|删除点id|delete point id| - |fullPath|string|节点完整路径|node full path| - |size|long|节点大小|file size| - |sha256|string|节点sha256|file sha256| - |metadata|object|节点元数据,key-value键值对|node metadata| - |deletedBy|string|删除人|delete user| - |deletedTime|string|删除时间|delete time| - -## 恢复被删除节点 - -- API: POST /repository/api/node/restore/{projectId}/{repoName}/{fullPath}?deletedId=1632451573064&conflictStrategy=SKIP -- API 名称: restore_node -- 功能说明: - - 中文:恢复被删除节点 - - English:restore deleted node -- 请求体 - 此接口请求体为空 - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |repoName|string|是|无|仓库名称|repo name| - |fullPath|string|是|无|删除的节点路径,可以为目录,也可以为文件|full path| - |deletedId|long|是|无|删除点id,通过查询获得|deleted point id| - |conflictStrategy|string|是|SKIP|冲突处理策略。假如用户新创建了新的同名文件的冲突处理策略|conflict strategy| - -- ConflictStrategy 冲突处理策略选项 - - SKIP: 跳过 - - OVERWRITE: 覆盖 - - FAILED: 失败 - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": { - "fullPath": "/test.txt", - "restoreCount": 1, - "skipCount": 0, - "conflictCount": 0 - }, - "traceId": "" - } - ``` - -- data字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |fullPath|string|节点完整路径|full path| - |restoreCount|long|恢复数量|restore count| - |skipCount|long|跳过数量|skip count| - |conflictCount|long|冲突数量|conflict count| - -## 自定义搜索 - -- API: POST /repository/api/node/search -- API 名称: node search -- 功能说明: - - 中文:节点自定义搜索。最外层的查询条件中必须包含projectId条件,可以传入repoType指定仓库类型或者repoName指定仓库查询。 - - English:search node -- 请求体 - 参考[自定义搜索接口公共说明](../common/search.md?id=自定义搜索协议) - - 假设需要查询*项目test下, 仓库为generic-local1或generic-local2,文件名以.tgz结尾的文件,并按照文件名和大小排序,查询结果包含name、fullPath、size、sha256、md5、metadata字段*,构造的请求体如下, - ``` json - - { - "select": ["name", "fullPath", "size", "sha256", "md5", "metadata"], - "page": { - "pageNumber": 1, - "pageSize": 20 - }, - "sort": { - "properties": ["name", "size"], - "direction": "ASC" - }, - "rule": { - "rules": [ - { - "field": "projectId", - "value": "test", - "operation": "EQ" - }, - { - "field": "repoName", - "value": ["generic-local1", "generic-local2"], - "operation": "IN" - }, - { - "field": "name", - "value": ".tgz", - "operation": "SUFFIX" - }, - { - "field": "folder", - "value": "false", - "operation": "EQ" - }, - ], - "relation": "AND" - } - } - ``` - - - -## 查询节点总览 - -- API: GET /repository/api/node/search/overview?projectId={projectId}&name={name}&exRepo={reponames} - -- API 名称: query_node_overview - -- 功能说明: - - - 中文:查询节点总览 - - English:query node overview - -- 请求体 - 此接口请求体为空 - -- 请求字段说明 - - | 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | - | --------- | ------ | -------- | ------ | -------------------------------- | ------------ | - | projectId | string | 是 | 无 | 项目名称 | project name | - | name | string | 是 | 无 | 查询文件名 | file name | - | exRepo | string | 否 | null | 排除的仓库,多个仓库以 `,` 分隔" | repo name | - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": [ - { - "projectId": "test", - "repos": [ - { - "repoName": "custom", - "packages": 10 - }, - { - "repoName": "scan_test", - "packages": 2 - } - ], - "sum": 20 - } - ], - "traceId": "" - } - ``` - -- data字段说明 - - | 字段 | 类型 | 说明 | Description | - | --------- | ------ | ------------ | -------------------- | - | projectId | string | 节点所属项目 | node project id | - | repoName | string | 节点所属仓库 | node repository name | - | packages | Int | 节点数量 | node count | - -## - -## 清理创建时间早于{date}的文件节点 - -- API: DELETE /repository/api/node/clean/{projectId}/{repoName}?date=yyyy-MM-dd'T'HH:mm:ss.SSSXXX - -- API 名称: delete_node_created_before_date - -- 功能说明: - - - 中文:清理创建时间早于{date}的文件节点 - - English:delete node created before date - -- 请求体 - 此接口请求体为空 - -- 请求字段说明 - - | 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | - | --------- | ------ | -------- | ------ | -------- | ------------ | - | projectId | string | 是 | 无 | 项目名称 | project name | - | repoName | string | 是 | 无 | 仓库名称 | repo name | - | date | string | 是 | 无 | 日期 | date time | - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": null - } - ``` - -## \ No newline at end of file diff --git a/docs/storage/apidoc/node/share.md b/docs/storage/apidoc/node/share.md deleted file mode 100644 index 22b326f134a..00000000000 --- a/docs/storage/apidoc/node/share.md +++ /dev/null @@ -1,182 +0,0 @@ -# Share文件分享接口 - -[toc] - -## 创建分享下载链接 - -- API: POST /repository/api/share/{projectId}/{repoName}/{fullPath} -- API 名称: create_share_url -- 功能说明: - - 中文:创建分享下载链接 - - English:create share url -- 请求体 - - ```json - { - "authorizedUserList": ["user1", "user2"], - "authorizedIpList": ["192.168.1.1", "127.0.0.1"], - "expireSeconds": 3600 - } - ``` - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |repoName|string|是|无|仓库名称|repo name| - |fullPath|string|是|无|完整路径|full path| - |authorizedUserList|[string]|否|无|授权用户列表,若为空所有用户可下载|share user list| - |authorizedIpList|[string]|否|无|授权ip列表,若为空所有ip可下载|share ip list| - |expireSeconds|long|否|0|下载链接有效时间,单位秒|expire seconds| - -- 响应体 - - ``` json - { - "code": 0, - "message": null, - "data": { - "projectId": "test", - "repoName": "generic-local", - "fullPath": "/test.txt", - "shareUrl": "/api/share/test/generic-local/test.json?token=bef56a14c33342beba7fdb5f63508d24", - "authorizedUserList": [ - "user1", - "user2" - ], - "authorizedIpList": [ - "192.168.1.1", - "127.0.0.1" - ], - "expireDate": "2020-08-13T12:35:38.541" - }, - "traceId": null - } - ``` - -- data字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |projectId|string|项目id|project id| - |repoName|string|仓库名称|repo name| - |fullPath|string|完整路径|full path| - |shareUrl|string|分享下载链接|share url| - |authorizedUserList|list|授权用户列表|authorized user list| - |authorizedIpList|list|授权ip列表|authorized ip list| - |expireDate|string|过期时间|expire date| - -## 创建分享下载链接(批量) - -- API: POST /repository/api/share/batch -- API 名称: create_batch_share_url -- 功能说明: - - 中文:创建分享下载链接(批量) - - English:create batch share url -- 请求体 - - ```json - { - "projectId": "", - "repoName": "", - "fullPathList": "", - "authorizedUserList": ["user1", "user2"], - "authorizedIpList": ["192.168.1.1", "127.0.0.1"], - "expireSeconds": 3600 - } - ``` - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |repoName|string|是|无|仓库名称|repo name| - |fullPathList|string|是|无|完整路径列表|full path list| - |authorizedUserList|[string]|否|无|授权用户列表,若为空所有用户可下载|share user list| - |authorizedIpList|[string]|否|无|授权ip列表,若为空所有ip可下载|share ip list| - |expireSeconds|long|否|0|下载链接有效时间,单位秒|expire seconds| - -- 响应体 - - ``` json - { - "code": 0, - "message": null, - "data": { - [ - "projectId": "test", - "repoName": "generic-local", - "fullPath": "/test.txt", - "shareUrl": "/api/share/test/generic-local/test.json?token=bef56a14c33342beba7fdb5f63508d24", - "authorizedUserList": [ - "user1", - "user2" - ], - "authorizedIpList": [ - "192.168.1.1", - "127.0.0.1" - ], - "expireDate": "2020-08-13T12:35:38.541" - ] - }, - "traceId": null - } - ``` - - -- data字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |projectId|string|项目id|project id| - |repoName|string|仓库名称|repo name| - |fullPath|string|完整路径|full path| - |shareUrl|string|分享下载链接|share url| - |authorizedUserList|[string]|授权用户列表|authorized user list| - |authorizedIpList|[string]|授权ip列表|authorized ip list| - |expireDate|string|过期时间|expire date| - -## 分享链接下载 - -- API: GET /repository/api/share/{projectId}/{repoName}/{fullPath}?token=xxx -- API 名称: download_share_url -- 功能说明: - - 中文:分享链接下载,支持HEAD操作 - - English:download by share url -- 请求体 - 此接口请求体为空 - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |repoName|string|是|无|仓库名称|repo name| - |fullPath|string|是|无|完整路径|full path| - |token|string|是|无|下载凭证|download token| - -- 请求头 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |Range|string|否|无|RFC 2616 中定义的字节范围,范围值必须使用 bytes=first-last 格式且仅支持单一范围,不支持多重范围。first 和 last 都是基于0开始的偏移量。例如 bytes=0-9,表示下载对象的开头10个字节的数据;bytes=5-9,表示下载对象的第6到第10个字节。此时返回 HTTP 状态码206(Partial Content)及 Content-Range 响应头部。如果 first 超过对象的大小,则返回 HTTP 状态码416(Requested Range Not Satisfiable)错误。如果不指定,则表示下载整个对象|bytes range| - -- 响应头 - - |字段|类型|说明|Description| - |---|---|---|---| - |Accept-Ranges|string|RFC 2616 中定义的服务器接收Range范围|RFC 2616 Accept-Ranges| - |Cache-Control|string|RFC 2616 中定义的缓存指令|RFC 2616 Cache-Control| - |Connection|string|RFC 2616 中定义,表明响应完成后是否会关闭网络连接。枚举值:keep-alive,close。|RFC 2616 Connection| - |Content-Disposition|string|RFC 2616 中定义的文件名称|RFC 2616 Content-Disposition| - |Content-Length|long|RFC 2616 中定义的 HTTP 响应内容长度(字节)|RFC 2616 Content Length| - |Content-Range|string|RFC 2616 中定义的返回内容的字节范围,仅当请求中指定了 Range 请求头部时才会返回该头部|RFC 2616 Content-Range| - |Content-Type|string|RFC 2616 中定义的 HTTP 响应内容类型(MIME)|RFC 2616 Content Length| - |Date|string|RFC 1123 中定义的 GMT 格式服务端响应时间,例如Mon, 27 Jul 2020 08:51:59 GMT|RFC 1123 Content Length| - |Etag|string|ETag 全称为 Entity Tag,是文件被创建时标识对象内容的信息标签,可用于检查对象的内容是否发生变化,通用制品文件会返回文件的sha256值|ETag, file sha256 checksum| - |Last-Modified|string|文件的最近一次上传的时间,例如Mon, 27 Jul 2020 08:51:58 GMT|file last modified time| - -- 响应体 - [文件流] diff --git a/docs/storage/apidoc/package/package.md b/docs/storage/apidoc/package/package.md deleted file mode 100644 index bcb69dccbc8..00000000000 --- a/docs/storage/apidoc/package/package.md +++ /dev/null @@ -1,394 +0,0 @@ -# Package制品包版本接口 - -[toc] - -## 分页查询包列表 - -- API: GET /repository/api/package/page/{projectId}/{repoName}?packageName=xxx&pageNumber=0&pageSize=20 -- API 名称: list_package_page -- 功能说明: - - 中文:分页查询包列表 - - English:list package page -- 请求体 - 此接口请求体为空 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |repoName|string|是|无|仓库名称|repo name| - |packageName|string|否|无|包名称,支持前缀匹配模糊搜索|package name| - |pageNumber|Int|是|无|页码|page number| - |pageSize|Int|是|无|每页数量|page size| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": { - "pageNumber": 0, - "pageSize": 1, - "totalRecords": 18, - "totalPages": 18, - "records": [ - { - "projectId" : "test", - "repoName" : "generic-local", - "name" : "test", - "key" : "com.tencent.bkrepo", - "type" : "MAVEN", - "latest" : "0.0.9", - "downloads" : 101, - "versions" : 9, - "description": null, - "createdBy" : "admin", - "createdDate" : "2020-07-27T16:02:31.394", - "lastModifiedBy" : "admin", - "lastModifiedDate" : "2020-07-27T16:02:31.394", - "extension" : { - "appVersion": "4.2.4" - }, - "historyVersion" : [ - "7.8.10" - ] - } - ] - }, - "traceId": null - } - ``` - -- records字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |projectId|string|节点所属项目|project id| - |repoName|string|节点所属仓库|repository name| - |name|string|包名称|package name| - |key|string|包唯一key|package unique key| - |type|string|包类别|package type| - |latest|string|最新上传版本名称|latest version name| - |downloads|Long|下载次数|download times| - |versions|Long|版本数量|version count| - |description|string|简要描述|brief description| - |createdBy|string|创建者|create user| - |createdDate|string|创建时间|create time| - |lastModifiedBy|string|上次修改者|last modify user| - |extension|object|扩展信息,key-value键值对|extension| - |historyVersion|list[string]|历史版本|history version| - -- extension字段说明 - |字段|类型|说明|Description| - |---|---|---|---| - |appVersion|string|软件版本|app version| - -## 查询包信息 - -- API: GET /repository/api/package/info/{projectId}/{repoName}?packageKey=docker://nginx -- API 名称: get_package_info -- 功能说明: - - 中文:查询包信息 - - English:get package info -- 请求体 - 此接口请求体为空 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |repoName|string|是|无|仓库名称|repo name| - |packageKey|string|是|无|包唯一key|package unique key| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": { - { - "projectId" : "test", - "repoName" : "generic-local", - "name" : "test", - "key" : "com.tencent.bkrepo", - "type" : "MAVEN", - "latest" : "0.0.9", - "downloads" : 101, - "versions": 9, - "description": null, - "createdBy" : "admin", - "createdDate" : "2020-07-27T16:02:31.394", - "lastModifiedBy" : "admin", - "lastModifiedDate" : "2020-07-27T16:02:31.394", - "extension" : { - "appVersion": "4.2.4" - }, - "historyVersion" : [ - "7.8.10" - ] - } - }, - "traceId": null - } - ``` - -- record字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |projectId|string|节点所属项目|project id| - |repoName|string|节点所属仓库|repository name| - |name|string|包名称|package name| - |key|string|包唯一key|package unique key| - |type|string|包类别|package type| - |latest|string|最新上传版本名称|latest version name| - |downloads|Long|下载次数|download times| - |versions|Long|版本数量|version count| - |description|string|简要描述|brief description| - |createdBy|string|创建者|create user| - |createdDate|string|创建时间|create time| - |lastModifiedBy|string|上次修改者|last modify user| - |lastModifiedDate|string|上次修改时间|last modify time| - |extension|object|扩展信息,key-value键值对|extension| - |historyVersion|list[string]|历史版本|history version| - -- extension字段说明 - |字段|类型|说明|Description| - |---|---|---|---| - |appVersion|string|软件版本|app version| - -## 删除包 - -- API: DELETE /repository/api/package/delete/{projectId}/{repoName}?packageKey=gav://com.tencent:test -- API 名称: delete_package -- 功能说明: - - 中文:删除包 - - English:delete package -- 请求体 - 此接口请求体为空 - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |repoName|string|是|无|仓库名称|repo name| - |packageKey|string|是|无|包唯一key|package unique key| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": null - } - ``` - -## 分页查询包版本 - -- API: GET /repository/api/version/page/{projectId}/{repoName}?packageKey=gav://com.tencent:test&version=0.0.1&stageTag=release&pageNumber=0&pageSize=20 -- API 名称: list_version_page -- 功能说明: - - 中文:分页查询版本列表 - - English:list version page -- 请求体 - 此接口请求体为空 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |repoName|string|是|无|仓库名称|repo name| - |packageKey|string|否|无|包唯一key|package unique key| - |version|string|否|无|版本名称,前缀匹配|version name| - |stageTag|string|否|无|晋级标签, 逗号分隔|stage tag list| - |pageNumber|Int|是|无|页码|page number| - |pageSize|Int|是|无|每页数量|page size| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": { - "pageNumber": 0, - "pageSize": 1, - "totalRecords": 18, - "totalPages": 18, - "records": [ - { - "name" : "0.0.9", - "size" : 1024, - "downloads" : 18, - "stageTag" : ["@prerelease", "@release"], - "createdBy" : "admin", - "createdDate" : "2020-07-27T16:02:31.394", - "lastModifiedBy" : "admin", - "lastModifiedDate" : "2020-07-27T16:02:31.394", - "metadata": { - "apiVersion": "v1", - "appVersion": "7.0", - "description": "Deploy a basic tomcat application server with sidecar as web archive container", - "home": "https://github.com/yahavb", - "icon": "http://tomcat.apache.org/res/images/tomcat.png", - "keywords": [], - "maintainers": [ - { - "name": "yahavb", - "email": "ybiran@ananware.systems" - } - ], - "name": "tomcat", - "sources": [], - "urls": [], - "version": "0.4.2" - }, - } - ] - }, - "traceId": null - } - ``` - -- records字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |name|string|版本名称|version name| - |size|long|版本大小|version size| - |downloads|long|版本下载次数|download times| - |stageTag|list[string]|晋级阶段标签列表|stage tag list| - |metadata|object|元数据,key-value键值对|metadata| - |createdBy|string|创建者|create user| - |createdDate|string|创建时间|create time| - |lastModifiedBy|string|上次修改者|last modify user| - |lastModifiedDate|string|上次修改时间|last modify time| - -## 删除版本 - -- API: DELETE /repository/api/version/delete/{projectId}/{repoName}?packageKey=npm://test&version=0.0.1 -- API 名称: delete_version -- 功能说明: - - 中文:删除版本 - - English:delete version -- 请求体 - 此接口请求体为空 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |repoName|string|是|无|仓库名称|repo name| - |packageKey|string|是|无|包唯一key|package unique key| - |version|string|是|无|版本名称|version name| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": null - } - ``` - -## 自定义搜索包 - -- API: POST /repository/api/package/search -- API 名称: package search -- 功能说明: - - 中文:节点自定义搜索。最外层的查询条件中必须包含projectId条件,可以传入repoType指定仓库类型或者repoName指定仓库查询。 - - English:search package -- 请求体 - 参考[自定义搜索接口公共说明](../common/search.md) - - ``` json - 查询在项目test下, 仓库类型为MAVEN,包名为spring开头的包,并按照包名排序,查询结果包含name、key、latest、donwloads、versions字段 - { - "select": ["name", "key", "latest", "downloads", "versions"], - "page": { - "pageNumber": 1, - "pageSize": 20 - }, - "sort": { - "properties": ["name"], - "direction": "ASC" - }, - "rule": { - "rules": [ - { - "field": "projectId", - "value": "test", - "operation": "EQ" - }, - { - "field": "repoType", - "value": "MAVEN", - "operation": "EQ" - }, - { - "field": "name", - "value": "spring", - "operation": "PREFIX" - } - ], - "relation": "AND" - } - } - ``` - -## 下载版本 - -- API: GET /repository/api/version/download/{projectId}/{repoName}?packageKey=npm://test&version=0.0.1 -- API 名称: download_version -- 功能说明: - - 中文:下载版本 - - English:download version - -- 请求体 - 此接口请求体为空 - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |repoName|string|是|无|仓库名称|repo name| - |packageKey|string|是|无|包唯一key|package unique key| - |version|string|是|无|版本名称|version name| - -- 响应体 - [文件流] - -## 公共说明 - -### 包类型枚举 - -> 用于标识构件包类型 - -|枚举值|说明| -|---|---| -|DOCKER|Docker包| -|MAVEN|Maven包| -|PYPI|Pypi包| -|NPM|Npm包| -|HELM|Helm包| -|COMPOSER|Composer包| -|RPM|Rpm包| - -### package key 格式 - -> 因为同个仓库下包名称不唯一, 所以使用package key来确定包的唯一性。 -> pakcage key的格式为: `{type}://{value}` - -|type类型|value格式|例子| -|---|---|---| -|gav (maven采用此格式)|groupId:artifactId|gav://com.tencent.bkrepo:test| -|docker|name(包名称,docker中名称唯一)|docker://test| -|npm|name|npm://test| \ No newline at end of file diff --git a/docs/storage/apidoc/package/stage.md b/docs/storage/apidoc/package/stage.md deleted file mode 100644 index 138e9d4fcb3..00000000000 --- a/docs/storage/apidoc/package/stage.md +++ /dev/null @@ -1,34 +0,0 @@ -# Stage制品晋级接口 - -[toc] - -## 制品晋级 - -- API: POST /repository/api/stage/upgrade/{projectId}/{repoName}/{packgekey}/{version}?tag=@release -- API 名称: upgrade_stage -- 功能说明: - - 中文:制品晋级 - - English:upgrade stage -- 请求体 - 此接口无请求体 - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |repoName|string|是|无|仓库名称|repo name| - |packageKey|string|是|无|包唯一key|package unique key| - |version|string|是|无|版本名称|version name| - |tag|string|否|无|不填则默认晋级下一阶段,可选值:@prerelease、@release。前面的@可以省略|new stage tag| - -- 响应体 - - ``` json - { - "code": 0, - "message": null, - "data": null, - "traceId": null - } - ``` diff --git a/docs/storage/apidoc/registry/docker.md b/docs/storage/apidoc/registry/docker.md deleted file mode 100644 index fd9f08305d2..00000000000 --- a/docs/storage/apidoc/registry/docker.md +++ /dev/null @@ -1,518 +0,0 @@ -## docker扩展接口说明 - -### 获取manifest文件 - -- API: GET /docker/ext/manifest/{projectId}/{repoName}/{name}/{tag} -- API 名称: get_repo_manifest -- 功能说明: - - 中文:获取repo对应的manifest文件 - - English:get manifest by repo and tag - -- input body: - - -``` json - -``` - - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|projectId|string|是|无|项目id|the project id| -|repoName|string|是|无|仓库名称| name of repo| -|name|string|是|无|docker镜像名| name of docker image| -|tag|string|是|无|repo tag |tag of docker repo| - - - -- output: - -``` -{ - "code":0, - "message":null, - "data":"{ - "schemaVersion": 2, - "mediaType": "application/vnd.docker.distribution.manifest.v2+json", - "config": { - "mediaType": "application/vnd.docker.container.image.v1+json", - "size": 9404, - "digest": "sha256:6146596998118de36add541f9e17075a0e40be15cfc84a7fa8efe0bbe5bdc49a" - }, - "layers": [ - { - "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", - "size": 50379708, - "digest": "sha256:16ea0e8c887910fe167687a0169991b4c1fc165257aab6b116f6a5e61a64e7af" - }, - { - "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", - "size": 7811508, - "digest": "sha256:50024b0106d53dcbd29889c65bc040439b2bb8947dac16c8c670db894a2c5ba6" - }, - { - "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", - "size": 9996013, - "digest": "sha256:ff95660c69375e19e287b2ea87ca9b4be008cd036e95d541515262b86cc521d9" - }, - { - "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", - "size": 51786970, - "digest": "sha256:9c7d0e5c0bc204b3a36e3f8ff320741da0bd0225e0a67e224c6265c1e208f80a" - }, - { - "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", - "size": 192044870, - "digest": "sha256:29c4fb388fdfef16e8278fba2b06d46e48d152e1b40f4347c8828a04c8e2a87e" - }, - { - "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", - "size": 11568, - "digest": "sha256:f87845d1b3b4e4ead42cddc30dcdcf5cf06555785f8299d304cc118126bc0dd8" - }, - { - "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", - "size": 98930042, - "digest": "sha256:fd6d3a50a72f31eec9fe21bc3c65888df636dc32e6cb6c44b698d73258cef077" - }, - { - "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", - "size": 11559, - "digest": "sha256:dcfb948bad0edeb2d030e8dc230224877ffd7f5d4a93ea43d940aaceb6d95d91" - }, - { - "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", - "size": 1943, - "digest": "sha256:f018ac72b8e07233e71dfd9cd1d9447c5fc034d2d8f272d7324e7b276912f8db" - } - ] -}", - "traceId":"" -} - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | bool |the manifest data |the data of manifest| -|traceId|string|请求跟踪id|the trace id| - - -### 根据layerId下载layer文件 - -- API: GET /docker/ext/layer/{projectId}/{repoName}/{name}/{Id} -- API 名称: -- 功能说明: - - 中文:根据layerId获取layer文件 - - English:download layer file by layerId - -- input body: - -``` json - -``` - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|projectId|string|是|无|项目id|the project id| -|repoName|string|是|无|仓库名称| name of repo| -|name|string|是|无|docker镜像名| name of docker image| -|Id|string|是|无|layer id|the id of layer| - - -- output: - -``` -文件流 - -``` - -- output 字段说明 - -### 获取指定projectId和repoName下的所有镜像 - -- API: GET /docker/ext/repo/{projectId}/{repoName}?pageNumber=0&pageSize=10&name=docker -- API 名称: get_image_by_project_repository -- 功能说明: - - 中文:获取指定project和仓库下的所有docker镜像 - - English:get image by project and repository - -- input body: - - -``` json - -``` - - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|projectId|string|是|无|项目id|the project id| -|repoName|string|是|无|仓库名称| name of repo| -|pageNumber|Int|是|无|页码数| number of page| -|pageSize|Int|是|无|每页大小| limit of page| -|name|string|否|无|镜像名称| image name| - - - -- output: - -``` -{ - "code":0, - "message":null, - "data":{ - "toatalRecords":100, - "records":[ - { - "name":"hello-world", - "lastModifiedBy":"admin", - "lastModifiedDate":"2020-09-10T14:48:22.846", - "downloadCount":0, - "logoUrl":"", - "description":"" - }, - { - "name":"mongo", - "lastModifiedBy":"admin", - "lastModifiedDate":"2020-08-28T12:07:12.672", - "downloadCount":0, - "logoUrl":"", - "description":"" - } - ] - }, - "traceId":"" -} - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | string array |image 名称列表 |the list of image| -|traceId|string|请求跟踪id|the trace id| -|name|string|镜像ID|the id of image| -|lastModifiedBy|string|创建人|the creator of image| -|lastModifiedDate|time|创建时间|create date of image| - -### 获取repo的所有tag - -- API: GET /docker/ext/tag/{projectId}/{repoName}/{name}?pageNumber=0&pageSize=10&tag=v1 -- API 名称: get_repo_tag_list -- 功能说明: - - 中文:获取repo对应的manifest文件 - - English:get image tag by repo - -- input body: - - -``` json - -``` - - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|projectId|string|是|无|项目id|the project id| -|repoName|string|是|无|仓库名称| name of repo| -|name|string|是|无|docker 镜像名称| name of docker image| -|pageNumber|Int|是|无|页码数| number of page| -|pageSize|Int|是|无|每页大小| limit of page| -|tag|string|否|无|tag名称| the tag name| - - - -- output: - -``` -{ - "code":0, - "message":null, - "data":{ - "toatalRecords":100, - "records":[ - { - "tag":"latest", - "stageTag":"", - "size":524, - "lastModifiedBy":"admin", - "lastModifiedDate":"2020-09-10T14:48:22.846", - "downloadCount":0, - "registryUrl":"bkrepo.example.com/test/test/php:latest" - }, - { - "tag":"v1", - "stageTag":"", - "size":524, - "lastModifiedBy":"admin", - "lastModifiedDate":"2020-09-10T14:49:37.904", - "downloadCount":0, - "registryUrl":"bkrepo.example.com/test/test/php:v1" - } - ] - }, - "traceId":"" -} -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | string array | image的tag列表 |tag list of the image| -|traceId|string|请求跟踪id|the trace id| -|tag|string|tag名称|the name of tag| -|stageTag|string|制品状态|the status of image| -|size|Int|镜像大小|the size of image| -|downloadCount|Int|下载次数|the download count of image| -|lastModifiedBy|date|更新人|the man upload it| -|lastModifiedDate|date|更新时间|the modified date| - - -### 删除指定projectId和repoName下的的镜像 - -- API: DELETE /docker/ext/package/delete/{projectId}/{repoName}?packageKey={packageKey} -- API 名称: delete_image_by_project_repository_name -- 功能说明: - - 中文:删除指定project和仓库下name的镜像 - - English:delete image by project and repository and image name - -- input body: - - -``` json - -``` - - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|projectId|string|是|无|项目id|the project id| -|repoName|string|是|无|仓库名称| name of repo| -|packageKey|string|是|无|镜像名称| name of image| - - - -- output: - -``` -{ - "code":0, - "message":null, - "traceId":"", - "data":true -} - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | bool |删除结果|the result of delete| -|traceId|string|请求跟踪id|the trace id| - -### 删除指定projectId和repoName下的的镜像的镜像tag - -- API: DELETE /docker/ext/version/delete/{projectId}/{repoName}?packageKey={packageKey}&version={version} -- API 名称: delete_image_by_project_repository_name_tag -- 功能说明: - - 中文:删除指定project和仓库下name的镜像 - - English:delete image by project and repository and image name - -- input body: - - -``` json - -``` - - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|projectId|string|是|无|项目id|the project id| -|repoName|string|是|无|仓库名称| name of repo| -|packageKey|string|是|无|镜像名称| name of image| -|version|string|是|无|镜像名称| tag of image| - - - -- output: - -``` -{ - "code":0, - "message":null, - "traceId":"", - "data":true -} - -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | bool |删除结果 | the result of delete| -|traceId|string|请求跟踪id|the trace id| - -### 获取repo下指定tag的详情 - -- API: GET /docker/ext/version/detail/{projectId}/{repoName}?packageKey={packageKey}&version={version} -- API 名称: get_repo_tag_detail -- 功能说明: - - 中文:获取repo下tag对象的镜像相亲 - - English:get image repo tag detail - -- input body: - - -``` json - -``` - - -- input 字段说明 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|projectId|string|是|无|项目id|the project id| -|repoName|string|是|无|仓库名称| name of repo| -|packageKey|string|是|无|镜像名称| name of image| -|version|string|是|无|镜像名称| tag of image| - - - -- output: - -``` -{ - "code":0, - "message":null, - "data":{ - "basic":{ - "domain":"bkrepo.example.com", - "size":2487, - "version":"v1", - "createdBy":"owen", - "createdDate":"2020-09-17 03:48:42.896Z", - "lastModifiedBy":"admin", - "lastModifiedDate":"2020-09-10T14:49:37.904", - "downloadCount":0, - "sha256":"fce289e99eb9bca977dae136fbe2a82b6b7d4c372474c9235adc1741675f587e", - "os":"linux" - }, - "history":[ - { - "created":"2019-01-01T01:29:27.416803627Z", - "created_by":"/bin/sh -c #(nop) COPY file:f77490f70ce51da25bd21bfc30cb5e1a24b2b65eb37d4af0c327ddc24f0986a6 in / " - }, - { - "created":"2019-01-01T01:29:27.650294696Z", - "created_by":"/bin/sh -c #(nop) CMD ["/hello"]" - } - ], - "metadata":{ - "docker.manifest":"v1", - "sha256":"92c7f9c92844bbbb5d0a101b22f7c2a7949e40f8ea90c8b3bc396879d95e899a", - "docker.repoName":"hello-world", - "docker.manifest.digest":"sha256:92c7f9c92844bbbb5d0a101b22f7c2a7949e40f8ea90c8b3bc396879d95e899a", - "docker.manifest.type":"application/vnd.docker.distribution.manifest.v2+json" - }, - "layers":[ - { - "mediaType":"application/vnd.docker.image.rootfs.diff.tar.gzip", - "size":977, - "digest":"sha256:1b930d010525941c1d56ec53b97bd057a67ae1865eebf042686d2a2d18271ced" - } - ] - }, - "traceId":"" -} -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | object | tag详情数据 |tag list of the image| -|traceId|string|请求跟踪id|the trace id| -|basic|object|基础数据|the basic data| -|history|object array|镜像构建历史|the history of build| -|metadata|object|元数据信息|the metadata of image tag| -|layers|object array|层级信息|the layer info of image| - -### 获取docker仓库地址 - -- API: GET /docker/ext/addr -- API 名称: get_docker_repo_addr -- 功能说明: - - 中文:获取docker镜像仓库配置地址 - - English:get docker repo addr - -- input body: - - -``` json - -``` - - -- input 字段说明 - - - - -- output: - -``` -{ - "code":0, - "message":null, - "data":"docker.bk.com", - "traceId":"" -} -``` - -- output 字段说明 - -| 字段|类型|说明|Description| -|---|---|---|---| -|code|bool|错误编码。 0表示success,>0表示失败错误 |0:success, other: failure| -|message|result message|错误消息 |the failure message | -|data | string |docker仓库地址|the docker registry addr| -|traceId|string|请求跟踪id|the trace id| - - -### 鉴权示例 - - - diff --git a/docs/storage/apidoc/registry/git.md b/docs/storage/apidoc/registry/git.md deleted file mode 100644 index a7813973c25..00000000000 --- a/docs/storage/apidoc/registry/git.md +++ /dev/null @@ -1,67 +0,0 @@ -## GIT节点接口说明 - -### 同步仓库 -- API: POST /{projectId}/{repoName}/sync?hub_type={hub_type}&owner={owner} - -- API 名称: repository_sync - -- 功能说明: - - - 中文:同步仓库 - - English:sync repository - -- 请求体 - 此接口请求体为空 - -- 请求字段说明 - - | 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | - | --------------------- | ------- | -------- | --------- | --------------------- | ----------------------- | - | projectId | string | 是 | 无 | 项目名称 | project name | - | repoName | string | 是 | 无 | 仓库名称 | repo name | - | hub_type | enum | 否 | 无 | 仓库类型[github] | hub type[github] | - | owner | string | 否 | 无 | 仓库拥有者,hub_type传的情况必须传 | hub owner,required when hub_type have a value | - - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": "" - } - ``` - -- data字段说明 - - 请求成功无返回数据 - -### 查询文件内容 -- API: POST /{projectId}/{repoName}/raw/{ref}/{path}?hub_type={hub_type}&owner={owner} - -- API 名称: get_file_content - -- 功能说明: - - - 中文:查询文件内容 - - English:get file content - -- 请求体 - 此接口请求体为空 - -- 请求字段说明 - - | 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | - | --------------------- | ------- | -------- | --------- | --------------------- | ----------------------- | - | projectId | string | 是 | 无 | 项目名称 | project name | - | repoName | string | 是 | 无 | 仓库名称 | repo name | - | ref | string | 是 | 无 | branch/tag/commit的名字, 默认分支为master | The name of branch/tag/commit, default branch is master| - | path | string | 是 | 无 | 文件路径 | file path | - | hub_type | enum | 否 | 无 | 仓库类型[github] | hub type[github] | - | owner | string | 否 | 无 | 仓库拥有者,hub_type传的情况必须传 | hub owner,required when hub_type have a value | - - -- 响应体 - [文件流] \ No newline at end of file diff --git a/docs/storage/apidoc/registry/maven.md b/docs/storage/apidoc/registry/maven.md deleted file mode 100644 index 14a4320820c..00000000000 --- a/docs/storage/apidoc/registry/maven.md +++ /dev/null @@ -1,222 +0,0 @@ -## Maven节点接口说明 - -### 删除 jar包 - -* API: DELETE /maven/ext/package/delete/{project}/{repoName}/?packageKey={packageKey} - -* API 名称: delete_jar - -* 功能说明: - - - 中文:删除jar包, - - English:delete jar - -* 请求体 - 此接口请求体为空 - -* 请求字段说明 - - | 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | - | ---------- | ------ | -------- | ------ | --------- | ------------------ | - | projectId | string | 是 | 无 | 项目名称 | project name | - | repoName | string | 是 | 无 | 仓库名称 | repo name | - | packageKey | string | 是 | 无 | 包唯一key | package unique key | - -* 响应体 - - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": "" - } - ``` - - - -* data字段说明 - - - -### 删除对应版本jar包 - -* API: DELETE /maven/ext/version/delete/{project}/{repoName}/?packageKey={packageKey}&version={version} - -* API 名称: delete_jar_with_version - -* 功能说明: - - - 中文:删除对应版本jar包, - - English:delete jar with version - -* 请求体 - 此接口请求体为空 - -* 请求字段说明 - - | 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | - | ---------- | ------ | -------- | ------ | --------- | ------------------ | - | projectId | string | 是 | 无 | 项目名称 | project name | - | repoName | string | 是 | 无 | 仓库名称 | repo name | - | packageKey | string | 是 | 无 | 包唯一key | package unique key | - | version | string | 是 | 无 | 版本名称 | version name | - -* 响应体 - - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": "" - } - ``` - - - -* data字段说明 - - - - -### 版本详情 - -* API: GET /maven/ext/package/detail/{project}/{repoName}/?packageKey={packageKey}&version={version} - -* API 名称: artifact_detail_detail - -* 功能说明: - - - 中文:maven jar 版本详情 - - English:artifact detail detail - -* 请求体 - 此接口请求体为空 - -* 请求字段说明 - - | 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | - | ---------- | ------ | -------- | ------ | --------- | ------------------ | - | projectId | string | 是 | 无 | 项目名称 | project name | - | repoName | string | 是 | 无 | 仓库名称 | repo name | - | packageKey | string | 是 | 无 | 包唯一key | package unique key | - | version | string | 是 | 无 | 版本名称 | version name | - -* 响应体 - - ```json - { - "code": 0, - "message": null, - "data": { - "basic": { - "groupId": "com.tencent.bk.devops.atom", - "artifactId": "bksdk", - "version": "1.0.0", - "size": 42786, - "fullPath": "/com/tencent/bk/devops/atom/bksdk/1.0.0/bksdk-1.0.0.jar", - "lastModifiedBy": "anonymous", - "lastModifiedDate": "2020-09-27T14:43:06.083", - "downloadCount": 10, - "sha256": "e8e3e3b50daf0c2638a69e0b6ca3a1eee0b367bcabef5ae5bd7983700b9a6d58", - "md5": "358d9a0f68b641bf0a25289d1795022b", - "stageTag": [ - "@release" - ], - "description": null - }, - "metadata": {} - }, - "traceId": "" - } - ``` - -* data字段说明 - - | 字段 | 类型 | 说明 | Description | - | ---------------- | ------ | --------------------------- | ------------------------- | - | groupId | String | groupId | groupId | - | artifactId | String | artifactId | artifactId | - | version | String | version | version | - | size | long | 节点大小 | file size | - | fullPath | string | 节点完整路径 | node full path | - | folder | bool | 是否为文件夹 | is folder | - | sha256 | string | 节点sha256 | file sha256 | - | md5 | array | 节点md5 | file md5 checksum | - | stageTag | string | 晋级状态标签 | stage status tag | - | metadata | object | 节点元数据,key-value键值对 | node metadata | - | downloadCount | Int | 下载次数 | the download count of jar | - | lastModifiedBy | string | 上次修改者 | last modify user | - | lastModifiedDate | string | 上次修改时间 | last modify time | - | description | string | 描述信息 | description | - -## GAVC 搜索接口 - -- API: GET /ext/search/gavc/{projectId}?g={groupId}&a={artifactId}&v={version}&c{classifier}&repos={repo[,repo]} - -- API 名称: gavc_search - -- 功能说明: - - - 中文:maven 制品 gavc 搜索 - - English:search maven artifact with gavc - -- 请求体 - 此接口请求体为空 - -- 请求字段说明 - - **g ,a ,v ,c 四个查询条件不能全为空** - - | 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | - | --------- | ------ | -------- | ------ | ---------- | ------------ | - | projectId | string | 是 | 无 | 项目名称 | project name | - | g | string | 否 | 无 | groupID | groupID | - | a | string | 否 | 无 | artifactId | artifactId | - | v | string | 否 | 无 | version | version | - | c | string | 否 | 无 | classifier | classifier | - | repos | string | 否 | 无 | 仓库名列表 | repo list | - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": { - "pageNumber": 1, - "pageSize": 20, - "totalRecords": 4, - "totalPages": 1, - "records": [ - { - "uri": "http://127.0.0.1/maven/test/maven/com/mycompany/app/my-app/1.0-3/my-app-1.0-3.jar" - }, - { - "uri": "http://127.0.0.1/maven/test/maven/com/mycompany/app/my-app/1.0-3/my-app-1.0-3.pom" - }, - { - "uri": "http://127.0.0.1/maven/test/maven1/com/mycompany/app/my-app/1.0-3/my-app-1.0-3.jar" - }, - { - "uri": "http://127.0.0.1/maven/test/maven1/com/mycompany/app/my-app/1.0-3/my-app-1.0-3.pom" - } - ], - "page": 1, - "count": 4 - }, - "traceId": "" - } - ``` - -- data字段说明 - - | 字段 | 类型 | 说明 | Description | - | ---- | ------ | ------------ | ------------ | - | uri | string | 文件下载链接 | artifact uri | - - - - - diff --git a/docs/storage/apidoc/registry/npm.md b/docs/storage/apidoc/registry/npm.md deleted file mode 100644 index ab60206e4f7..00000000000 --- a/docs/storage/apidoc/registry/npm.md +++ /dev/null @@ -1,220 +0,0 @@ -## NPM节点接口说明 - -NPM节点接口使用统一接口协议,公共部分请参照[通用接口协议说明](./common.md) - -### 查询包的版本详情 - -- API: GET /npm/ext/version/detail/{projectId}/{repoName}?packageKey=xxx&version=xxx - -- API 名称: package_version_detail - -- 功能说明: - - 中文:查询NPM包版本详情信息 - - English:package version detail -- 请求体 - 此接口请求体为空 - -- 请求字段说明 - - | 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | - | ---------- | ------ | -------- | ------ | --------- | ------------------ | - | projectId | string | 是 | 无 | 项目名称 | project name | - | repoName | string | 是 | 无 | 仓库名称 | repo name | - | packageKey | string | 是 | 无 | 包唯一Key | package unique Key | - | version | string | 是 | 无 | 包版本 | package version | - -- 响应体 - -```json -{ - "code": 0, - "message": null, - "data": { - "basic": { - "version": "1.0.0", - "fullPath": "/helloworld/-/helloworld-1.0.0.tgz", - "size": 416, - "sha256": "d89fa4a0516258d994db19d0bb3aec099f98b9d6d7554c1da66db97b50b535c1", - "md5": "57616ff6cdec6db95c9b2f3fae259185", - "stageTag": [ - "@prerelease", - "@release" - ], - "projectId": "test", - "repoName": "npm-test", - "downloadCount": 0, - "createdBy": "admin", - "createdDate": "2020-09-28T17:29:04.814", - "lastModifiedBy": "admin", - "lastModifiedDate": "2020-09-28T17:29:04.814" - }, - "metadata": {}, - "dependencyInfo": { - "dependencies": [ - { - "name": "underscore", - "version": "^1.11.0" - }, - { - "name": "@hapi/hoek", - "version": "^9.0.0" - } - ], - "devDependencies": [ - { - "name": "@hapi/code", - "version": "8.x.x" - }, - { - "name": "@hapi/lab", - "version": "22.x.x" - } - ], - "dependents": { - "pageNumber": 1, - "pageSize": 20, - "totalRecords": 1, - "totalPages": 1, - "records": [ - { - "createdBy": "admin", - "createdDate": "2020-09-26T17:56:05.395", - "name": "helloworld", - "deps": "@xwhy/charis", - "projectId": "test", - "repoName": "npm-test" - } - ], - "count": 1, - "page": 1 - } - } - }, - "traceId": "" -} -``` - -- data字段说明 - - - Basic字段 - - | 字段 | 类型 | 说明 | Description | - | ---------------- | ------ | ---------------- | -------------------- | - | version | string | 包对应版本 | project id | - | fullPath | string | 包对应仓库全路径 | fullPath | - | size | string | 包大小 | file size | - | sha256 | string | 包的sha256值 | file sha256 | - | md5 | string | 节点md5值 | file md5 | - | stageTag | string | 晋级状态标签 | stage status tag | - | projectId | string | 节点所属项目 | node project id | - | repoName | string | 节点所属仓库 | node repository name | - | downloadCount | string | 简要描述 | download times | - | createdBy | string | 创建者 | create user | - | createdDate | string | 创建时间 | create time | - | lastModifiedBy | string | 上次修改者 | last modify user | - | lastModifiedDate | string | 上次修改时间 | last modify time | - - - Metadata字段: - - | 字段 | 类型 | 说明 | Description | - | ---- | ---- | ---- | ----------- | - | | | | | - - - dependencyInfo字段: - - - dependencies: 依赖信息 - - | 字段 | 类型 | 说明 | Description | - | ---- | ---- | ---- | ----------- | - | name | string | 依赖的包名称 | dependencies package name | - | version | string | 依赖的包版本 | dependencies package version | - - - devDependencies: 开发依赖信息 - - | 字段 | 类型 | 说明 | Description | - | ---- | ---- | ---- | ----------- | - | name | string | 开发依赖的包名称 | devDependencies package name | - | version | string | 开发依赖的包版本 | devDependencies package version | - - - dependents: 被依赖信息 - - | 字段 | 类型 | 说明 | Description | - | ----------- | ------ | -------------- | ---------------------- | - | name | string | 包名称 | package name | - | deps | string | 被依赖的包名称 | package dependent name | - | projectId | string | 节点所属项目 | node project id | - | repoName | string | 节点所属仓库 | node repository name | - | createdBy | string | 创建者 | create user | - | createdDate | string | 创建时间 | create time | - - - -### 删除仓库下的包 - -- API: DELETE /npm/ext/package/delete/{projectId}/{repoName}?packageKey=npm://helloworld -- API 名称: delete_package -- 功能说明: - - 中文:删除包 - - English:delete package -- 请求体 - 此接口请求体为空 -- 请求字段说明 - -| 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | -| ---------- | ------ | -------- | ------ | --------- | ------------------ | -| projectId | string | 是 | 无 | 项目名称 | project name | -| repoName | string | 是 | 无 | 仓库名称 | repo name | -| packageKey | string | 是 | 无 | 包唯一key | package unique key | - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": "" - } - ``` - -- record字段说明 - - 请求成功无返回数据 - - - -### 删除包版本 - -- API: DELETE /npm/ext/version/delete/{projectId}/{repoName}?packageKey=npm://helloworld&version=1.0.1 -- API 名称: delete_version -- 功能说明: - - - 中文:删除版本 - - English:delete version -- 请求体 - 此接口请求体为空 - -- 请求字段说明 - - | 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | - | ---------- | ------ | -------- | ------ | ---------- | ------------------ | - | projectId | string | 是 | 无 | 项目名称 | project name | - | repoName | string | 是 | 无 | 仓库名称 | repo name | - | packageKey | string | 是 | 无 | 包唯一key | package unique key | - | version | string | 是 | 无 | 包版本名称 | version name | - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": "" - } - ``` - -- record字段说明 - - 请求成功无返回数据 - diff --git a/docs/storage/apidoc/registry/rds.md b/docs/storage/apidoc/registry/rds.md deleted file mode 100644 index 2572e9c8676..00000000000 --- a/docs/storage/apidoc/registry/rds.md +++ /dev/null @@ -1,487 +0,0 @@ -## RDS节点接口说明 - -### 删除 rds包 - -* API: DELETE /rds/ext/package/delete/{project}/{repoName}/?packageKey={packageKey} - -* API 名称: delete_rds - -* 功能说明: - - - 中文:删除rds包, - - English:delete rds - -* 请求体 - 此接口请求体为空 - -* 请求字段说明 - - | 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | - | ---------- | ------ | -------- | ------ | --------- | ------------------ | - | projectId | string | 是 | 无 | 项目名称 | project name | - | repoName | string | 是 | 无 | 仓库名称 | repo name | - | packageKey | string | 是 | 无 | 包唯一key | package unique key | - -* 响应体 - - 成功 - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": "" - } - ``` - 失败 - ```json - { - "error": "remove package rds://chart failed: no such file or directory" - } - ``` - - -* data字段说明 - - - -### 删除对应版本rds包 - -* API: DELETE /rds/ext/version/delete/{project}/{repoName}/?packageKey={packageKey}&version={version} - -* API 名称: delete_rds_with_version - -* 功能说明: - - - 中文:删除对应版本rds包, - - English:delete rds with version - -* 请求体 - 此接口请求体为空 - -* 请求字段说明 - - | 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | - | ---------- | ------ | -------- | ------ | --------- | ------------------ | - | projectId | string | 是 | 无 | 项目名称 | project name | - | repoName | string | 是 | 无 | 仓库名称 | repo name | - | packageKey | string | 是 | 无 | 包唯一key | package unique key | - | version | string | 是 | 无 | 版本名称 | version name | - - -* 响应体 - - 成功 - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": "" - } - ``` - 失败 - ```json - { - "error": "remove package rds://chart failed: no such file or directory" - } - ``` - - -* data字段说明 - - -### 删除对应版本rds包 - -* API: DELETE /rds/{project}/{repoName}/api/charts/{name}/{version} -* API 名称: delete_rds_with_version - -* 功能说明: - - - 中文:删除对应版本rds包, - - English:delete rds with version - -* 请求体 - 此接口请求体为空 - -* 请求字段说明 - - | 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | - | ---------- | ------ | -------- | ------ | --------- | ------------------ | - | projectId | string | 是 | 无 | 项目名称 | project name | - | repoName | string | 是 | 无 | 仓库名称 | repo name | - | version | string | 是 | 无 | 版本名称 | version name | - | name | string | 是 | 无 | 包名称 | name | - - -* 响应体 - - 成功 - ```json - { - "deleted": true - } - ``` - 失败 - ```json - { - "error": "remove package rds://chart for version [1.0.0] failed: no such file or directory" - } - ``` - - - -* data字段说明 - - - -### 版本详情 - -* API: GET /rds/ext/version/detail/{project}/{repoName}/?packageKey={packageKey}&version={version} - -* API 名称: artifact_detail_detail - -* 功能说明: - - - 中文:rds 版本详情 - - English:artifact detail detail - -* 请求体 - 此接口请求体为空 - -* 请求字段说明 - - | 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | - | ---------- | ------ | -------- | ------ | --------- | ------------------ | - | projectId | string | 是 | 无 | 项目名称 | project name | - | repoName | string | 是 | 无 | 仓库名称 | repo name | - | packageKey | string | 是 | 无 | 包唯一key | package unique key | - | version | string | 是 | 无 | 版本名称 | version name | - -* 响应体 - - 成功 - ```json - { - "code": 0, - "message": null, - "data": { - "basic": { - "groupId": "com.tencent.bk.devops.atom", - "artifactId": "bksdk", - "version": "1.0.0", - "size": 42786, - "fullPath": "/com/tencent/bk/devops/atom/bksdk/1.0.0/bksdk-1.0.0.jar", - "lastModifiedBy": "anonymous", - "lastModifiedDate": "2020-09-27T14:43:06.083", - "downloadCount": 10, - "sha256": "e8e3e3b50daf0c2638a69e0b6ca3a1eee0b367bcabef5ae5bd7983700b9a6d58", - "md5": "358d9a0f68b641bf0a25289d1795022b", - "stageTag": [ - "@release" - ], - "description": null - }, - "metadata": {} - }, - "traceId": "" - } - ``` - 失败 - ```json - { - "error": "node [/chart-1.0.0.tgz] don't found." - } - ``` - -* data字段说明 - - | 字段 | 类型 | 说明 | Description | - | ---------------- | ------ | --------------------------- | ------------------------- | - | groupId | String | groupId | groupId | - | artifactId | String | artifactId | artifactId | - | version | String | version | version | - | size | long | 节点大小 | file size | - | fullPath | string | 节点完整路径 | node full path | - | folder | bool | 是否为文件夹 | is folder | - | sha256 | string | 节点sha256 | file sha256 | - | md5 | array | 节点md5 | file md5 checksum | - | stageTag | string | 晋级状态标签 | stage status tag | - | metadata | object | 节点元数据,key-value键值对 | node metadata | - | downloadCount | Int | 下载次数 | the download count of jar | - | lastModifiedBy | string | 上次修改者 | last modify user | - | lastModifiedDate | string | 上次修改时间 | last modify time | - | description | string | 描述信息 | description | - -## rds 包上传 - -- API: POST /api/{projectId}/{repoName}/charts - -- API 名称: rds 上传 - -- 功能说明: - - - 中文:rds 制品上传 - - English:rds chart push - -- 请求体: - - form-data : - - key: chart - - value: 文件 - -- 请求字段说明 - - | 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | - | --------- | ------ | -------- | ------ | ---------- | ------------ | - | projectId | string | 是 | 无 | 项目名称 | project name | - | repoName | string | 是 | 无 | 仓库名称 | repo name | - -- 响应体 - - 成功 - ```json - { - "saved": true - } - ``` - 失败 - ```json - { - "error": "chart-1.0.0.zip already exists" - } - ``` - -- data字段说明 - -### 获取索引index - -* API: GET /rds/{project}/{repoName}/index.yaml - -* API 名称: get index detail - -* 功能说明: - - - 中文:获取rds仓库下索引文件信息 - - English:get index detail - -* 请求体 - 此接口请求体为空 - -* 请求字段说明 - - | 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | - | ---------- | ------ | -------- | ------ | --------- | ------------------ | - | projectId | string | 是 | 无 | 项目名称 | project name | - | repoName | string | 是 | 无 | 仓库名称 | repo name | - -* 响应体 - 成功 - ``` - apiVersion: "v1" - entries: - 包名: - - name: "XXX" - code: "XXX" - version: "XXX" - description: "XXX" - home: "XXXX" - icon: "XXX" - digest: "XXX" - created: "XXX" - extension: "XXX" - keywords: - - "XXXX" - - "XXX" - - "XXX" - - "XXX" - maintainers: - - name: "XXXX" - email: "XXX" - rdsversion: "v1" - - name: "XXX" - code: "XXX" - version: "XXX" - description: "XXX" - home: "XXXX" - icon: "XXX" - digest: "XXX" - created: "XXX" - extension: "XXX" - keywords: - - "XXXX" - - "XXX" - - "XXX" - - "XXX" - maintainers: - - name: "XXXX" - email: "XXX" - rdsversion: "v1" - generated: "2022-03-21T15:42:47.176Z" - serverInfo: {} - ``` - 失败 - ```json - { - "error": "Repository [test-rds] not found" - } - ``` - - | 字段 | 类型 | 说明 | Description | - | ---------------- | ------ | --------------------------- | ------------------------- | - | apiVersion | String | apiVersion | apiVersion | - | entries | map | 包信息 | rds info | - | generated | String | 生成时间 | generated time | - - -entries中key 为包name, value为包含包多个版本的详情set - -### 获取特定包信息 - -* API: GET /rds/{project}/{repoName}/api/charts/{name}/{version} - -* API 名称: get rds list - -* 功能说明: - - - 中文:获取特定包信息 - - English: get rds list - -* 请求体 - 此接口请求体为空 - -* 请求字段说明 - - | 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | - | ---------- | ------ | -------- | ------ | --------- | ------------------ | - | projectId | string | 是 | 无 | 项目名称 | project name | - | repoName | string | 是 | 无 | 仓库名称 | repo name | - | name | string | 可选 | 无 | 包名 | name unique key | - | version | string | 可选 | 无 | 版本名称 | version name | - -* 响应体 - 当name与version不传,查询所有的包 - 成功 - ```json - { - "包名": [ - { - "name": "XXX", - "code": "XXX", - "version": "XXX", - "description": "XXX", - "home": "XXX", - "icon": "XXX", - "digest": "XXX", - "created": "XXX", - "extension": "zip", - "keywords": [ - "XXX", - "XXX", - "XXX", - "XXX" - ], - "maintainers": [ - { - "name": "XXX", - "email": "XXX" - } - ], - "rdsversion": "v1" - } - ] - } - ``` - 当version不传,查询指定name包的所有版本 - ```json - [ - { - "name": "XXX", - "code": "XXX", - "version": "XXX", - "description": "XXX", - "home": "XXX", - "icon": "XXX", - "digest": "XXX", - "created": "XXX", - "extension": "zip", - "keywords": [ - "XXX", - "XXX", - "XXX", - "XXX" - ], - "maintainers": [ - { - "name": "XXX", - "email": "XXX" - } - ], - "rdsversion": "v1" - } - ] - ``` - 查询指定name包的指定version版本 - ```json - { - "name": "XXX", - "code": "XXX", - "version": "XXX", - "description": "XXX", - "home": "XXX", - "icon": "XXX", - "digest": "XXX", - "created": "XXX", - "extension": "zip", - "keywords": [ - "XXX", - "XXX", - "XXX", - "XXX" - ], - "maintainers": [ - { - "name": "XXX", - "email": "XXX" - } - ], - "rdsversion": "v1" - } - ``` - 失败 - ```json - { - "error": "Repository [test-rds] not found" - } - ``` - - | 字段 | 类型 | 说明 | Description | - | ---------------- | ------ | --------------------------- | ------------------------- | - | apiVersion | String | apiVersion | apiVersion | - | entries | map | 包信息 | rds info | - | generated | String | 生成时间 | generated time | - - -entries中key 为包name, value为包含包多个版本的详情set - -## 下载文件 - -- API: GET /rds/{project}/{repoName}/charts/{filename} -- API 名称: download -- 功能说明: - - 中文:下载制品文件 - - English:download rds file - -- 请求体 - 此接口请求体为空 - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |project|string|是|无|项目名称|project name| - |repoName|string|是|无|仓库名称|repo name| - |filename|string|是|无|包名(格式为name-version.文件类型后缀)|file name| - -- 响应体 - [文件流] \ No newline at end of file diff --git a/docs/storage/apidoc/registry/rpm.md b/docs/storage/apidoc/registry/rpm.md deleted file mode 100644 index 323b8007edd..00000000000 --- a/docs/storage/apidoc/registry/rpm.md +++ /dev/null @@ -1,64 +0,0 @@ -### 创建仓库 - -- API: POST /repository/api/repo/create - -- API 名称: create_repo - -- 功能说明: - - - 中文:创建仓库 - - English:create repo - -- 请求体 - - ```json - { - "projectId": "test", - "name": "generic-local", - "type": "RPM", - "category": "COMPOSITE", - "public": false, - "description": "repo description", - "configuration": { - "settings": { - "enabledFileLists": false, - "repodataDepth": 0, - "groupXmlSet": [] - } - }, - "storageCredentialsKey": null - } - ``` - -- 请求字段说明 - - | 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | - | --------------------- | ------- | -------- | --------- | --------------------- | ----------------------- | - | projectId | string | 是 | 无 | 项目名称 | project name | - | name | string | 是 | 无 | 仓库名称 | repo name | - | type | string | 是 | 无 | 仓库类型,枚举值 | repo type | - | category | string | 否 | COMPOSITE | 仓库类别,枚举值 | repo category | - | public | boolean | 否 | false | 是否公开 | is public repo | - | description | string | 否 | 无 | 仓库描述 | repo description | - | configuration | object | 否 | 无 | 仓库配置,参考后文 | repo configuration | - | storageCredentialsKey | string | 否 | 无 | 存储凭证key | storage credentials key | - | enabledFileLists | Boolean | 是 | false | 是否启用filelists索引 | enabledFileLists | - | repodataDepth | Int | 是 | 0 | 索引目录深度 | repodataDepth | - | groupXmlSet | String | 否 | 无 | 分组文件列表 | groupXmlSet | - - - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": "" - } - ``` - -- data字段说明 - - 请求成功无返回数据 \ No newline at end of file diff --git a/docs/storage/apidoc/replication/cluster-node.md b/docs/storage/apidoc/replication/cluster-node.md deleted file mode 100644 index 7a905e7c4eb..00000000000 --- a/docs/storage/apidoc/replication/cluster-node.md +++ /dev/null @@ -1,458 +0,0 @@ -# Replication集群节点管理接口 - -[toc] - -## 创建集群节点 - -- API: POST /replication/api/cluster/create -- API 名称: create_cluster_node -- 功能说明: - - 中文:创建集群节点 - - English:create cluster node -- 请求体 - - ```json - { - "name": "shanghai", - "url": "http://bkrepo.xxx.com", - "certificate": null, - "username": "username", - "password": "password", - "type": "EDGE" - } - ``` - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |name|string|是|无|节点名称,长度不超过32位|cluster node name| - |url|string|是|无|节点url,符合URL统一规范|cluster node url| - |certificate|string|否|null|节点证书|cluster node certificate| - |username|string|否|null|节点认证用户名|cluster node username| - |password|string|否|null|节点认证密码|cluster node password| - |type|string|是|否|[CENTER,EDGE,STANDALONE]|cluster node type| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": null - } - ``` - -## 测试集群连通状态 - -- API: GET /replication/api/cluster/tryConnect -- API 名称: test_connect -- 功能说明: - - 中文:测试集群连通状态 - - English:test connect status - -- 请求体: - - ``` json - { - "name":"shanghai" - } - ``` - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |name|string|是|无|节点名称|cluster node name| - -- 响应体: - - ``` - { - "code": 0, - "message": null, - "data": null, - "traceId": null - } - ``` - -## 删除集群节点 - -- API: DELETE /replication/api/cluster/delete/{id} -- API 名称: delete_cluster_node -- 功能说明: - - 中文:删除集群节点 - - English:delete cluster node -- 请求体 - 此接口无请求体 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |id|string|是|无|节点唯一id|cluster node id| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": null - } - ``` - -## 校验集群节点是否存在 - -- API: GET /replication/api/cluster/exist?name=shanghai -- API 名称: check_cluster_exist -- 功能说明: - - 中文:校验集群节点是否存在 - - English:check cluster node exist -- 请求体 - 此接口无请求体 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |name|string|是|无|集群节点名称|cluster node name| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": true, - "traceId": null - } - ``` - -- data字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |data|boolean|集群节点是否存在|cluster node exist or not| - -## 根据id查询集群节点信息 - -- API: GET /replication/api/cluster/info/{id} -- API 名称: get_cluster_node_info -- 功能说明: - - 中文:查询集群节点详情 - - English:get cluster node info -- 请求体 - 此接口无请求体 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |id|string|是|无|集群id|cluster node id| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": { - "id":"609a57ddba727966d138c51e", - "name":"shanghai", - "status":"HEALTHY", - "errorReason":null, - "type":"EDGE", - "url":"http://backup.bkrepo.xxx.com", - "username":"admin", - "password":"password", - "certificate":null, - "createdBy" : "system", - "createdDate" : "2020-03-16T12:13:03.371", - "lastModifiedBy" : "system", - "lastModifiedDate" : "2020-03-16T12:13:03.371" - }, - "traceId": null - } - ``` - -- data字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |id|string|集群节点id|cluster node id| - |name|string|集群节点名称|cluster node name| - |status|enum|[HEALTHY,UNHEALTHY]|cluster node status| - |errorReason|string/集群状态问题错误原因|cluster node status failed reason| - |type|string|集群节点类型|cluster node type| - |url|string|集群节点url|cluster node url| - |username|string|集群节点用户名|cluster node username| - |password|string|集群节点密码|cluster node password| - |certificate|string|集群节点证书|cluster node certificate| - |createdBy|string|创建者|create user| - |createdDate|string|创建时间|create time| - |lastModifiedBy|string|上次修改者|last modify user| - |lastModifiedDate|string|上次修改时间|last modify time| - -## 根据name查询集群节点信息 - -- API: GET /replication/api/cluster/info?name=shanghai -- API 名称: get_cluster_node_info -- 功能说明: - - 中文:查询集群节点详情 - - English:get cluster node info -- 请求体 - 此接口无请求体 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |name|string|是|无|集群节点名称|cluster node name| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": { - "id":"609a57ddba727966d138c51e", - "name":"shanghai", - "status":"HEALTHY", - "errorReason":null, - "type":"EDGE", - "url":"http://backup.bkrepo.xxx.com", - "username":"admin", - "password":"password", - "certificate":null, - "createdBy" : "system", - "createdDate" : "2020-03-16T12:13:03.371", - "lastModifiedBy" : "system", - "lastModifiedDate" : "2020-03-16T12:13:03.371" - }, - "traceId": null - } - ``` - -- data字段说明 - - 同上 - -## 获取中心节点 - -- API: GET /replication/api/cluster/info/center -- API 名称: get_center_cluster_node_info -- 功能说明: - - 中文:查询集群节点详情 - - English:get center cluster node info -- 请求体 - 此接口无请求体 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |name|string|是|无|集群节点名称|cluster node name| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": { - "id":"609a57ddba727966d138c51e", - "name":"shanghai", - "status":"HEALTHY", - "errorReason":null, - "type":"CENTER", - "url":"http://backup.bkrepo.xxx.com", - "username":"admin", - "password":"password", - "certificate":null, - "createdBy" : "system", - "createdDate" : "2020-03-16T12:13:03.371", - "lastModifiedBy" : "system", - "lastModifiedDate" : "2020-03-16T12:13:03.371" - }, - "traceId": null - } - ``` - -- data字段说明 - - 同上 - -## 查询边缘节点列表 - -- API: GET /replication/api/cluster/list/edge -- API 名称: get_edge_cluster_node_list -- 功能说明: - - 中文:查询集群节点详情 - - English:get edge cluster node list -- 请求体 - 此接口无请求体 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |name|string|是|无|集群节点名称|cluster node name| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": [ - { - "id":"609a57ddba727966d138c51e", - "name":"shanghai", - "status":"HEALTHY", - "errorReason":null, - "type":"CENTER", - "url":"http://backup.bkrepo.xxx.com", - "username":"admin", - "password":"password", - "certificate":null, - "createdBy" : "system", - "createdDate" : "2020-03-16T12:13:03.371", - "lastModifiedBy" : "system", - "lastModifiedDate" : "2020-03-16T12:13:03.371" - } - ], - "traceId": null - } - ``` - -- data字段说明 - - 同上 - -## 列表查询集群节点 - -- API: GET /replication/api/cluster/list?name=shanghai&type=EDGE -- API 名称: list_cluster_node -- 功能说明: - - 中文:列表查询集群节点 - - English:list cluster node -- 请求体 - 此接口无请求体 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |name|string|否|无|集群节点名称|cluster name| - |type|string|否|无|集群节点类型,枚举值|cluster type| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": [ - { - "id":"609a57ddba727966d138c51e", - "name":"shanghai", - "status":"HEALTHY", - "errorReason":null, - "type":"EDGE", - "url":"http://backup.bkrepo.xxx.com", - "username":"admin", - "password":"password", - "certificate":null, - "createdBy" : "system", - "createdDate" : "2020-03-16T12:13:03.371", - "lastModifiedBy" : "system", - "lastModifiedDate" : "2020-03-16T12:13:03.371" - } - ], - "traceId": null - } - ``` - -- data字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |id|string|集群节点id|cluster node id| - |name|string|集群节点名称|cluster node name| - |status|enum|[HEALTHY,UNHEALTHY]|cluster node status| - |errorReason|string/集群状态问题错误原因|cluster node status failed reason| - |type|string|集群节点类型|cluster node type| - |url|string|集群节点url|cluster node url| - |username|string|集群节点用户名|cluster node username| - |password|string|集群节点密码|cluster node password| - |certificate|string|集群节点证书|cluster node certificate| - |createdBy|string|创建者|create user| - |createdDate|string|创建时间|create time| - |lastModifiedBy|string|上次修改者|last modify user| - |lastModifiedDate|string|上次修改时间|last modify time| - -## 分页列表查询集群节点 - -- API: GET /replication/api/cluster/page?name=shanghai&type=EDGE -- API 名称: list_cluster_node_page -- 功能说明: - - 中文:分页列表查询集群节点 - - English:list cluster node page -- 请求体 - 此接口无请求体 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |pageNumber|int|是|无|当前页|page number| - |pageSize|int|是|无|分页数量|page size| - |name|string|否|无|集群节点名称|cluster name| - |type|string|否|无|[EDGE,CENTER,STANDALONE]|cluster type| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": { - "pageNumber": 0, - "pageSize": 1, - "totalRecords": 18, - "totalPages": 2, - "records": [ - { - "id":"609a57ddba727966d138c51e", - "name":"shanghai", - "status":"HEALTHY", - "errorReason":null, - "type":"EDGE", - "url":"http://backup.bkrepo.xxx.com", - "username":"admin", - "password":"password", - "certificate":null, - "createdBy" : "system", - "createdDate" : "2020-03-16T12:13:03.371", - "lastModifiedBy" : "system", - "lastModifiedDate" : "2020-03-16T12:13:03.371" - } - ] - }, - "traceId": null - } - ``` - -- data字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |id|string|集群节点id|cluster node id| - |name|string|集群节点名称|cluster node name| - |status|enum|[HEALTHY,UNHEALTHY]|cluster node status| - |errorReason|string/集群状态问题错误原因|cluster node status failed reason| - |type|string|集群节点类型|cluster node type| - |url|string|集群节点url|cluster node url| - |username|string|集群节点用户名|cluster node username| - |password|string|集群节点密码|cluster node password| - |certificate|string|集群节点证书|cluster node certificate| - |createdBy|string|创建者|create user| - |createdDate|string|创建时间|create time| - |lastModifiedBy|string|上次修改者|last modify user| - |lastModifiedDate|string|上次修改时间|last modify time| diff --git a/docs/storage/apidoc/replication/record.md b/docs/storage/apidoc/replication/record.md deleted file mode 100644 index 64f993f50c7..00000000000 --- a/docs/storage/apidoc/replication/record.md +++ /dev/null @@ -1,322 +0,0 @@ -# Replication仓库同步执行日志接口 - -[toc] - -## 根据recordId查询任务执行日志 - -- API: GET /replication/api/task/record/{recordId} -- API 名称: get_task_record -- 功能说明: - - 中文:查询任务信息 - - English:get task record -- 请求体 - 此接口无请求体 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |recordId|string|是|无|记录唯一key|record id| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": { - "replicaObjectType": "REPOSITORY", - "record": { - "id": "609b573d53ccce752bf9b860", - "taskKey": "651095dfe0524ce9b3ab53d13532361c", - "status": "SUCCESS", - "startTime": "2021-05-12T12:19:08.813", - "endTime": "2021-05-12T12:19:37.967", - "errorReason": null - } - }, - "traceId": null - } - ``` - -- data字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |replicaObjectType|enum|[REPOSITORY,PACKAGE,PATH]|replica object type| - |id|string|执行日志唯一id|record id| - |taskKey|string|任务唯一key|task key| - |status|enum|[RUNNING,SUCCESS,FAILED]|task status| - |startTime|date|任务开始执行时间|task execute start time| - |endTime|date|任务结束执行时间|task execute end time| - |errorReason|string|错误原因,未执行或执行成功则为null|task failed error reason| - -## 根据key查询任务执行日志列表 - -- API: GET /replication/api/task/record/list/{key} -- API 名称: list_task_record -- 功能说明: - - 中文:查询任务信息列表 - - English:list task record -- 请求体 - 此接口无请求体 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |key|string|是|无|任务唯一key|task key| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": [ - { - "id": "609b573d53ccce752bf9b860", - "taskKey": "651095dfe0524ce9b3ab53d13532361c", - "status": "SUCCESS", - "startTime": "2021-05-12T12:19:08.813", - "endTime": "2021-05-12T12:19:37.967", - "errorReason": null - } - ], - "traceId": null - } - ``` - -- data字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |id|string|执行日志唯一id|record id| - |taskKey|string|任务唯一key|task key| - |status|enum|[RUNNING,SUCCESS,FAILED]|task status| - |startTime|date|任务开始执行时间|task execute start time| - |endTime|date|任务结束执行时间|task execute end time| - |errorReason|string|错误原因,未执行或执行成功则为null|task failed error reason| - -## 根据key分页查询任务执行日志列表 - -- API: GET /replication/api/task/record/page/{key} -- API 名称: list_task_record_page -- 功能说明: - - 中文:分页查询任务日志列表 - - English:list task record page -- 请求体 - 此接口无请求体 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |key|string|是|无|任务唯一id|task id| - |pageNumber|int|是|无|当前页|page number| - |pageSize|int|是|无|分页数量|page size| - |status|enum|否|无|执行状态|execute status| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": { - "pageNumber": 0, - "pageSize": 1, - "totalRecords": 8, - "totalPages": 2, - "records": [ - { - "id": "609b573d53ccce752bf9b860", - "taskKey": "651095dfe0524ce9b3ab53d13532361c", - "status": "SUCCESS", - "startTime": "2021-05-12T12:19:08.813", - "endTime": "2021-05-12T12:19:37.967", - "errorReason": null - } - ] - }, - "traceId": null - } - ``` - -- data字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |id|string|执行日志唯一id|record id| - |taskKey|string|任务唯一key|task key| - |status|enum|[RUNNING,SUCCESS,FAILED]|task status| - |startTime|date|任务开始执行时间|task execute start time| - |endTime|date|任务结束执行时间|task execute end time| - |errorReason|string|错误原因,未执行或执行成功则为null|task failed error reason| - - -## 根据recordId查询任务执行日志详情列表 - -- API: GET /replication/api/task/record/detail/list/{recordId} -- API 名称: list_task_record_detail -- 功能说明: - - 中文:查询任务日志详情列表 - - English:list task record detail -- 请求体 - 此接口无请求体 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |recordId|string|是|无|任务执行日志唯一id|record id| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": [ - { - "id": "979b573d53efcd752bf9b762", - "recordId": "609b573d53ccce752bf9b860", - "localCluster": "651095dfe0524ce9b3ab53d13532361c", - "remoteCluster": "SUCCESS", - "localRepoName": "npm-local", - "repoType": "NPM", - "packageConstraint": { - "packageKey": "npm://helloworld", - "versions": ["1.1.0","1.3.0"] - }, - "pathConstraint": null, - "status": "SUCCESS", - "progress": { - "success": 10, - "skip": 0, - "failed": 0, - "totalSize": 100 - }, - "startTime": "2021-05-12T12:19:08.813", - "endTime": "2021-05-12T12:19:37.967", - "errorReason": null - } - ], - "traceId": null - } - ``` - -- data字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |id|string|记录详情唯一id|record detail id| - |recordId|string|记录唯一id|record id| - |localCluster|string|本地集群名称|local cluster node name| - |remoteCluster|string|远程集群名称|remote cluster node name| - |localRepoName|string|本地仓库名称|local repository name| - |repoType|enum|[DOCKER,NPM,RPM,...]|local repository type| - |packageConstraints|object|否|无|包限制|package constraints| - |pathConstraints|object|否|无|路径限制|path constraints| - |status|enum|[RUNNING,SUCCESS,FAILED]|task execute status| - |progress|object|同步进度|task execute progress| - |startTime|date|任务开始执行时间|task execute start time| - |endTime|date|任务结束执行时间|task execute end time| - |errorReason|string|错误原因,未执行或执行成功则为null|task failed error reason| - -- progress字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |success|long|成功数量|success size| - |skip|long|跳过数量|skip size| - |failed|long|失败数量|failed size| - |totalSize|long|数据总量|total size| - -## 根据recordId分页查询任务执行日志详情列表 - -- API: GET /replication/api/task/record/detail/page/{recordId} -- API 名称: list_task_record_detail_page -- 功能说明: - - 中文:分页查询任务日志详情列表 - - English:list task record detail page -- 请求体 - 此接口无请求体 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |recordId|string|是|无|任务执行日志唯一id|record id| - |pageNumber|int|是|无|当前页|page number| - |pageSize|int|是|无|分页数量|page size| - |packageName|string|否|无|包名称,支持前缀模糊匹配|package name| - |repoName|string|否|无|仓库名称|repo name| - |clusterName|string|否|无|远程节点名称|cluster node name| - |path|string|否|无|路径名称,支持前缀模糊匹配|file path| - |status|enum|否|无|[SUCCESS,RUNNING,FAILED]|execute status| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": { - "pageNumber": 0, - "pageSize": 1, - "totalRecords": 18, - "totalPages": 2, - "records": [ - { - "id": "979b573d53efcd752bf9b762", - "recordId": "609b573d53ccce752bf9b860", - "localCluster": "wuxi", - "remoteCluster": "wuhan", - "localRepoName": "npm-local", - "repoType": "NPM", - "packageConstraint": { - "packageKey": "npm://helloworld", - "versions": ["1.1.0","1.3.0"] - }, - "pathConstraint": { - "path": "/busy/box.txt" - }, - "status": "SUCCESS", - "progress": { - "success": 10, - "skip": 0, - "failed": 0, - "totalSize": 10 - }, - "startTime": "2021-05-12T12:19:08.813", - "endTime": "2021-05-12T12:19:37.967", - "errorReason": null - } - ] - }, - "traceId": null - } - ``` - -- data字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |id|string|记录详情唯一id|record detail id| - |recordId|string|记录唯一id|record id| - |localCluster|string|本地集群名称|local cluster node name| - |remoteCluster|string|远程集群名称|remote cluster node name| - |localRepoName|string|本地仓库名称|local repository name| - |repoType|enum|[DOCKER,NPM,RPM,...]|local repository type| - |packageConstraints|object|否|无|包限制|package constraints| - |pathConstraints|object|否|无|路径限制|path constraints| - |status|enum|[RUNNING,SUCCESS,FAILED]|task execute status| - |progress|object|同步进度|task execute progress| - |startTime|date|任务开始执行时间|task execute start time| - |endTime|date|任务结束执行时间|task execute end time| - |errorReason|string|错误原因,未执行或执行成功则为null|task failed error reason| - -- progress字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |success|long|成功数量|success size| - |skip|long|跳过数量|skip size| - |failed|long|失败数量|failed size| - |totalSize|long|数据总量|total size| diff --git a/docs/storage/apidoc/replication/replication.md b/docs/storage/apidoc/replication/replication.md deleted file mode 100644 index 131649110ac..00000000000 --- a/docs/storage/apidoc/replication/replication.md +++ /dev/null @@ -1,594 +0,0 @@ -# Replication仓库同步接口 - -[toc] - -## 创建集群同步任务 - -- API: POST /replication/api/task/create -- API 名称: create_replication_task -- 功能说明: - - 中文:创建集群同步任务 - - English:create replication task -- 请求体: - - ```json - { - "name": "计划", - "localProjectId": "bkrepo", - "replicaObjectType": "REPOSITORY", - "replicaTaskObjects": [ - { - "localRepoName": "maven-local", - "remoteProjectId": "bkrepo", - "remoteRepoName": "maven-local", - "repoType": "MAVEN", - "packageConstraints": [ - { - "packageKey": "gav://com.alibaba:fastjson", - "versions": ["1.2.47","1.2.48"] - } - ], - "pathConstraints": [] - } - ], - "replicaType": "SCHEDULED", - "setting": { - "rateLimit": 0, - "includeMetadata": true, - "conflictStrategy": "SKIP", - "errorStrategy": "CONTINUE", - "executionStrategy": "IMMEDIATELY", - "executionPlan": { - "executeImmediately": true - } - }, - "remoteClusterIds": ["651095dfe0524ce9b3ab53d13532361c","329fbcda45944fb9ae5c2573acd7bd2a"], - "enabled": true, - "description": "test replica task" - } - ``` - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |name|string|是|无|计划名称|replication name| - |localProjectId|string|是|无|本地项目ID|the local project Id| - |replicaObjectType|enum|是|无|[REPOSITORY,PACKAGE,PATH]|replication object type| - |replicaTaskObjects|object|是|无|同步对象信息|replication object info| - |replicaType|enum|是|SCHEDULED|[SCHEDULED,REAL_TIME]|replication type| - |setting|object|是|无|计划相关设置|task setting| - |remoteClusterIds|list|是|无|远程集成节点id|the remote cluster node ids| - |enabled|bool|是|true|计划是否启动|do task enabled| - |description|sting|否|无|描述|description| - -- replicaTaskObjects对象说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |localRepoName|string|是|无|本地仓库名称|the local repoName| - |remoteProjectId|string|是|无|远程项目id|the remote project Id| - |remoteRepoName|string|是|无|远程仓库名称|the remote repoName| - |repoType|enum|是|无|[DOCKER,MAVEN,NPM, ...]|repository type| - |packageConstraints|list|否|无|包限制|package constraints| - |pathConstraints|list|否|无|路径限制|path constraints| - -- setting对象说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |rateLimit|long|是|0|分发限速|rate limit| - |includeMetadata|bool|是|true|是否同步元数据|do include metadata| - |conflictStrategy|enum|是|SKIP|[SKIP,OVERWRITE,FAST_FAIL]|conflict strategy| - |errorStrategy|enum|是|CONTINUE|[CONTINUE,FAST_FAIL]|error strategy| - |executionStrategy|enum|是|IMMEDIATELY|[IMMEDIATELY,SPECIFIED_TIME,CRON_EXPRESSION]|execution strategy| - |executionPlan|object|是|无|调度策略|execution plan| - -- executionPlan对象说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |executeImmediately|bool|是|true|立即执行|execute immediately| - |executeTime|time|否|无|执行时间执行|execute time| - |cronExpression|string|否|无|cron表达式执行|cron expression| - - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": { - "id": "609b573353ccce752bf9b85f", - "key": "784e49c5ba974a1e8ac503a840f65eb5", - "name": "测试分发计划", - "projectId": "bkrepo", - "replicaObjectType": "REPOSITORY", - "replicaType": "SCHEDULED", - "setting": { - "rateLimit": 0, - "includeMetadata": true, - "conflictStrategy": "SKIP", - "errorStrategy": "CONTINUE", - "executionStrategy": "IMMEDIATELY", - "executionPlan": { - "executeImmediately": true - } - }, - "remoteClusters": [ - { - "id": "651095dfe0524ce9b3ab53d13532361c", - "name": "shanghai" - }, - { - "id": "329fbcda45944fb9ae5c2573acd7bd2a", - "name": "beijing" - } - ], - "description": "for test", - "lastExecutionStatus": "SUCCESS", - "lastExecutionTime": "2020-03-16T12:00:00.000", - "nextExecutionTime": "2020-03-17T12:00:00.000", - "executionTimes": 5, - "enabled": true, - "createdBy" : "system", - "createdDate" : "2020-03-16T12:13:03.371", - "lastModifiedBy" : "system", - "lastModifiedDate" : "2020-03-16T12:13:03.371" - }, - "traceId": null - } - ``` - -## 根据key查询任务信息 - -- API: GET /replication/api/task/info/{key} -- API 名称: get_task_info -- 功能说明: - - 中文:查询任务信息 - - English:get task info -- 请求体 - 此接口无请求体 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |key|string|是|无|任务唯一key|task key| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": { - "id": "609b573353ccce752bf9b85f", - "key": "784e49c5ba974a1e8ac503a840f65eb5", - "name": "测试分发计划", - "projectId": "bkrepo", - "replicaObjectType": "REPOSITORY", - "replicaType": "SCHEDULED", - "setting": { - "rateLimit": 0, - "includeMetadata": true, - "conflictStrategy": "SKIP", - "errorStrategy": "CONTINUE", - "executionStrategy": "IMMEDIATELY", - "executionPlan": { - "executeImmediately": true - } - }, - "remoteClusters": [ - { - "id": "651095dfe0524ce9b3ab53d13532361c", - "name": "shanghai" - }, - { - "id": "329fbcda45944fb9ae5c2573acd7bd2a", - "name": "beijing" - } - ], - "description": "for test", - "lastExecutionStatus": "SUCCESS", - "lastExecutionTime": "2020-03-16T12:00:00.000", - "nextExecutionTime": "2020-03-17T12:00:00.000", - "executionTimes": 5, - "enabled": true, - "createdBy" : "system", - "createdDate" : "2020-03-16T12:13:03.371", - "lastModifiedBy" : "system", - "lastModifiedDate" : "2020-03-16T12:13:03.371" - }, - "traceId": null - } - ``` - -- data字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |id|string|任务唯一id|task id| - |key|string|任务唯一key|task key| - |name|string|任务名称|task name| - |projectId|string/所属项目id|task projectId| - |replicaObjectType|enum|是|无|[REPOSITORY,PACKAGE,PATH]|replication object type| - |replicaType|enum|[SCHEDULED,REAL_TIME]|replica type| - |setting|object|计划相关设置|task setting| - |remoteClusters|set|远程集成节点信息|the remote cluster node info| - |description|string|任务描述信息|task description| - |lastExecutionStatus|enum|[RUNNING,SUCCESS,FAILED]|task last execution status| - |lastExecutionTime|date|上次执行时间|task last execution time| - |nextExecutionTime|date|下次执行时间|task next execution time| - |executionTimes|long|执行次数|execution times| - |enabled|bool|是|true|计划是否启动|do task enabled| - |createdBy|string|创建者|create user| - |createdDate|string|创建时间|create time| - |lastModifiedBy|string|上次修改者|last modify user| - |lastModifiedDate|string|上次修改时间|last modify time| - -## 根据key查询任务详情 - -- API: GET /replication/api/task/detail/{key} -- API 名称: get_task_detail -- 功能说明: - - 中文:查询任务信息 - - English:get task detail -- 请求体 - 此接口无请求体 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |key|string|是|无|任务唯一key|task key| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": { - "task": { - "id": "609b573353ccce752bf9b85f", - "key": "784e49c5ba974a1e8ac503a840f65eb5", - "name": "测试分发计划", - "projectId": "bkrepo", - "replicaObjectType": "REPOSITORY", - "replicaType": "SCHEDULED", - "setting": { - "rateLimit":0, - "includeMetadata":true, - "conflictStrategy": "SKIP", - "errorStrategy": "CONTINUE", - "executionStrategy": "IMMEDIATELY", - "executionPlan":{ - "executeImmediately":true - } - }, - "remoteClusters": [ - { - "id": "651095dfe0524ce9b3ab53d13532361c", - "name": "shanghai" - }, - { - "id": "329fbcda45944fb9ae5c2573acd7bd2a", - "name": "beijing" - } - ], - "description": "for test", - "lastExecutionStatus": "SUCCESS", - "lastExecutionTime": "2020-03-16T12:00:00.000", - "nextExecutionTime": "2020-03-17T12:00:00.000", - "executionTimes": 5, - "enabled": true, - "createdBy" : "system", - "createdDate" : "2020-03-16T12:13:03.371", - "lastModifiedBy" : "system", - "lastModifiedDate" : "2020-03-16T12:13:03.371" - }, - "objects": [ - { - "localRepoName": "npm-local", - "remoteProjectId": "bkrepo", - "remoteRepoName": "npm-local", - "repoType": "NPM", - "packageConstraints": [ - { - "packageKey": "npm://helloworld", - "versions": ["1.0.0","1.0.1"] - } - ], - "pathConstraints": [] - } - ] - }, - "traceId": null - } - ``` - -- data字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |task|object|同步任务基础信息|task info| - |objects|list|同步对象列表|task objects| - -- task字段说明 - 同上 - -- objects字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |localRepoName|string|本地仓库名称|local repo name| - |remoteProjectId|string|远程项目id|remote project id| - |remoteRepoName|string|远程仓库名称|remote repo name| - |repoType|enum|[MAVEN,DOCKER,NPM,...]|local repo type| - |packageConstraints|list|包限制|package constraints| - |pathConstraints|list|路径限制|path constraints| - -## 分页查询任务 - -- API: GET /replication/api/task/page/{projectId}?name=test&lastExecutionStatus=SUCCESS&enabled=true&sortType=CREATE_TIME&pageNumber=0&pageSize=20 -- API 名称: list_task_page -- 功能说明: - - 中文:分页查询任务 - - English:list task page -- 请求体 - 此接口无请求体 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目id|project id| - |name|string|否|无|任务名称,支持前缀模糊匹配|task name| - |lastExecutionStatus|enum|否|无|上次执行状态|last execution status| - |enabled|bool|否|无|任务启停状态|do task enabled| - |sortType|enum|否|CREATED_TIME|[CREATED_TIME,LAST_EXECUTION_TIME,NEXT_EXECUTION_TIME]|sort by time| - |pageNumber|int|是|无|当前页|page number| - |pageSize|int|是|无|分页数量|page size| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": { - "pageNumber": 0, - "pageSize": 1, - "totalRecords": 18, - "totalPages": 2, - "records": [ - { - "id": "609b573353ccce752bf9b85f", - "key": "784e49c5ba974a1e8ac503a840f65eb5", - "name": "testTask", - "projectId": "bkrepo", - "replicaObjectType": "REPOSITORY", - "replicaType": "SCHEDULED", - "setting": { - "rateLimit":0, - "includeMetadata":true, - "conflictStrategy": "SKIP", - "errorStrategy": "CONTINUE", - "executionStrategy": "IMMEDIATELY", - "executionPlan": { - "executeImmediately":true - } - }, - "remoteClusters": [ - { - "id": "651095dfe0524ce9b3ab53d13532361c", - "name": "shanghai" - }, - { - "id": "329fbcda45944fb9ae5c2573acd7bd2a", - "name": "beijing" - } - ], - "description": "for test", - "lastExecutionStatus": "SUCCESS", - "lastExecutionTime": "2020-03-16T12:00:00.000", - "nextExecutionTime": "2020-03-17T12:00:00.000", - "executionTimes": 5, - "enabled": true, - "createdBy" : "system", - "createdDate" : "2020-03-16T12:13:03.371", - "lastModifiedBy" : "system", - "lastModifiedDate" : "2020-03-16T12:13:03.371" - } - ] - }, - "traceId": null - } - ``` - -- data字段说明 - - 同上 - -## 删除任务 - -- API: DELETE /replication/api/task/delete/{key} -- API 名称: delete_task -- 功能说明: - - 中文:删除任务 - - English:delete task -- 请求体 - 此接口无请求体 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |key|string|是|无|任务唯一key|task key| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": null - } - ``` - -## 任务启停状态切换 - -- API: POST /replication/api/task/toggle/status/{key} -- API 名称: toggle_status_task -- 功能说明: - - 中文:任务启停状态切换 - - English:task toggle status -- 请求体 - 此接口无请求体 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |key|string|是|无|任务唯一key|task key| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": null - } - ``` - -## 复制集群同步任务 - -- API: POST /replication/api/task/copy -- API 名称: copy_replication_task -- 功能说明: - - 中文:复制集群同步任务 - - English:copy replication task -- 请求体: - - ```json - { - "name": "task_copy", - "key": "e8d095dfe0524ce9b3ab53d1353239h8", - "description": "copy replica task" - } - ``` - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |name|string|是|无|计划名称|replication name| - |key|string|是|无|任务唯一key|task unique key| - |description|sting|否|无|描述|description| - -- 响应体 - - ``` - { - "code": 0, - "message": null, - "data": null, - "traceId": null - } - ``` - -## 更新同步任务 - -- API: POST /replication/api/task/update -- API 名称: update_replication_task -- 功能说明: - - 中文:更新集群同步任务 - - English:update replication task -- 请求体: - - ```json - { - "key": "计划唯一key", - "name": "更新后的名称", - "localProjectId": "bkrepo", - "replicaObjectType": "REPOSITORY", - "replicaTaskObjects": [ - { - "localRepoName": "maven-local", - "remoteProjectId": "bkrepo", - "remoteRepoName": "maven-local", - "repoType": "MAVEN", - "packageConstraints": [ - { - "packageKey": "gav://com.alibaba:fastjson", - "versions": ["1.2.47","1.2.48"] - } - ], - "pathConstraints": [] - } - ], - "remoteClusterIds": ["651095dfe0524ce9b3ab53d13532361c","329fbcda45944fb9ae5c2573acd7bd2a"], - "description": "test replica task" - } - ``` - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |key|string|是|否|唯一key|replication task key| - |name|string|是|无|计划名称|replication name| - |localProjectId|string|是|无|本地项目ID|the local project Id| - |replicaObjectType|enum|是|无|[REPOSITORY,PACKAGE,PATH]|replication object type| - |replicaTaskObjects|object|是|无|同步对象信息|replication object info| - |remoteClusterIds|list|是|无|远程集成节点id|the remote cluster node ids| - |description|sting|否|无|描述|description| - -- replicaTaskObjects对象说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |localRepoName|string|是|无|本地仓库名称|the local repoName| - |remoteProjectId|string|是|无|远程项目id|the remote project Id| - |remoteRepoName|string|是|无|远程仓库名称|the remote repoName| - |repoType|enum|是|无|[DOCKER,MAVEN,NPM, ...]|repository type| - |packageConstraints|list|否|无|包限制|package constraints| - |pathConstraints|list|否|无|路径限制|path constraints| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": null - } - ``` - -## 手动执行同步任务 - -- API: POST /replication/api/task/execute/{key} -- API 名称: execute_replication_task -- 功能说明: - - 中文:手动执行集群同步任务 - - English:execute replication task -- 请求体: - 此接口无请求体 - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |key|string|是|否|唯一key|replication task key| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": null - } - ``` diff --git a/docs/storage/apidoc/repo/project.md b/docs/storage/apidoc/repo/project.md deleted file mode 100644 index 5b74da9bab7..00000000000 --- a/docs/storage/apidoc/repo/project.md +++ /dev/null @@ -1,81 +0,0 @@ -# Project项目接口 - -[toc] - -## 创建仓库 - -- API: POST /repository/api/project/create -- API 名称: create_project -- 功能说明: - - 中文:创建项目 - - English:create project -- 请求体 - - ```json - { - "name": "test", - "displayName": "test", - "description": "project description" - } - ``` - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |name|string|是|无|项目名称,要求以字母或者下划线开头,长度不超过32位|proejct name| - |displayName|string|是|无|显示名称,要求以字母或者下划线开头,长度不超过32位。此字段保留作用,和name设置为相同值即可|project display name| - |description|string|是|无|项目描述|project description| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": null - } - ``` - -## 查询项目列表 - -- API: GET /repository/api/project/list -- API 名称: get_project_list -- 功能说明: - - 中文:查询项目列表 - - English:get project list -- 请求体 - 此接口请求体为空 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |names|string|否|无|项目名称,多个以,隔开|project name| - |displayNames|string|否|无|显示名称,多个以,隔开|project display name| - |pageSize|int|否|无|分页数量|page size| - |pageNumber|int|否|无|当前页|page number| -- 响应体 - - ``` json - { - "code":0, - "message":"", - "data":[ - { - "name":"project1", - "displayName":"project1", - "description":"project1" - } - ], - "traceId": null - } - ``` - -- data 字段说明 - - | 字段|类型|说明|Description| - |---|---|---|---| - |name|string|项目名|the project name | - |displayName|string|项目展示名称|the display name of project| - |description|string|项目描述|the description of project| diff --git a/docs/storage/apidoc/repo/proxy-channel.md b/docs/storage/apidoc/repo/proxy-channel.md deleted file mode 100644 index 1acf75fdc23..00000000000 --- a/docs/storage/apidoc/repo/proxy-channel.md +++ /dev/null @@ -1,46 +0,0 @@ -# ProxyChannel代理源接口 - -[toc] - -## 查询公有源列表 - -- API: GET /repository/api/proxy-channel/list/public/{repoType} -- API 名称: list_public_proxy_channel -- 功能说明: - - 中文:列表查询公有源 - - English:list puiblic proxy channel -- 请求体 - 此接口无请求体 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |repoType|string|是|无|仓库类型,枚举值|repo type| - -- 响应体 - - ```json - { - "code" : 0, - "message" : null, - "data" : [ { - "id" : "5f48b52fdf23460c0e2251e9", - "public" : true, - "name" : "maven-center", - "url" : "http://http://center.maven.com", - "repoType" : "MAVEN" - } ], - "traceId" : null - } - ``` - -- data字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |id|string|代理源id|proxy channel id| - |public|boolean|是否为公有源|is public channel| - |name|string|代理源名称|repo name| - |url|string|代理源url|repo category| - |repoType|string|仓库类型|repo type| - diff --git a/docs/storage/apidoc/repo/repository.md b/docs/storage/apidoc/repo/repository.md deleted file mode 100644 index fcc9f0b2cb2..00000000000 --- a/docs/storage/apidoc/repo/repository.md +++ /dev/null @@ -1,556 +0,0 @@ -# Repository仓库接口 - -[toc] - -## 创建仓库 - -- API: POST /repository/api/repo/create -- API 名称: create_repo -- 功能说明: - - 中文:创建仓库 - - English:create repo -- 请求体 - - ```json - { - "projectId": "test", - "name": "generic-local", - "type": "GENERIC", - "category": "LOCAL", - "public": false, - "description": "repo description", - "configuration": null, - "storageCredentialsKey": null, - "quota": 1024 - } - ``` - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |name|string|是|无|仓库名称|repo name| - |type|string|是|无|仓库类型,枚举值|repo type| - |category|string|否|COMPOSITE|仓库类别,枚举值|repo category| - |public|boolean|否|false|是否公开|is public repo| - |description|string|否|无|仓库描述|repo description| - |configuration|object|否|无|仓库配置,参考后文|repo configuration| - |storageCredentialsKey|string|否|无|存储凭证key|storage credentials key| - |quota|long|否|无|仓库配额|repo quota| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": null - } - ``` - - -## 更新仓库信息 - -- API: POST /repository/api/repo/update/{projectId}/{repoName} -- API 名称: update_repo -- 功能说明: - - 中文:更新仓库信息 - - English:update repo -- 请求体 - ```json - { - "public": false, - "description": "repo description", - "configuration": null - } - ``` - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |repoName|string|是|无|仓库名称|repo name| - |public|boolean|否|无|是否公开。null则不修改|is public repo| - |description|string|否|无|仓库描述。null则不修改|repo description| - |configuration|RepositoryConfiguration|否|无|仓库配置,参考后文。null则不修改|repo configuration| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": null - } - ``` - -## 删除仓库 - -- API: DELETE /repository/api/repo/delete/{projectId}/{repoName}?forced=false -- API 名称: delete_repo -- 功能说明: - - 中文:删除仓库 - - English:delete repo - -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |repoName|string|是|无|仓库名称|repo name| - |forced|boolean|否|false|是否强制删除。如果为false,当仓库中存在文件时,将无法删除仓库|force to delete repo| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": null - } - ``` - -## 查询仓库信息 - -- API: GET /repository/api/repo/info/{projectId}/{repoName}/{type} -- API 名称: get_repo_info -- 功能说明: - - 中文:查询仓库详情 - - English:get repo info -- 请求体 - 此接口无请求体 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |repoName|string|是|无|仓库名称|repo name| - |type|string|否|无|仓库类型|repo type| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": { - "projectId" : "test", - "name" : "local", - "type" : "GENERIC", - "category" : "LOCAL", - "public" : false, - "description" : "", - "configuration": {}, - "createdBy" : "system", - "createdDate" : "2020-03-16T12:13:03.371", - "lastModifiedBy" : "system", - "lastModifiedDate" : "2020-03-16T12:13:03.371", - "quota": 1024, - "used": 100 - }, - "traceId": null - } - ``` - -- data字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |projectId|string|项目id|project id| - |name|string|仓库名称|repo name| - |type|string|仓库类型|repo type| - |category|string|仓库类别|repo category| - |public|boolean|是否公开项目|is public repo| - |description|string|仓库描述|repo description| - |configuration|[object]|仓库配置,参考仓库配置介绍|repo configuration| - |createdBy|string|创建者|create user| - |createdDate|string|创建时间|create time| - |lastModifiedBy|string|上次修改者|last modify user| - |lastModifiedDate|string|上次修改时间|last modify time| - |quota|long|仓库配额,单位字节,值为nul时表示未设置仓库配额|repo quota| - |used|long|仓库已使用容量,单位字节|repo used volume| - -## 校验仓库是否存在 - -- API: GET /repository/api/repo/exist/{projectId}/{repoName} -- API 名称: check_repo_exist -- 功能说明: - - 中文:校验仓库是否存在 - - English:check repo exist -- 请求体 - 此接口无请求体 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |repoName|string|是|无|仓库名称|repo name| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": true, - "traceId": null - } - ``` - -- data字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |data|boolean|仓库是否存在|repo exist or not| - -## 分页查询仓库 - -- API: GET /repository/api/repo/page/{projectId}/{pageNumber}/{pageSize}?name=local&type=GENERIC -- API 名称: list_repo_page -- 功能说明: - - 中文:分页查询仓库 - - English:list repo page -- 请求体 - 此接口无请求体 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |pageNumber|int|是|无|当前页|page number| - |pageSize|int|是|无|分页数量|page size| - |name|string|否|无|仓库名称,支持前缀模糊匹配|repo name| - |type|string|否|无|仓库类型,枚举值|repo type| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": { - "pageNumber": 0, - "pageSize": 1, - "totalRecords": 18, - "totalPages": 2, - "records": [ - { - "projectId" : "test", - "name" : "local", - "type" : "GENERIC", - "category" : "LOCAL", - "public" : false, - "description" : "", - "createdBy" : "system", - "createdDate" : "2020-03-16T12:13:03.371", - "lastModifiedBy" : "system", - "lastModifiedDate" : "2020-03-16T12:13:03.371", - "quota": 1024, - "used": 100 - } - ] - }, - "traceId": null - } - ``` - -- data字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |projectId|string|项目id|project id| - |name|string|仓库名称|repo name| - |type|string|仓库类型|repo type| - |category|string|仓库类别|repo category| - |public|boolean|是否公开项目|is public repo| - |description|string|仓库描述|repo description| - |createdBy|string|创建者|create user| - |createdDate|string|创建时间|create time| - |lastModifiedBy|string|上次修改者|last modify user| - |lastModifiedDate|string|上次修改时间|last modify time| - |quota|long|仓库配额,单位字节,值为nul时表示未设置仓库配额|repo quota| - |used|long|仓库已使用容量,单位字节|repo used volume| - -## 列表查询仓库 - -- API: GET /repository/api/repo/list/{projectId}?name=local&type=GENERIC -- API 名称: list_repo -- 功能说明: - - 中文:列表查询仓库 - - English:list repo -- 请求体 - 此接口无请求体 -- 请求字段说明 - - |字段|类型|是否必须|默认值|说明|Description| - |---|---|---|---|---|---| - |projectId|string|是|无|项目名称|project name| - |name|string|否|无|仓库名称,支持前缀模糊匹配|repo name| - |type|string|否|无|仓库类型,枚举值|repo type| - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": [ - { - "projectId" : "test", - "name" : "local", - "type" : "GENERIC", - "category" : "LOCAL", - "public" : false, - "description" : "", - "createdBy" : "system", - "createdDate" : "2020-03-16T12:13:03.371", - "lastModifiedBy" : "system", - "lastModifiedDate" : "2020-03-16T12:13:03.371", - "quota": 1024, - "used": 100 - } - ], - "traceId": null - } - ``` - -- data字段说明 - - |字段|类型|说明|Description| - |---|---|---|---| - |projectId|string|项目id|project id| - |name|string|仓库名称|repo name| - |type|string|仓库类型|repo type| - |category|string|仓库类别|repo category| - |public|boolean|是否公开项目|is public repo| - |description|string|仓库描述|repo description| - |createdBy|string|创建者|create user| - |createdDate|string|创建时间|create time| - |lastModifiedBy|string|上次修改者|last modify user| - |lastModifiedDate|string|上次修改时间|last modify time| - |quota|long|仓库配额,单位字节,值为nul时表示未设置仓库配额|repo quota| - |used|long|仓库已使用容量,单位字节|repo used volume| - -## 查询仓库配额 - -- API: GET /repository/api/repo/quota/{projectId}/{repoName} - -- API 名称:get_repo_quota - -- 功能说明: - - - 中文:查询仓库配额 - - English:get repo quota - -- 请求体 - - - 此接口无请求体 - - - 请求字段说明 - - | 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | - | --------- | ------ | -------- | ------ | -------- | ------------ | - | projectId | string | 是 | 无 | 项目名称 | project name | - | repoName | string | 是 | 无 | 仓库名称 | repo name | - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": { - "quota": 1024, - "used": 100 - }, - "traceId": "" - } - ``` - -- data字段说明 - - | 字段 | 类型 | 说明 | Description | - | ----- | ---- | ----------------------------------------------- | ---------------- | - | quota | long | 仓库配额,单位字节,值为nul时表示未设置仓库配额 | repo quota | - | used | long | 仓库已使用容量,单位字节 | repo used volume | - -## 修改仓库配额 - -- API: POST /repository/api/repo/quota/{projectId}/{repoName} - -- API 名称:update_repo_quota - -- 功能说明: - - - 中文:修改仓库配额 - - English:update repo quota - -- 请求体 - - ``` - quota=102400 - ``` - - - 请求字段说明 - - | 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | - | --------- | ------ | -------- | ------ | -------- | ------------ | - | projectId | string | 是 | 无 | 项目名称 | project name | - | repoName | string | 是 | 无 | 仓库名称 | repo name | - | quota | long | 是 | 无 | 仓库配额 | repo quota | - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": "" - } - ``` - -- data字段说明 - - - 此接口无返回data - -## 仓库公共枚举值说明 -### 仓库类型RepositoryType - -> 用于标识仓库功能类型 - -|枚举值|说明| -|---|---| -|GENERIC|通用二进制文件仓库| -|DOCKER|Docker仓库| -|MAVEN|Maven仓库| -|PYPI|Pypi仓库| -|NPM|Npm仓库| -|HELM|Helm仓库| -|COMPOSER|Composer仓库| -|RPM|Rpm仓库| - -### 仓库类别RepositoryCategory - -> 用于标识仓库类别 - -|枚举值|说明| -|---|---| -|LOCAL|本地仓库。普通仓库,上传/下载构件都在本地进行。| -|REMOTE|远程仓库。通过访问远程地址拉取构件,不支持上传| -|VIRTUAL|虚拟仓库。可以组合多个本地仓库和远程仓库拉取构件,不支持上传| -|COMPOSITE|组合仓库。具有LOCAL的功能,同时也支持代理多个远程地址进行下载| - -## RepositoryConfiguration仓库配置项 -### 公共配置项 - -每一类配置都具有下列公共配置项 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|type|string|是|无|不同类型仓库分别对应local、remote、virtual、composite(小写),用于反序列化,创建和修改时需要提供该字段|configuration type| -|settings|map|否|无|不同类型仓库可以通过该字段进行差异化配置|repo settings| - -### local本地仓库配置项 - -|字段|类型|是否必须|默认值|说明|Description| -|:------|---|---|---|---|---| -|webHook|WebHook|否|无|WebHook相关配置|web hook| - -- **WebHook配置项** - -|字段|类型|是否必须|默认值|说明|Description| -|:----------|---|---|---|---|---| -|webHookList|[WebHookSetting]|否|无|WebHook 列表|web hook list| - -- **WebHookSetting配置项** - -|字段|类型|是否必须|默认值|说明|Description| -|:------|---|---|---|---|---| -|url|string|否|无|远程url地址|remote web hook url| -|headers|map|否|无|发起远程url的自定义headers|web hook headers| - -### remote远程仓库配置项 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|url|string|否|空|远程地址|remote repository url| -|credentials|RemoteCredentialsConfiguration|否|默认配置|访问凭证配置|remote credentials configuration| -|network|RemoteNetworkConfiguration|否|默认配置|网络配置|remote network configuration| -|cache|RemoteCacheConfiguration|否|默认配置|缓存配置|remote cache configuration| - -- **RemoteCredentialsConfiguration** - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|username|string|否|无|远程仓库 用户名|remote repo username| -|password|string|否|无|远程仓库 密码|remote repo password| - -- **RemoteNetworkConfiguration** - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|proxy|NetworkProxyConfiguration|否|无|网络代理配置|network proxy| -|connectTimeout|long|否|10 * 1000|网络连接超时时间(单位ms)|network connect timeout| -|readTimeout|long|否|10 * 1000|网络读取超时时间(单位ms)|network read timeout| - -- **NetworkProxyConfiguration** - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|host|string|是|无|网络代理主机|proxy host| -|port|int|是|无|网络代理端口|proxy int| -|username|string|否|无|网络代理用户名|proxy username| -|password|string|否|无|网络代理密码|proxy password| - -- **RemoteCacheConfiguration** - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|enabled|boolean|否|true|是否开启缓存|cache enabled| -|expiration|long|否|---1|构件缓存过期时间(单位分钟,0或负数表示永久缓存)|cache expiration| - -### virtual虚拟仓库配置项 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|repositoryList|[RepositoryIdentify]|否|无|仓库列表|repo list| - -- **RepositoryIdentify** - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|projectId|string|是|无|代理项目名称|project id| -|name|string|是|无|代理仓库名称|repo name| - -### composite组合仓库配置项 - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|proxy|ProxyConfiguration|否|无|仓库代理配置|repo proxy configuration| - -- **ProxyConfiguration** - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|channelList|[ProxyChannelSetting]|否|无|代理源列表|proxy channel list| - -- **ProxyChannelSetting** - -|字段|类型|是否必须|默认值|说明|Description| -|---|---|---|---|---|---| -|public|boolean|是|无|是否为公有源|is public| -|name|string|否|无|代理源名称|proxy channel name| -|url|string|否|无|代理源地址|proxy channel url| -|credentialKey|string|否|无|鉴权凭据key|proxy credentials id| -|username|string|否|无|代理源认证用户名|channel username| -|password|string|否|无|代理源认证密码|channel password| - -### 依赖源的差异化配置项 - -各个依赖源的差异化配置通过`settings`进行配置,每项配置的具体含义请参考依赖源文档。 \ No newline at end of file diff --git a/docs/storage/apidoc/scanner/report.md b/docs/storage/apidoc/scanner/report.md deleted file mode 100644 index 9d2e181a7d1..00000000000 --- a/docs/storage/apidoc/scanner/report.md +++ /dev/null @@ -1,171 +0,0 @@ -# 扫描报告接口 - -[toc] - -## 获取扫描报告预览 - -- API: POST /scanner/api/scan/reports/overview -- API 名称: get_report_overview -- 功能说明: - - 中文:预览扫描报告 - - English:scan report overview -- 请求体 - -```json -{ - "scanner": "default", - "credentialsKeyFiles": [ - { - "credentialsKey": null, - "sha256List":["af5d27f8921339531c5315c0928558f0de9ef1d27d07ff0f487602239cf885b5"] - } - ] -} -``` - -- 请求字段说明 - -| 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | -|-----------------------------------------|--------|------|-----|-------------------------|-----------------| -| scanner | string | 是 | 无 | 要获取的报告使用的扫描器名称 | scanner name | -| credentialsKeyFiles.credentialsKeyFiles | string | 否 | 无 | 被扫描文件所在存储,为null时表示在默认存储 | credentials key | -| credentialsKeyFiles.sha256List | array | 是 | 无 | 要查询报告的文件sha256列表 | sha256 list | - -- 响应体 - -```json -{ - "code": 0, - "message": null, - "data": [ - { - "status": "SUCCESS", - "sha256": "726683039c3af2005142c80af8ba823715ee07acbff17eb2662f08fb2b903d0f", - "scanDate": "2022-03-10T17:06:05.122", - "overview": { - "cveLowCount": 5, - "cveCriticalCount": 10, - "licenseRiskLowCount": 52, - "licenseRiskMidCount": 56, - "sensitiveUriCount": 2095, - "cveHighCount": 44, - "sensitiveIpv4Count": 386, - "licenseRiskNotAvailableCount": 30, - "licenseRiskHighCount": 24, - "cveMidCount": 35, - "sensitiveEmailCount": 237 - } - } - ], - "traceId": "" -} -``` -- data字段说明 - -| 字段 | 类型 | 说明 | Description | -|------------------------------|--------|-----------------------|-------------------------------------| -| status | string | 文件扫描状态 | file scan status | -| sha256 | string | 文件sha256 | file sha256 | -| scanDate | string | 文件扫描时间 | file scan datetime | -| overview | object | 文件扫描结果预览,不同扫描器预览结果不一样 | file scan result overview | -| cveLowCount | number | 低风险漏洞数 | low risk vulnerabilities count | -| cveMidCount | number | 中风险漏洞数 | mid risk vulnerabilities count | -| cveHighCount | number | 高风险漏洞数 | high risk vulnerabilities count | -| cveCriticalCount | number | 严重风险漏洞数 | critical risk vulnerabilities count | -| licenseRiskLowCount | number | 制品依赖的库使用的低风险证书数量 | low risk license count | -| licenseRiskMidCount | number | 制品依赖的库使用的中风险证书数量 | mid risk license count | -| licenseRiskHighCount | number | 制品依赖的库使用的高风险证书数量 | high risk license count | -| licenseRiskNotAvailableCount | number | 知识库未收录的证书数量 | unknown license count | -| sensitiveEmailCount | number | 敏感邮箱地址数 | sensitive email count | -| sensitiveIpv4Count | number | 敏感ipv4地址数 | sensitive ipv4 address count | -| sensitiveIpv6Count | number | 敏感ipv6地址数 | sensitive ipv6 address count | -| sensitiveUriCount | number | 敏感uri数 | sensitive uri count | -| sensitiveSecretCount | number | 敏感密钥数 | sensitive secret count | -| sensitiveCryptoObjectCount | number | 敏感密钥文件数 | sensitive crypto count | - -扫描结果预览字段参考[支持的扫描器](./supported-scanner.md) - -## 获取扫描报告详情 - -- API: POST /scanner/api/scan/reports/detail/{projectId}/{repoName}/{artifactUri} -- API 名称: get_report_detail -- 功能说明: - - 中文:获取扫描报告详情 - - English:scan report detail -- 请求体 - -```json -{ - "scanner": "default", - "reportType": "SENSITIVE_ITEM", - "pageLimit": { - "pageNumber": 1, - "pageSize": 10 - } -} -``` - -- 请求字段说明 - -| 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | -|----------------------|--------|------|-----|----------------------------------------------------------------------------------------|-----------------| -| projectId | string | 是 | 无 | 文件所属项目id | project id | -| repoName | string | 是 | 无 | 文件所属仓库名 | repository name | -| artifactUri | string | 是 | 无 | 文件路径 | artifact uri | -| scanner | string | 是 | 无 | 扫描器名 | scanner name | -| reportType | string | 是 | 无 | 扫描报告类型,arrowhead有CHECK_SEC_ITEM,APPLICATION_ITEM,CVE_SEC_ITEM,SENSITIVE_ITEM,4种类型的扫描报告 | report type | -| pageLimit.pageNumber | number | 否 | 1 | 分页页码 | page number | -| pageLimit.pageSize | number | 否 | 20 | 分页大小 | page size | - -- 响应体 - -```json -{ - "code": 0, - "message": null, - "data": { - "status": "SUCCESS", - "sha256": "726683039c3af2005d4ac80af8ba823715ee07acbff17eb2662f08fb2b903d0f", - "detail": { - "pageNumber": 1, - "pageSize": 10, - "totalRecords": 1, - "totalPages": 1, - "records": [ - { - "path": "test.xml", - "type": "uri", - "subtype": "uri", - "content": "https://example.com", - "domain": "example.com", - "attr": { - "scheme": "https" - } - } - ], - "count": 1, - "page": 1 - }, - "type": "SENSITIVE_ITEM" - }, - "traceId": "" -} -``` - - data字段说明 - -| 字段 | 类型 | 说明 | Description | -|------------------------|--------|----------|-------------------------| -| status | string | 文件扫描状态 | file scan status | -| sha256 | string | 文件sha256 | file sha256 | -| detail.pageNumber | number | 页码 | page number | -| detail.pageSize | number | 页大小 | page size | -| detail.totalRecords | number | 总记录数量 | total records | -| detail.totalPage | number | 总页数 | total page | -| detail.records.path | string | 制品用的库的路径 | lib path | -| detail.records.type | string | 敏感信息类型 | sensitive item class | -| detail.records.subtype | string | 敏感信息子类型 | sensitive item subclass | -| detail.records.content | string | 敏感信息内容 | sensitive content | -| detail.records.attr | string | 敏感信息属性 | sensitive item attr | - -扫描结果详情字段参考[支持的扫描器](./supported-scanner.md) \ No newline at end of file diff --git a/docs/storage/apidoc/scanner/scan.md b/docs/storage/apidoc/scanner/scan.md deleted file mode 100644 index 5f83a495493..00000000000 --- a/docs/storage/apidoc/scanner/scan.md +++ /dev/null @@ -1,256 +0,0 @@ -# 扫描接口 - -[toc] - -## 创建扫描任务 - -- API: POST /scanner/api/scan -- API 名称: scan -- 功能说明: - - 中文:发起扫描 - - English:scan -- 请求体 - -```json -{ - "scanner": "default", - "rule": { - "relation": "AND", - "rules": [ - { - "field": "projectId", - "value": "testProjectId", - "operation": "EQ" - }, - { - "field": "repoName", - "value": "maven-local", - "operation": "EQ" - }, - { - "field": "fullPath", - "value": "/", - "operation": "PREFIX" - } - ] - } -} -``` - -- 请求字段说明 - -| 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | -|---------|--------|------|-----|------------------------------------------------------------|-----------------| -| scanner | string | 是 | 无 | 要获取的报告使用的扫描器名称 | scanner name | -| rule | object | 是 | 无 | 要扫描的文件匹配规则,参考[自定义搜索接口公共说明](../common/search.md?id=自定义搜索协议) | file match rule | - -- 响应体 - -```json -{ - "code": 0, - "message": null, - "data": { - "taskId": "622aca02e01725126f31f7ce", - "createdBy": "admin", - "triggerDateTime": "2022-03-11T12:03:14.283", - "startDateTime": null, - "finishedDateTime": null, - "status": "PENDING", - "rule": { - "rules": [ - { - "field": "projectId", - "value": "testProjectId", - "operation": "EQ" - }, - { - "field": "repoName", - "value": "maven-local", - "operation": "EQ" - }, - { - "field": "fullPath", - "value": "/", - "operation": "PREFIX" - } - ], - "relation": "AND" - }, - "total": 0, - "scanning": 0, - "failed": 0, - "scanned": 0, - "scanner": "default", - "scannerType": "arrowhead", - "scannerVersion": "1::1", - "scanResultOverview": null - }, - "traceId": "" -} -``` - -- data字段说明 - -| 字段 | 类型 | 说明 | Description | -|--------------------|--------|------------------------------------------------------------|------------------------| -| taskId | string | 任务id | task id | -| createdBy | string | 任务创建者 | task creator | -| triggerDatetime | string | 触发任务的时间 | task trigger time | -| startDateTime | string | 任务开始执行时间 | task started time | -| finishedDateTime | string | 任务执行结束时间 | task finished time | -| status | string | 任务状态 | task status | -| rule | object | 要扫描的文件匹配规则,参考[自定义搜索接口公共说明](../common/search.md?id=自定义搜索协议) | file match rule | -| total | number | 总扫描文件数 | total scan file count | -| failed | number | 扫描失败文件数 | scan failed file count | -| scanned | number | 已扫描文件数 | scanned file count | -| scanner | string | 使用的扫描器明 | scanner name | -| scannerType | string | 扫描器类型 | scanner type | -| scannerVersion | string | 扫描器版本 | scanner version | -| scanResultOverview | array | 扫描结果预览 | scan result overview | - -扫描结果预览字段参考[支持的扫描器](./supported-scanner.md) - -## 获取扫描任务 - -- API: GET /scanner/api/scan/tasks/{taskId} -- API 名称: get_task -- 功能说明: - - 中文:获取扫描任务 - - English:get scan task -- 请求体 此接口请求体为空 - -- 请求字段说明 - -| 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | -|--------|--------|------|-----|------|-------------| -| taskId | string | 是 | 无 | 任务id | task id | - -- 响应体 - -```json -{ - "code": 0, - "message": null, - "data": { - "taskId": "622aca02e01725126f31f7ce", - "createdBy": "admin", - "triggerDateTime": "2022-03-11T12:03:14.283", - "startDateTime": "2022-03-11T12:03:16.542", - "finishedDateTime": "2022-03-11T13:09:23.319", - "status": "FINISHED", - "rule": { - "rules": [ - { - "field": "projectId", - "value": "testProjectId", - "operation": "EQ" - }, - { - "field": "repoName", - "value": "maven-local", - "operation": "EQ" - }, - { - "field": "fullPath", - "value": "/", - "operation": "PREFIX" - } - ], - "relation": "AND" - }, - "total": 1307, - "scanning": 0, - "failed": 0, - "scanned": 1307, - "scanner": "default", - "scannerType": "arrowhead", - "scannerVersion": "1::1", - "scanResultOverview": { - "sensitiveUriCount": 4 - } - }, - "traceId": "" -} -``` - -- data字段说明 - -响应体参考[创建扫描任务](./scan.md?id=创建扫描任务)响应体 - -## 分页获取扫描任务 - -- API: GET /scanner/api/scan/tasks -- API 名称: get_tasks -- 功能说明: - - 中文:分页获取扫描任务 - - English:get scan tasks -- 请求体 此接口请求体为空 - -- 请求字段说明 - -| 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | -|------------|--------|------|-----|------|-------------| -| pageSize | number | 否 | 20 | 分页大小 | page size | -| pageNumber | number | 否 | 1 | 分页页码 | page number | - -- 响应体 - -```json -{ - "code": 0, - "message": null, - "data": { - "pageNumber": 1, - "pageSize": 20, - "totalRecords": 1, - "totalPages": 1, - "records": [ - { - "taskId": "62277d0ff6671d535feaa286", - "createdBy": "admin", - "triggerDateTime": "2022-03-08T23:58:07.319", - "startDateTime": "2022-03-10T11:40:04.808", - "finishedDateTime": null, - "status": "SCANNING_SUBMITTED", - "rule": { - "rules": [ - { - "field": "projectId", - "value": "testProjectId", - "operation": "EQ" - }, - { - "field": "repoName", - "value": "test", - "operation": "EQ" - }, - { - "field": "fullPath", - "value": "/", - "operation": "PREFIX" - } - ], - "relation": "AND" - }, - "total": 1, - "scanning": 1, - "failed": 0, - "scanned": 0, - "scanner": "default", - "scannerType": "arrowhead", - "scannerVersion": "1::1", - "scanResultOverview": null - } - ], - "count": 1, - "page": 1 - }, - "traceId": "" -} -``` -- data字段说明 - -响应体参考[分页接口响应格式](../common/common.md?id=统一分页接口响应格式) - -响应体参考[创建扫描任务](./scan.md?id=创建扫描任务)响应体 diff --git a/docs/storage/apidoc/scanner/scanner.md b/docs/storage/apidoc/scanner/scanner.md deleted file mode 100644 index 2a429a7795d..00000000000 --- a/docs/storage/apidoc/scanner/scanner.md +++ /dev/null @@ -1,242 +0,0 @@ -# 扫描器接口 - -[toc] - -## 创建扫描器 - -- API: POST /scanner/api/scanners -- API 名称: create_scanner -- 功能说明: - - 中文:创建扫描器 - - English:create scanner -- 创建arrowhead扫描器请求体 - -```json -{ - "name": "default", - "version": "1::1", - "type": "arrowhead", - "rootPath": "/data1/arrowhead", - "configFilePath": "/standalone.toml", - "cleanWorkDir": false, - "maxScanDuration": 600000, - "knowledgeBase": { - "secretId": "username", - "secretKey": "key", - "endpoint": "http://localhost:8021" - }, - "container": { - "image": "arrowhead:latest", - "args": "/data/standalone.toml" - }, - "resultFilterRule": { - "sensitiveItemFilterRule": { - "excludes": { - "type": [ - "ipv6" - ] - } - } - } -} -``` - -- 请求字段说明 -详情参考[支持的扫描器](./supported-scanner.md) - -| 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | -|---------------------------------------------------|---------|------|------------------|--------------------------------------------------|------------------------------------| -| name | string | 是 | 无 | 扫描器名 | scanner name | -| version | string | 是 | 无 | 扫描器版本,arrowhead扫描器版本和漏洞库版本用::分隔 | scanner version | -| type | string | 是 | 无 | 扫描器类型 | scanner type | -| rootPath | string | 是 | 无 | 扫描器工作根目录 | scanner work dir | -| configFilePath | string | 否 | /standalone.toml | 生成的arrowhead扫描器配置文件存放路径 | arrowhead scanner config file path | -| cleanWorkDir | boolean | 否 | true | 扫描结束后是否清理目录 | clean work dir after scan | -| maxScanDuration | number | 否 | 600000 | 扫描超时时间,单位为毫秒 | max scan duration | -| knowledgeBase.secretId | string | 否 | 无 | 漏洞库用户名 | knowledge base username | -| knowledgeBase.secretKey | string | 否 | 无 | 漏洞库认证密钥 | knowledge base key | -| knowledgeBase.endpoint | string | 否 | 无 | 漏洞库地址 | knowledge base address | -| container.image | string | 是 | 无 | 使用的arrowhead镜像tag | arrowhead image tag | -| container.args | string | 是 | 无 | 启动容器时传的参数 | container args | -| container.workDir | string | 否 | /data | 容器内工作目录根目录 | work dir | -| container.inputDir | string | 否 | /package | 容器内扫描时的输入目录,相对于工作目录 | input dir | -| container.outputDir | string | 否 | /output | 容器内扫描时的输出目录,相对于工作目录 | output dir | -| resultFilterRule.sensitiveItemFilterRule.excludes | array | 否 | 无 | 敏感信息扫描结果过滤规则,key为敏感信息结果字段名,value为要过滤的敏感信息结果字段值列表 | sensitiv item filter rule | - -- 响应体 - -```json -{ - "code": 0, - "message": null, - "data": { - "name": "default", - "version": "1::1", - "rootPath": "/data1/arrowhead", - "configFilePath": "/standalone.toml", - "cleanWorkDir": false, - "knowledgeBase": { - "secretId": "username", - "secretKey": "key", - "endpoint": "http://localhost:8021" - }, - "container": { - "image": "arrowhead:latest", - "args": "/data/standalone.toml", - "workDir": "/data", - "inputDir": "/package", - "outputDir": "/output" - }, - "resultFilterRule": { - "sensitiveItemFilterRule": { - "excludes": { - "type": [ - "ipv6" - ] - } - } - }, - "maxScanDuration": 600000, - "type": "arrowhead" - }, - "traceId": "" -} - ``` - -## 查询扫描器 - -- API: GET /scanner/api/scanners/{scannerName} -- API 名称: get_scanner -- 功能说明: - - 中文:查询扫描器 - - English:get scanner -- 请求体 此接口请求体为空 -- 请求字段说明 - -| 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | -|-------------|--------|------|-----|------|--------------| -| scannerName | string | 否 | 无 | 扫描器名 | scanner name | - -- 响应体 - -```json -{ - "code": 0, - "message": null, - "data": { - "name": "default", - "version": "1::1", - "rootPath": "/data1/arrowhead", - "configFilePath": "/standalone.toml", - "cleanWorkDir": false, - "knowledgeBase": { - "secretId": "username", - "secretKey": "key", - "endpoint": "http://localhost:8021" - }, - "container": { - "image": "arrowhead:latest", - "args": "/data/standalone.toml", - "workDir": "/data", - "inputDir": "/package", - "outputDir": "/output" - }, - "resultFilterRule": { - "sensitiveItemFilterRule": { - "excludes": { - "type": [ - "ipv6" - ] - } - } - }, - "maxScanDuration": 600000, - "type": "arrowhead" - }, - "traceId": null -} - ``` - -- data字段说明 -详情参考[支持的扫描器](./supported-scanner.md) - -## 删除扫描器 - -- API: DELETE /scanner/api/scanners/{scannerName} -- API 名称: delete_scanner -- 功能说明: - - 中文:删除扫描器 - - English:delete scanner -- 请求体 此接口请求体为空 - -- 请求字段说明 - -| 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | -|-------------|--------|------|-----|-------|--------------| -| scannerName | string | 是 | 无 | 扫描器名称 | scanner name | - -- 响应体 - -```json -{ - "code": 0, - "message": null, - "data": null, - "traceId": null -} - ``` - -## 获取扫描器列表 - -- API: GET /scanner/api/scanners -- API 名称: list_scanner -- 功能说明: - - 中文:获取扫描器列表 - - English:list scanner -- 请求体 此接口请求体为空 - -- 响应体 - -```json -{ - "code": 0, - "message": null, - "data": [ - { - "name": "default", - "version": "1::1", - "rootPath": "/data1/arrowhead", - "configFilePath": "/standalone.toml", - "cleanWorkDir": false, - "knowledgeBase": { - "secretId": "username", - "secretKey": "key", - "endpoint": "http://localhost:8021" - }, - "container": { - "image": "arrowhead:latest", - "args": "/data/standalone.toml", - "workDir": "/data", - "inputDir": "/package", - "outputDir": "/output" - }, - "resultFilterRule": { - "sensitiveItemFilterRule": { - "excludes": { - "type": [ - "ipv6" - ] - } - } - }, - "maxScanDuration": 600000, - "type": "arrowhead" - } - ], - "traceId": "" -} -``` - -- data字段说明 - -详情参考[支持的扫描器](./supported-scanner.md) \ No newline at end of file diff --git a/docs/storage/apidoc/scanner/supported-scanner.md b/docs/storage/apidoc/scanner/supported-scanner.md deleted file mode 100644 index 9db4fc47d0f..00000000000 --- a/docs/storage/apidoc/scanner/supported-scanner.md +++ /dev/null @@ -1,122 +0,0 @@ -# 已支持的扫描器 - -**扫描器配置公共字段** - -| 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | -|---------|--------|------|-----|-------|-----------------| -| name | string | 是 | 无 | 扫描器名 | scanner name | -| type | string | 是 | 无 | 扫描器类型 | scanner type | -| version | string | 是 | 无 | 扫描器版本 | scanner version | - -# Arrowhead扫描器 - -## 扫描器配置 - -| 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | -|------------------|---------|------|------------------|---------------------------------------|-----------------------------------------| -| rootPath | string | 是 | 无 | 扫描器工作根目录,扫描执行时每个扫描任务都会在这个目录下创建自己的工作目录 | scanner root path | -| configFilePath | string | 是 | /standalone.toml | 扫描器配置存放路径,相对于扫描任务的工作目录 | scanner config file relative path | -| cleanWorkDir | boolean | 否 | true | 扫描结束后是否清理扫描任务的工作目录 | clean scan task work dir after scanning | -| maxScanDuration | number | 否 | 600000 | 扫描任务最长执行时间,超过后会终止扫描 | max scan duration | -| knowledgeBase | object | 是 | 无 | 漏洞库配置 | knowledge base config | -| container | object | 是 | 无 | 扫描器容器配置 | container config | -| resultFilterRule | object | 否 | 无 | 扫描器结果过滤规则 | result filter rule | - -### knowledgeBase - -| 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | -|-----------|---------|------|-------|---------|-----------------------------------| -| secretId | string | 否 | null | 漏洞库用户名 | scanner config file relative path | -| secretKey | string | 否 | null | 漏洞库凭据 | scanner config file relative path | -| endpoint | string | 否 | null | 漏洞库地址 | scanner config file relative path | - -### container - - -| 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | -|-----------|--------|------|----------|------------------------------|--------------------------------| -| image | string | 是 | 无 | 扫描器镜像tag | image tag | -| args | string | 否 | 无 | 容器启动参数 | container start args | -| workDir | string | 否 | /data | 容器内的工作目录,会将扫描任务的工作目录挂载到这个目录里 | scanner work dir in container | -| inputDir | string | 否 | /package | 输入目录,相对于workDir的路径 | scanner input dir in container | -| outputDir | string | 否 | /output | 输出目录,相对于workDir的路径 | scanner output dir incontainer | - -### resultFilterRule - -| 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | -|-------------------------|--------|------|-----|------------|----------------------------| -| sensitiveItemFilterRule | object | 是 | 无 | 敏感信息结果过滤规则 | sensitive item filter rule | - -#### sensitiveItemFilterRule - -| 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | -|----------|--------|------|-----|--------------------------------------------------------------|----------------------------| -| excludes | object | 是 | 无 | 敏感信息结果过滤规则map,key为结果字段名,value为key对应的结果字段值的列表,结果字段的值在列表中的会被过滤 | sensitive item filter rule | - -## 扫描结果 - -### 扫描结果预览 - -| 字段 | 类型 | 说明 | Description | -|------------------------------|--------|------------------|-------------------------------------| -| cveLowCount | number | 低风险漏洞数 | low risk vulnerabilities count | -| cveMidCount | number | 中风险漏洞数 | mid risk vulnerabilities count | -| cveHighCount | number | 高风险漏洞数 | high risk vulnerabilities count | -| cveCriticalCount | number | 严重风险漏洞数 | critical risk vulnerabilities count | -| licenseRiskLowCount | number | 制品依赖的库使用的低风险证书数量 | low risk license count | -| licenseRiskMidCount | number | 制品依赖的库使用的中风险证书数量 | mid risk license count | -| licenseRiskHighCount | number | 制品依赖的库使用的高风险证书数量 | high risk license count | -| licenseRiskNotAvailableCount | number | 知识库未收录的证书数量 | unknown license count | -| sensitiveEmailCount | number | 敏感邮箱地址数 | sensitive email count | -| sensitiveIpv4Count | number | 敏感ipv4地址数 | sensitive ipv4 address count | -| sensitiveIpv6Count | number | 敏感ipv6地址数 | sensitive ipv6 address count | -| sensitiveUriCount | number | 敏感uri数 | sensitive uri count | -| sensitiveSecretCount | number | 敏感密钥数 | sensitive secret count | -| sensitiveCryptoObjectCount | number | 敏感密钥文件数 | sensitive crypto count | - -### 扫描详细结果 - -#### APPLICATION_ITEM - -| 字段 | 类型 | 说明 | Description | -|----------------|--------|-------------------------|-----------------| -| path | string | 使用的库在被扫描文件中的路径 | library path | -| libraryName | string | 库名 | library name | -| libraryVersion | string | 库版本 | library version | -| license | string | 使用的证书 | license | -| licenseRisk | string | 证书风险等级,low,mid,high三个等级 | license risk | - -#### SENSITIVE_ITEM - -| 字段 | 类型 | 说明 | Description | -|---------|--------|---------------------|---------------------------| -| path | string | 存在敏感信息的文件相对被扫描文件的路径 | sensitive file path | -| type | string | 敏感信息类型 | sensitive content type | -| subtype | string | 敏感信息子类型 | sensitive content subtype | -| content | string | 敏感信息内容 | sensitive content | -| domain | string | uri,email类型的敏感信息的域名 | domain | -| attr | object | 敏感信息属性 | attr | - -#### CVE_SEC_ITEM - -| 字段 | 类型 | 说明 | Description | -|-----------------|--------|-------------------|---------------------------------------------| -| path | string | 存在漏洞的文件相对被扫描文件的路径 | path | -| component | string | 存在漏洞的组件 | component with the vulnerability | -| version | string | 组件版本 | component version | -| versionEffected | string | 受影响组件版本 | component version effected by vulnerability | -| versionFixed | string | 组件修复版本 | fixed component version | -| name | string | 漏洞名 | vulnerability name | -| category | string | 漏洞利用类型 | category | -| categoryType | string | 漏洞类型 | category type | -| pocId | string | poc id | poc id | -| cveId | string | cve id | cve id | -| cnvdId | string | cnvd id | cnvd id | -| cnnvdId | string | cnnvd id | cnnvd id | -| cweId | string | cwe id | cwe id | -| cvssRank | string | cvss等级 | cvss rank | -| cvss | string | cvss评分 | cvss | -| cvssV3Vector | string | cvss V3 漏洞影响评价 | cvss v3 vector | -| cvssV2Vector | string | cvss V2 漏洞影响评价 | cvss v2 vector | -| dynamicLevel | string | dynamic level | dynamic level | -| level | string | 知识库漏洞评级 | leveL | diff --git a/docs/storage/apidoc/webhook/payload.md b/docs/storage/apidoc/webhook/payload.md deleted file mode 100644 index 08f93119f9e..00000000000 --- a/docs/storage/apidoc/webhook/payload.md +++ /dev/null @@ -1,574 +0,0 @@ -# WebHook事件消息载荷 - -## 公共消息 - -### 公共消息载荷 - -每个WebHook事件消息载荷都包含以下字段: - -| 字段 | 类型 | 说明 | -| --------- | ------ | ---------------- | -| eventType | String | 触发事件类型 | -| user | Object | 触发事件用户信息 | - -### 公共请求头 - -| 名称 | 说明 | -| -------------- | --------------- | -| X-BKREPO-EVENT | 触发WebHook事件 | - -## 测试事件 - -WebHook服务提供测试事件,方便用户添加WebHook后测试连通性 - -### 消息载荷 - -| 字段 | 类型 | 说明 | -| --------- | ------ | ----------------- | -| eventType | String | 触发事件类型 | -| user | Object | 触发事件用户信息 | -| webHook | Object | 测试的WebHook信息 | - -示例 - -```json -{ - "user" : { - "userId" : "string", - "name" : "string", - "email" : null, - "phone" : null, - "createdDate" : "2021-07-05T11:19:31.921", - "locked" : false, - "admin" : false - }, - "webHook" : { - "id" : "string", - "url" : "http://localhost", - "triggers" : [ "NODE_CREATED", "NODE_DELETED" ], - "associationType" : "ARTIFACT_REPO", - "associationId" : "string", - "createdBy" : "string", - "createdDate" : "2021-09-13T17:45:33.878", - "lastModifiedBy" : "string", - "lastModifiedDate" : "2021-09-13T17:45:33.879" - }, - "eventType" : "WEBHOOK_TEST" -} -``` - -## 项目事件 - -### 创建项目 - -消息载荷 - -| 字段 | 类型 | 说明 | -| --------- | ------ | ---------------- | -| eventType | String | 触发事件类型 | -| user | Object | 触发事件用户信息 | -| project | Object | 创建的项目信息 | - -示例 - -```json -{ - "user" : { - "userId" : "string", - "name" : "string", - "email" : null, - "phone" : null, - "createdDate" : "2021-07-05T11:19:31.921", - "locked" : false, - "admin" : false - }, - "project" : { - "name" : "string", - "displayName" : "http://localhost", - "description" : "string", - "createdBy" : "test", - "createdDate" : "2021-09-13T17:45:33.878", - "lastModifiedBy" : "test", - "lastModifiedDate" : "2021-09-13T17:45:33.879" - }, - "eventType" : "PROJECT_CREATED" -} -``` - - - -## 仓库事件 - -### 创建仓库 - -消息载荷 - -| 字段 | 类型 | 说明 | -| ---------- | ------ | ---------------- | -| eventType | String | 触发事件类型 | -| user | Object | 触发事件用户信息 | -| repository | Object | 创建的仓库信息 | - -示例 - -```json -{ - "user" : { - "userId" : "string", - "name" : "string", - "email" : null, - "phone" : null, - "createdDate" : "2021-07-05T11:19:31.921", - "locked" : false, - "admin" : false - }, - "repository" : { - "projectId" : "project", - "name" : "repo", - "type" : "GENERIC", - "category" : "LOCAL", - "public" : false, - "description" : "string", - "configuration" : "{}", - "storageCredentialsKey" : "string", - "createdBy" : "test", - "createdDate" : "2021-09-13T17:45:33.878", - "lastModifiedBy" : "test", - "lastModifiedDate" : "2021-09-13T17:45:33.879" - }, - "eventType" : "REPO_CREATED" -} -``` - - - -### 更新仓库 - -消息载荷 - -| 字段 | 类型 | 说明 | -| ---------- | ------ | ---------------- | -| eventType | String | 触发事件类型 | -| user | Object | 触发事件用户信息 | -| repository | Object | 创建的仓库信息 | - -示例 - -```json -{ - "user" : { - "userId" : "string", - "name" : "string", - "email" : null, - "phone" : null, - "createdDate" : "2021-07-05T11:19:31.921", - "locked" : false, - "admin" : false - }, - "repository" : { - "projectId" : "project", - "name" : "repo", - "type" : "GENERIC", - "category" : "LOCAL", - "public" : false, - "description" : "string", - "configuration" : "{}", - "storageCredentialsKey" : "string", - "createdBy" : "test", - "createdDate" : "2021-09-13T17:45:33.878", - "lastModifiedBy" : "test", - "lastModifiedDate" : "2021-09-13T17:45:33.879" - }, - "eventType" : "REPO_UPDATED" -} -``` - - - -### 删除仓库 - -消息载荷 - -| 字段 | 类型 | 说明 | -| --------- | ------ | -------------------- | -| eventType | String | 触发事件类型 | -| user | Object | 触发事件用户信息 | -| projectId | String | 删除仓库的所属项目ID | -| repoName | String | 删除的仓库名称 | - -示例 - -```json -{ - "user" : { - "userId" : "string", - "name" : "string", - "email" : null, - "phone" : null, - "createdDate" : "2021-07-05T11:19:31.921", - "locked" : false, - "admin" : false - }, - "projectId" : "project", - "repoName" : "repo", - "eventType" : "REPO_DELETED" -} -``` - - - -## 节点事件 - -### 创建节点 - -消息载荷 - -| 字段 | 类型 | 说明 | -| --------- | ------ | ---------------- | -| eventType | String | 触发事件类型 | -| user | Object | 触发事件用户信息 | -| node | Object | 创建的节点信息 | - -示例 - -```json -{ - "user" : { - "userId" : "string", - "name" : "string", - "email" : null, - "phone" : null, - "createdDate" : "2021-07-05T11:19:31.921", - "locked" : false, - "admin" : false - }, - "node" : { - "createdBy" : "string", - "createdDate" : "2021-09-15T14:48:40.73", - "lastModifiedBy" : "string", - "lastModifiedDate" : "2021-09-15T14:48:40.73", - "folder" : false, - "path" : "/", - "name" : "test.txt", - "fullPath" : "/test.txt", - "size" : 32, - "sha256" : "28eb526a0b9e4a022cce7e9c6dffb11699c3c19a11b419d1b13873271a3c099e", - "md5" : "156c8805787b870939a80c708b64c946", - "metadata" : { }, - "projectId" : "project", - "repoName" : "repo" - }, - "eventType" : "NODE_CREATED" -} -``` - -### 移动节点 - -消息载荷 - -| 字段 | 类型 | 说明 | -| ------------ | ------ | ---------------- | -| eventType | String | 触发事件类型 | -| user | Object | 触发事件用户信息 | -| node | Object | 移动后的节点信息 | -| srcProjectId | String | 源项目Id | -| srcRepoName | String | 源仓库名 | -| srcFullPath | String | 源节点完整路径 | - -示例 - -```json -{ - "user" : { - "userId" : "string", - "name" : "string", - "email" : null, - "phone" : null, - "createdDate" : "2021-07-05T11:19:31.921", - "locked" : false, - "admin" : false - }, - "node" : { - "createdBy" : "string", - "createdDate" : "2021-09-15T14:48:40.73", - "lastModifiedBy" : "string", - "lastModifiedDate" : "2021-09-15T14:48:40.73", - "folder" : false, - "path" : "/", - "name" : "test.txt", - "fullPath" : "/test.txt", - "size" : 32, - "sha256" : "28eb526a0b9e4a022cce7e9c6dffb11699c3c19a11b419d1b13873271a3c099e", - "md5" : "156c8805787b870939a80c708b64c946", - "metadata" : { }, - "projectId" : "project", - "repoName" : "repo" - }, - "srcProjectId": "project", - "srcRepoName": "repo", - "srcFullPath": "/test.txt", - "eventType" : "NODE_MOVED" -} -``` - -### 重命名节点 - -消息载荷 - -| 字段 | 类型 | 说明 | -| ----------- | ------ | ---------------------- | -| eventType | String | 触发事件类型 | -| user | Object | 触发事件用户信息 | -| node | Object | 重命名后的节点信息 | -| oldFullPath | String | 节点重命名前的完整路径 | - -示例 - -```json -{ - "user" : { - "userId" : "string", - "name" : "string", - "email" : null, - "phone" : null, - "createdDate" : "2021-07-05T11:19:31.921", - "locked" : false, - "admin" : false - }, - "node" : { - "createdBy" : "string", - "createdDate" : "2021-09-15T14:48:40.73", - "lastModifiedBy" : "string", - "lastModifiedDate" : "2021-09-15T14:48:40.73", - "folder" : false, - "path" : "/", - "name" : "test.txt", - "fullPath" : "/test.txt", - "size" : 32, - "sha256" : "28eb526a0b9e4a022cce7e9c6dffb11699c3c19a11b419d1b13873271a3c099e", - "md5" : "156c8805787b870939a80c708b64c946", - "metadata" : { }, - "projectId" : "project", - "repoName" : "repo" - }, - "oldFullPath": "/old.txt" - "eventType" : "NODE_RENAMED" -} -``` - -### 复制节点 - -消息载荷 - -| 字段 | 类型 | 说明 | -| ------------ | ------ | ---------------- | -| eventType | String | 触发事件类型 | -| user | Object | 触发事件用户信息 | -| node | Object | 复制后的节点信息 | -| srcProjectId | String | 源项目Id | -| srcRepoName | String | 源仓库名 | -| srcFullPath | String | 源节点完整路径 | - -示例 - -```json -{ - "user" : { - "userId" : "string", - "name" : "string", - "email" : null, - "phone" : null, - "createdDate" : "2021-07-05T11:19:31.921", - "locked" : false, - "admin" : false - }, - "node" : { - "createdBy" : "string", - "createdDate" : "2021-09-15T14:48:40.73", - "lastModifiedBy" : "string", - "lastModifiedDate" : "2021-09-15T14:48:40.73", - "folder" : false, - "path" : "/", - "name" : "test.txt", - "fullPath" : "/test.txt", - "size" : 32, - "sha256" : "28eb526a0b9e4a022cce7e9c6dffb11699c3c19a11b419d1b13873271a3c099e", - "md5" : "156c8805787b870939a80c708b64c946", - "metadata" : { }, - "projectId" : "project", - "repoName" : "repo" - }, - "srcProjectId": "project", - "srcRepoName": "repo", - "srcFullPath" - "eventType" : "NODE_COPIED" -} -``` - -### 删除节点 - -消息载荷 - -| 字段 | 类型 | 说明 | -| --------- | ------ | ---------------- | -| eventType | String | 触发事件类型 | -| user | Object | 触发事件用户信息 | -| node | Object | 删除的节点信息 | - -示例 - -```json -{ - "user" : { - "userId" : "string", - "name" : "string", - "email" : null, - "phone" : null, - "createdDate" : "2021-07-05T11:19:31.921", - "locked" : false, - "admin" : false - }, - "projectId" : "project", - "repoName" : "repo", - "fullPath" : "/test.txt", - "eventType" : "NODE_DELETED" -} -``` - -## 元数据事件 - -### 保存元数据 - -消息载荷 - -| 字段 | 类型 | 说明 | -| --------- | ------ | ---------------- | -| eventType | String | 触发事件类型 | -| user | Object | 触发事件用户信息 | -| node | Object | 节点信息 | -| metedata | Object | 保存的元数据 | - -示例 - -```json -{ - "user" : { - "userId" : "string", - "name" : "string", - "email" : null, - "phone" : null, - "createdDate" : "2021-07-05T11:19:31.921", - "locked" : false, - "admin" : false - }, - "node" : { - "createdBy" : "string", - "createdDate" : "2021-09-15T14:48:40.73", - "lastModifiedBy" : "string", - "lastModifiedDate" : "2021-09-15T14:48:40.73", - "folder" : false, - "path" : "/", - "name" : "test.txt", - "fullPath" : "/test.txt", - "size" : 32, - "sha256" : "28eb526a0b9e4a022cce7e9c6dffb11699c3c19a11b419d1b13873271a3c099e", - "md5" : "156c8805787b870939a80c708b64c946", - "metadata" : { }, - "projectId" : "project", - "repoName" : "repo" - }, - "metedata" : { "key" : "value" } - "eventType" : "METEDATA_SAVED" -} -``` - -### 删除元数据 - -消息载荷 - -| 字段 | 类型 | 说明 | -| ------------------- | ------ | ---------------- | -| eventType | String | 触发事件类型 | -| user | Object | 触发事件用户信息 | -| node | Object | 节点信息 | -| deletedMetedataKeys | Set | 删除的元数据Key | - -示例 - -```json -{ - "user" : { - "userId" : "string", - "name" : "string", - "email" : null, - "phone" : null, - "createdDate" : "2021-07-05T11:19:31.921", - "locked" : false, - "admin" : false - }, - "node" : { - "createdBy" : "string", - "createdDate" : "2021-09-15T14:48:40.73", - "lastModifiedBy" : "string", - "lastModifiedDate" : "2021-09-15T14:48:40.73", - "folder" : false, - "path" : "/", - "name" : "test.txt", - "fullPath" : "/test.txt", - "size" : 32, - "sha256" : "28eb526a0b9e4a022cce7e9c6dffb11699c3c19a11b419d1b13873271a3c099e", - "md5" : "156c8805787b870939a80c708b64c946", - "metadata" : { }, - "projectId" : "project", - "repoName" : "repo" - }, - "deletedMetedataKeys": ["key1","key2"] - "eventType" : "METEDATA_DELETED" -} -``` - -## 包版本事件 - -### 创建版本 - -消息载荷 - -| 字段 | 类型 | 说明 | -| -------------- | ------ | ---------------- | -| eventType | String | 触发事件类型 | -| user | Object | 触发事件用户信息 | -| packageVersion | Object | 包版本信息 | - -示例 - -```json -{ - "user" : { - "userId" : "string", - "name" : "string", - "email" : null, - "phone" : null, - "createdDate" : "2021-07-05T11:19:31.921", - "locked" : false, - "admin" : false - }, - "packageVersion" : { - "createdBy" : "string", - "createdDate" : "2021-09-15T14:48:40.73", - "lastModifiedBy" : "string", - "lastModifiedDate" : "2021-09-15T14:48:40.73", - "name" : false, - "size" : "/", - "downloads" : "test.txt", - "stageTag" : "/test.txt", - "metedata" : 32, - "tags" : "28eb526a0b9e4a022cce7e9c6dffb11699c3c19a11b419d1b13873271a3c099e", - "extension" : {"key": "value"}, - "contentPath" : "string" - }, - "eventType" : "VERSION_CREATED" -} -``` - - - diff --git a/docs/storage/apidoc/webhook/webhook.md b/docs/storage/apidoc/webhook/webhook.md deleted file mode 100644 index 77a3f535792..00000000000 --- a/docs/storage/apidoc/webhook/webhook.md +++ /dev/null @@ -1,347 +0,0 @@ -## Webhook接口 - -### Webhook公共请求参数说明 - -#### 触发器类型 - -| 枚举值 | 说明 | -| ---------------- | ----------- | -| PROJECT_CREATED | 项目创建 | -| REPO_CREATED | 仓库创建 | -| REPO_UPDATED | 仓库更新 | -| NODE_CREATED | 节点创建 | -| NODE_RENAMED | 节点重命名 | -| NODE_MOVED | 节点移动 | -| NODE_COPIED | 节点复制 | -| NODE_DELETED | 节点删除 | -| METADATA_DELETED | 元数据删除 | -| METADATA_SAVED | 元数据保存 | -| VERSION_CREATED | 版本创建 | -| WEBHOOK_TEST | webhook测试 | - -#### 关联对象类型 - -| 枚举值 | 说明 | -| ------- | ---- | -| SYSTEM | 系统 | -| PROJECT | 项目 | -| REPO | 仓库 | - -#### 关联对象Id - -association_type为PROJECT时,association_id为{projectId} - -association_type为REPO时,association_id为{projectId}:{repoName} - -### 创建webhook - -- API: POST /webhook/api/webhook/create - -- API名称: create_webhook - -- 功能说明: - - - 中文:创建webhook - - English:create webhook - -- 请求体 - - ```json - { - "url": "string", - "headers": {"key": "value"}, - "triggers": ["NODE_CREATED"], - "resourceKeyPattern": "regex pattern", - "association_type": "REPO", - "association_id": "string" - } - ``` - - | 字段 | 是否必须 | 说明 | 示例 | - | ---------------- |----------| --------------- | ------------------------- | - | url | 是 | webhook请求地址 | http://bkrepo.example.com | - | headers | 否 | 自定义请求头 | {"key" : "value"} | - | triggers | 是 | 触发事件 | ["NODE_CREATED"] | - | resourceKeyPattern | 否 | 事件资源key正则匹配模型 | (.*).apk | - | association_type | 是 | 关联对象类型 | REPO | - | association_id | 否 | 关联对象id | projectId:repoName | - - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": null - } - ``` - -### 更新webhook - -- API: PUT /webhook/api/webhook/update - -- API名称: update_webhook - -- 功能说明: - - - 中文:更新webhook - - English:update webhook - -- 请求体 - - ```json - { - "id": "string", - "url": "string", - "token": "string", - "triggers": ["NODE_CREATED"] - } - ``` - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": null - } - ``` - -### 删除webhook - -- API: DELETE /webhook/api/webhook/delete/{id} - -- API名称: delete_webhook - -- 功能说明: - - - 中文:删除webhook - - English:delete webhook - -- 请求参数 - - | 参数名 | 类型 | 说明 | - | ------ | ------ | ---------- | - | id | string | webhook id | - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": null, - "traceId": null - } - ``` - -### 查询webhook - -- API: GET /webhook/api/webhook/{id} - -- API名称: get_webhook - -- 功能说明: - - - 中文:创建webhook - - English:create webhook - -- 请求参数 - - | 参数名 | 类型 | 说明 | - | ------ | ------ | ---------- | - | id | string | webhook id | - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": { - "id": "string", - "url": "string", - "token": "string", - "triggers": ["NODE_CREATED"], - "associationType": "REPO", - "associationId": "string", - "createdBy": "string", - "createdDate": "string", - "lastModifiedBy": "string", - "lastModifiedDate": "string" - }, - "traceId": null - } - ``` - -### 查询webhook列表 - -- API: GET /webhook/api/webhook/list - -- API名称: list_webhook - -- 功能说明: - - - 中文:查询webhook列表 - - English:list webhook - -- 请求参数 - - | 参数名 | 类型 | 说明 | - | --------------- | --------------- | ------------ | - | associationId | string | 关联对象id | - | associationType | AssociationType | 关联对象类型 | - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": [{ - "id": "string", - "url": "string", - "token": "string", - "triggers": ["NODE_CREATED"], - "associationType": "REPO", - "associationId": "string", - "createdBy": "string", - "createdDate": "string", - "lastModifiedBy": "string", - "lastModifiedDate": "string" - }], - "traceId": null - } - ``` - -### 测试webhook - -- API: GET /webhook/api/webhook/test/{id} - -- API名称: test_webhook - -- 功能说明: - - - 中文:测试webhook - - English:test webhook - -- 请求参数 - - | 参数名 | 类型 | 说明 | - | ------ | ------ | ---------- | - | id | string | webhook id | - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": { - "id": "string", - "webHookUrl": "string", - "triggeredEvent": "NODE_CREATED", - "requestHeaders": { - "key": "value" - }, - "requestPayload": "string", - "status": "SUCCESS" / "FAIL", - "responseHeaders": { - "key": "value" - }, - "responseBody": "string", - "requestDuration": 100, - "requestTime": "2021-12-27T00:00:00.000", - "errorMsg": "string" - }, - "traceId": null - } - ``` - -### 重试webhook - -- API: GET /webhook/api/webhook/retry/{logId} - -- API名称: retry_webhook_request - -- 功能说明: - - - 中文:重试webhook请求 - - English:retry webhook request - -- 请求参数 - - | 参数名 | 类型 | 说明 | - | ------ | ------ | ---------------------- | - | logId | string | webhook request log id | - -- 响应体 - -```json -{ - "code": 0, - "message": null, - "data": { - "id": "string", - "webHookUrl": "string", - "triggeredEvent": "NODE_CREATED", - "requestHeaders": { - "key": "value" - }, - "requestPayload": "string", - "status": "SUCCESS", - "responseHeaders": { - "key": "value" - }, - "responseBody": "string", - "requestDuration": 100, - "requestTime": "2021-12-27T00:00:00.000", - "errorMsg": "string" - }, - "traceId": null -} -``` - -### 查询webhook请求日志列表 - -- API: GET /webhook/api/log/list/{webHookId} - -- API名称: list_webhook_log - -- 功能说明: - - - 中文:查询webhook请求日志列表 - - English:list webhook log - -- 请求参数 - - | 参数名 | 类型 | 说明 | - | --------- | ------ | ---------- | - | webHookId | string | webhook id | - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": [{ - "webhookUrl": "string", - "triggeredEvent": "NODE_UPLOADED", - "requestHeaders": "string", - "requestPayload": "string", - "status": "SUCCESS", - "responseHeaders": "string", - "responseBody": "string", - "requestDuration": "string", - "requestTime": "string", - "errorMsg": "string" - }], - "traceId": null - } - ``` - diff --git a/docs/storage/index.html b/docs/storage/index.html deleted file mode 100644 index f102e5a6ef6..00000000000 --- a/docs/storage/index.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - Document - - - - - - -
加载中...
- - - - - - diff --git a/docs/storage/install/README.md b/docs/storage/install/README.md deleted file mode 100644 index 18ea9d29c0a..00000000000 --- a/docs/storage/install/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# 蓝鲸制品库部署文档 - -- **二进制包部署** - - [说明](/install/binary/) - - [网关部署](/install/binary/gateway) - - [前端部署](/install/binary/frontend) - - [后端部署](/install/binary/backend) -- **容器化部署** - - [Helm Charts部署](/install/helm.md) -- [repo.env配置项](/install/env.md) -- [源码编译](/install/compile.md) diff --git a/docs/storage/install/_sidebar.md b/docs/storage/install/_sidebar.md deleted file mode 100644 index 352f815ca24..00000000000 --- a/docs/storage/install/_sidebar.md +++ /dev/null @@ -1,9 +0,0 @@ -- 二进制包部署 - - [说明](/install/binary/) - - [网关部署](/install/binary/gateway) - - [前端部署](/install/binary/frontend) - - [后端部署](/install/binary/backend) -- 容器化部署 - - [Helm Charts部署](/install/helm.md) -- [repo.env配置项](/install/env.md) -- [源码编译](/install/compile.md) diff --git a/docs/storage/install/binary/README.md b/docs/storage/install/binary/README.md deleted file mode 100644 index cb74a251dc1..00000000000 --- a/docs/storage/install/binary/README.md +++ /dev/null @@ -1,108 +0,0 @@ -# 安装部署 - -## 1. 部署目录说明 - -部署的目录遵循蓝鲸运营规范,这里举例以/data/bkee 作为主目录,用户可以自行更换,比如叫/a/b 都可以。目录层次多,需要仔细看,具体如下: - -```shell -|- /data/bkee # 蓝鲸根目录 - |- ci # ci部署程序目录 - |- bkrepo # bkrepo部署目录 -``` - -具体说明下以下章节。 - -### 1.1 bkrepo部署目录 - -```shell -|- /data/bkee/bkrepo # 程序主目录 - |- backend # 后端程序目录 - |- frontend # 存放的前端发布的静态资源目录 - |- gateway # 网关配置文件及lua脚本 - |- scripts # 部署脚本 - |- support-files # 配置文件目录 -``` - - -## 2.服务部署 - -### 2.1 系统要求 - -- CentOS 7.X -- jdk: 1.8 -- mongodb 3.6 -- Consul 1.0+ [Consul安装](consul.md) - - -### 2.2 设置部署环境变量 - -| 变量名 | 用途 | -| ------------ |---------------------------| -|WORK_DIR| bkrepo安装目录,以/data/bkee/为例 | -|BK_REPO_MONGODB_USER| mongodb 用户名 | -|BK_REPO_MONGODB_PASSWORD| mongodb密码 | -|BK_REPO_MONGODB_ADDR| mongodb地址 | -|BK_REPO_MONGODB_DB_NAME| mongodb数据库名 | -|BK_REPO_SERVICE_PREFIX| bkrepo服务前缀,默认为bkrepo- | -|BK_REPO_CONSUL_SERVER_HOST| bkrepo consul服务ip | -|BK_REPO_CONSUL_SERVER_PORT| bkrepo consul服务port | - -### 2.2 mongodb数据库初始化 - -将support-files/sql 目录下按文件序号顺序执行 - -```shell -mongo -u $BK_REPO_MONGODB_USER -p $BK_REPO_MONGODB_PASSWORD $BK_REPO_MONGODB_ADDR/$BK_REPO_MONGODB_DB_NAME init-data.js -``` - -### 2.2 consul配置初始化,后端配置文件渲染 - -涉及到配置文件里面有双"_"下划线定义的变量需要做占位符号替换,已经抽离到scripts/repo.env文件里: - -- scripts/repo.env 中有对应的配置项,需要进行修改,如果遇到配置项涉及到蓝鲸的或者不会用到的,则可以保持默认配置不修改即可,修改后保存退出。 - - - 修改INSTALL_PATH,这个为安装主目录,默认是/data/bkee - - 修改MODULE变量建议不要修改,默认为bkrepo - -```shell -cd $WORK_DIR/bkrepo/scripts -chmod +x render_tpl -./render_tpl -u -p $WORK_DIR -m bkrepo -e repo.env $WORK_DIR/bkrepo/support-files/templates/*.yaml -services=(auth repository dockerapi generic docker helm maven npm) -for var in ${services[@]}; -do - service=$BK_REPO_SERVICE_PREFIX$var - echo $service - curl -T $WORK_DIR/etc/bkrepo/$var.yaml http://$BK_REPO_CONSUL_SERVER_HOST:$BK_REPO_CONSUL_SERVER_PORT/v1/kv/bkrepo-config/$service/data -done -curl -T $WORK_DIR/etc/bkrepo/application.yaml http://$BK_REPO_CONSUL_SERVER_HOST:$BK_REPO_CONSUL_SERVER_PORT/v1/kv/bkrepo-config/application/data -echo "put config to consul kv success." -``` - - -## 3 程序部署 - -### 3.1 网关部署 - -采用OpenResty作为网关服务器,部署主要分为OpenResty安装, gateway的lua和nginx配置代码部署两部分。 - - - -### 3.2 前端部署 - -- [前端编译](frontend.md),对编译有兴趣可以自行研究 - -前端配置文件渲染 - -```shell -cd $WORK_DIR/bkrepo/scripts -chmod +x render_tpl -./render_tpl -u -p /data/bkee -m bkrepo -e repo.env /data/workspace/frontend/ui/frontend#ui#index.html -``` - -### 3.3 后端微服务部署 - -- [后端服务部署](backend.md) - - - diff --git a/docs/storage/install/binary/backend.md b/docs/storage/install/binary/backend.md deleted file mode 100644 index bb65e78daf1..00000000000 --- a/docs/storage/install/binary/backend.md +++ /dev/null @@ -1,59 +0,0 @@ -# 后端微服务部署 - -蓝鲸ci后端(backend目录下)有如下微服务 -- auth -- repository -- generic -- docker (如需要docker仓库服务) -- helm (如需要helm仓库服务) -- npm (如需要npm仓库服务) -- rpm (如需要rpm仓库服务) -- pypi(如需要pypi仓库服务) -- maven (如需要maven仓库服务) - -## 1.服务器要求 - -jdk: 1.8 ,java 运行时 -consul: 1.0 (服务器本地启动consul agent,并且加入到consul 服务集群),用作配置中心与服务发现 - - -## 微服务部署 - -### 2.1 设置部署环境变量 - -| 变量名 | 用途 | -| ------------ | ---------------- | -|BK_REPO_LOGS_DIR|bkrepo日志目录| -|BK_REPO_JVM_XMS|java进程启动占用内存大小| -|BK_REPO_ENV|部署环境,prod|test|dev| -|BK_REPO_CONSUL_SERVER_HOST|consul server host| -|BK_REPO_CONSUL_SERVER_PORT |consul server port| -|MODULE |微服务模块名称,比如auth,repository| - -### 2.2 服务启动 - -在部署服务器上的示例/data/bkee/的主目录下 - -微服务启动脚本,以auth微服务为例,建立auth.sh脚本 - -```shell -mkdir -p $BK_REPO_LOGS_DIR -java -server \ - -Dsun.jnu.encoding=UTF-8 \ - -Dfile.encoding=UTF-8 \ - -Xloggc:$BK_REPO_LOGS_DIR/gc.log \ - -XX:+PrintTenuringDistribution \ - -XX:+PrintGCDetails \ - -XX:+PrintGCDateStamps \ - -XX:+HeapDumpOnOutOfMemoryError \ - -XX:HeapDumpPath=oom.hprof \ - -XX:ErrorFile=error_sys.log \ - -Xms$BK_REPO_JVM_XMS \ - -Xmx$BK_REPO_JVM_XMX \ - -jar $MODULE.jar \ - --spring.profiles.active=$BK_REPO_ENV \ - --spring.cloud.consul.host=$BK_REPO_CONSUL_SERVER_HOST \ - --spring.cloud.consul.port=$BK_REPO_CONSUL_SERVER_PORT -``` -- 启动微服务:以auth微服务为例 /data/bkee/bkrepo/backend/auth.sh - diff --git a/docs/storage/install/binary/consul.md b/docs/storage/install/binary/consul.md deleted file mode 100644 index b1f61ba3254..00000000000 --- a/docs/storage/install/binary/consul.md +++ /dev/null @@ -1,51 +0,0 @@ -## Consul部署 - -### 系统要求 - -- Consul 1.0及以上版本 - -### consul安装及启动 - -- consul下载 -从这里选择对应的操作系统下载[consul](https://releases.hashicorp.com/consul/1.0.2/)并解压 - -- consul安装 - -将consul应用上传到服务器上,修改文件权限后,作为全局应用放到`/usr/local/sbin/`目录下。 -```shell -# 修改consul程序mod -chmod 755 ./consul -# 将consul程序放到`/usr/local/sbin/`即可 -cp ./consul /usr/local/sbin/ -``` - -- consul 服务端启动 - -```shell -consul agent -server -data-dir={consul_directory} -ui -http-port={consul_http_port} -datacenter=bk-repo -domain=bk-repo -bootstrap -client=0.0.0.0 -# 例子:consul server服务器IP=10.10.10.1 -consul agent -server -data-dir=/data/consul -ui -http-port=8080 -datacenter=bk-repo -domain=bk-repo -bootstrap -client=0.0.0.0 -``` - -- consul 客户端启动 - -```shell -consul agent -data-dir={consul_directory} -datacenter=bk-repo -domain=bk-repo -join={server_IP} -bind={local_IP} - -# 例子:consul client服务器IP=10.10.10.2 -consul agent -data-dir=/data/consul -datacenter=bk-repo -domain=bk-repo -join=10.10.10.1 -bind=10.10.10.2 -``` - -如果你的服务是部署也是部署在consul服务端的话,那就不需要启动consul客户端,直接连接服务端即可 - -- 参数说明 - -| 参数名称 | 参数说明 | -| ------------ | ---------------- | -| consul_directory | consul的数据目录 | -| consul_http_port | consul管理界面的访问端口 | -| server_IP | 服务端的IP地址 | -| local_IP | 当前机器的IP地址 | - -- 验证 -登录网页验证: http://{service_IP}:8080 diff --git a/docs/storage/install/binary/frontend.md b/docs/storage/install/binary/frontend.md deleted file mode 100644 index ae232feeb0e..00000000000 --- a/docs/storage/install/binary/frontend.md +++ /dev/null @@ -1,22 +0,0 @@ -# bkrepo 前端编译文档 - -## 系统要求 - -nodejs版本 8.0.0及以上 - -## 编译说明 - -- 1、打包并部署相应的vue工程 -进入到src/frontend目录下 - -```shell -# 先全局安装yarn -npm install -g yarn -# 然后执行install -yarn install -# 然后安装每个子服务的依赖 -yarn start -# 最后执行打包命令 -yarn public -``` - diff --git a/docs/storage/install/compile.md b/docs/storage/install/compile.md deleted file mode 100644 index 52e8ec0688a..00000000000 --- a/docs/storage/install/compile.md +++ /dev/null @@ -1,2 +0,0 @@ -# 源码编译 -*TODO* \ No newline at end of file diff --git a/docs/storage/install/env.md b/docs/storage/install/env.md deleted file mode 100644 index 424578df89f..00000000000 --- a/docs/storage/install/env.md +++ /dev/null @@ -1,158 +0,0 @@ -# repo.env配置项说明 - -## 环境配置项 - -| 配置项 | 说明 | 示例 | -| ----------- | -------- | ----------------- | -| BK_REPO_ENV | 部署环境 | dev / test / prod | - - - -## 网关配置项 - -| 配置项 | 说明 | 示例 | -| ------------------------------- | ------------------- |-------------------------------------------------------------------------------------------------------| -| BK_REPO_HOST | bkrepo主机地址 | bkrepo.example.com | -| BK_REPO_UI_HOST | bkrepo前端主机地址 | bkrepo.example.com | -| BK_REPO_HTTP_PORT | bkrepo http端口 | 80 | -| BK_REPO_HTTPS_PORT | bkrepo https端口 | 443 | -| BK_REPO_APIGW_URL | bkrepo api网关url | | -| BK_REPO_APP_CODE | bkrepo app code | | -| BK_REPO_APP_TOKEN | bkrepo app token | | -| BK_REPO_HOME | bkrepo部署目录 | /data/bkce | -| BK_REPO_LOGS_DIR | bkrepo日志目录 | /data/logs | -| BK_REPO_PAAS_FQDN | bkrepo paas fqdn | paas.example.com | -| BK_REPO_PAAS_LOGIN_URL | 蓝鲸paas登录地址 | http://paas.example.com:80/login/?c_url= | -| BK_REPO_AUTHORIZATION | bkrepo认证token | Platform MThiNjFjOWMtOTAxYi00ZWEzLTg5YzMtMWY3NGJlOTQ0YjY2OlVzOFpHRFhQcWs4NmN3TXVrWUFCUXFDWkxBa00zSw== | -| BK_REPO_GATEWAY_CORS_ALLOW_LIST | 网关跨域允许列表 | | -| BK_REPO_GATEWAY_DNS_ADDR | 网关dns解析服务地址 | 127.0.0.1:53 | -| BK_REPO_SERVICE_PREFIX | bkrepo微服务前缀 | bkrepo- | -| BK_REPO_DEPLOY_MODE | bkrepo部署模式 | standalone / ci | - -## consul配置项 - -| 配置项 | 说明 | 示例 | -| -------------------------- | --------------- | --------- | -| BK_REPO_CONSUL_DNS_HOST | consul host | 127.0.0.1 | -| BK_REPO_CONSUL_DNS_PORT | consul dns端口 | 53 | -| BK_REPO_CONSUL_SERVER_HOST | consul host | 127.0.0.1 | -| BK_REPO_CONSUL_SERVER_PORT | consul http端口 | 8500 | -| BK_REPO_CONSUL_DOMAIN | consul domain | bk-repo | -| BK_REPO_CONSUL_TAG | consul tag | bkce | - -## redis配置项 - -| 配置项 | 说明 | 示例 | -| ---------------------------- | --------------- | --------- | -| BK_REPO_REDIS_HOST | reids host | 127.0.0.1 | -| BK_REPO_REDIS_ADMIN_PASSWORD | redis admin密码 | | -| BK_REPO_REDIS_PORT | redis端口 | 6379 | - -## application配置项 - -| 配置项 | 说明 | 示例 | -| ------------------------ | --------------------------------------------------- | -------------------------- | -| BK_REPO_STORAGE_TYPE | 存储方式 | filesystem / innercos | -| BK_REPO_FILE_PATH | 文件系统存储路径 | /data/storage | -| BK_REPO_COS_SECRET_ID | 对象存储secret id | | -| BK_REPO_COS_SECRET_KEY | 对象存储secret key | | -| BK_REPO_COS_REGION | 对象存储区域 | ap-guangzhou | -| BK_REPO_COS_BUCKET | 对象存储桶 | example-123456 | -| BK_REPO_CACHE_ENABLE | 是否启动存储缓存。存储缓存使用分布式文件系统,如cfs | true / false | -| BK_REPO_CACHE_MOUNT_PATH | 存储缓存挂载路径 | /data/bkrepo | -| BK_REPO_CACHE_EXPIRE_DAY | 存储缓存过期天数, -1表示永不过期 | | -| BK_REPO_MONGODB_URI | mongodb连接uri | mongodb://127.0.0.1/bkrepo | - - - -## repository配置项 - -| 配置项 | 说明 | 示例 | -| ----------------------- | ------------------ | ----- | -| BK_REPO_REPOSITORY_PORT | repository服务端口 | 25901 | - - - -## auth配置项 - -| 配置项 | 说明 | 示例 | -| ------------------------- | -------------------- | -------------------------------- | -| BK_REPO_AUTH_PORT | auth服务端口 | 25902 | -| BK_REPO_AUTH_REALM | auth realm | devops | -| BK_IAM_PRIVATE_URL | 蓝鲸iam url | http://iam.service.consul:8080 | -| BK_PAAS_PRIVATE_URL | 蓝鲸paas url | http://paas.service.consul | -| BK_REPO_IAM_CALLBACK_USER | 蓝鲸iam 回调用户 | | -| BK_REPO_IAM_ENV | 蓝鲸iam环境 | prod | -| BK_REPO_IAM_HOST | 蓝鲸iam主机地址 | iam.service.consul | -| BK_REPO_IAM_HTTP_PORT | 蓝鲸iam http端口 | 80 | -| BK_REPO_IAM_IP0 | 蓝鲸iam ip | iam.service.consul | -| BK_REPO_IAM_TOKEN_URL | 蓝鲸iam获取token url | /bkiam/api/v1/auth/access-tokens | -| BK_CI_AUTH_ENV | 蓝盾auth环境 | prod | -| BK_CI_PUBLIC_URL | 蓝盾url | http://devops.example.com | -| BK_CI_AUTH_TOKEN | 蓝盾auth token | | -| BK_REPO_SSM_ENV | 蓝鲸ssm环境 | prod | -| BK_REPO_SSM_HOST | 蓝鲸ssm主机地址 | bkssm.service.consul | -| BK_REPO_SSM_HTTP_PORT | 蓝鲸ssm http端口 | 5000 | -| BK_REPO_SSM_IP0 | 蓝鲸ssm ip | bkssm.service.consul | - -## docker api配置项 - -| 配置项 | 说明 | 示例 | -| ------------------------------------- | ------------------- | ------------------------- | -| BK_REPO_DOCKERAPI_PORT | docker api服务端口 | 25906 | -| BK_REPO_DOCKERAPI_REALM | docker api realm | bkrepo | -| BK_REPO_DOCKERAPI_HARBOR_URL | harbor url | | -| BK_REPO_DOCKERAPI_HARBOR_USERNAME | harbor用户名 | | -| BK_REPO_DOCKERAPI_HARBOR_PASSWORD | harbor密码 | | -| BK_REPO_DOCKERAPI_HARBOR_IMAGE_PREFIX | harbor image prefix | | -| BK_SSM_PRIVATE_URL | 蓝鲸ssm url | http://ssm.service.consul | - -## generic配置项 - -| 配置项 | 说明 | 示例 | -| -------------------- | --------------- | ----- | -| BK_REPO_GENERIC_PORT | generic服务端口 | 25801 | - -## docker配置项 - -| 配置项 | 说明 | 示例 | -| ------------------------- | ---------------- | ------------------------- | -| BK_REPO_DOCKER_PORT | docker服务端口 | 25906 | -| BK_REPO_DOCKER_HOST | docker主机地址 | docker.bkrepo.example.com | -| BK_REPO_DOCKER_HTTP_PORT | docker http端口 | 80 | -| BK_REPO_DOCKER_HTTPS_PORT | docker https端口 | 443 | -| BK_REPO_DOCKER_CERT_KEY | docker 证书key | | -| BK_REPO_DOCKER_CERT_PEM | docker 证书pem | | - -## maven配置项 - -| 配置项 | 说明 | 示例 | -| ------------------ | ------------- | ----- | -| BK_REPO_MAVEN_PORT | maven服务端口 | 25803 | - -## npm配置项 - -| 配置项 | 说明 | 示例 | -| ---------------- | ----------- | ----- | -| BK_REPO_NPM_PORT | npm服务端口 | 25804 | - -## pypi配置项 - -| 配置项 | 说明 | 示例 | -| ----------------- | ------------ | ----- | -| BK_REPO_PYPI_PORT | pypi服务端口 | 25805 | - -## helm配置项 - -| 配置项 | 说明 | 示例 | -| ---------------------- | ------------- | ----------------------- | -| BK_REPO_HELM_PORT | helm服务端口 | 25806 | -| BK_REPO_HELM_HOST | helm主机地址 | helm.bkrepo.example.com | -| BK_REPO_HELM_HTTP_PORT | helm http端口 | 80 | - -## git配置项 - -| 配置项 | 说明 | 示例 | -| ---------------- | ----------- | ----- | -| BK_REPO_GIT_PORT | git服务端口 | 25810 | - diff --git a/docs/storage/install/helm.md b/docs/storage/install/helm.md deleted file mode 100644 index 4f922e8c26f..00000000000 --- a/docs/storage/install/helm.md +++ /dev/null @@ -1,419 +0,0 @@ -# BK-REPO - -此Chart用于在Kubernetes集群中通过helm部署bkrepo - -## 环境要求 -- Kubernetes 1.12+ -- Helm 3+ -- PV provisioner - -## 安装Chart -使用以下命令安装名称为`bkrepo`的release, 其中``代表helm仓库地址: - -```shell -$ helm repo add bkee -$ helm install bkrepo bkee/bkrepo -``` - -上述命令将使用默认配置在Kubernetes集群中部署bkrepo, 并输出访问指引。 - -## 卸载Chart -使用以下命令卸载`bkrepo`: - -```shell -$ helm uninstall bkrepo -``` - -上述命令将移除所有和bkrepo相关的Kubernetes组件,并删除release。 - -## Chart依赖 -- [bitnami/nginx-ingress-controller](https://github.com/bitnami/charts/tree/master/bitnami/nginx-ingress-controller) -- [bitnami/mongodb](https://github.com/bitnami/charts/blob/master/bitnami/mongodb) - -## 配置说明 -下面展示了可配置的参数列表以及默认值 - -### Charts 全局设置 - -|参数|描述|默认值 | -|---|---|---| -| `global.imageRegistry` | Global Docker image registry | `nil` | -| `global.imagePullSecrets` | Global Docker registry secret names as an array | `[]` (does not add image pull secrets to deployed pods) | -| `global.storageClass` | Global storage class for dynamic provisioning | `nil` | - -### Kubernetes组件公共配置 - -下列参数用于配置Kubernetes组件的公共属性,一份配置作用到每个组件 - -|参数|描述|默认值 | -|---|---|---| -| `commonAnnotations` | Annotations to add to all deployed objects | `{}` | -| `commonLabels` | Labels to add to all deployed objects | `{}` | - -### Kubernetes组件通用配置 - -下列参数表示Kubernetes组件的通用配置,每个微服务进行单独配置。能够配置的微服务有: - -- gateway -- repository -- auth -- generic -- docker -- npm -- pypi -- helm - -|参数|描述|默认值 | -|---|---|---| -| `image.registry` | 镜像仓库 | `mirrors.tencent.com` | -| `image.repository` | 镜像名称 | `bkrepo/xxx` | -| `image.tag` | 镜像tag | `{TAG_NAME}` | -| `image.pullPolicy` | 镜像拉取策略 | `IfNotPresent` | -| `image.pullSecrets` | 镜像拉取Secret名称数组 | `[]` | -| `imagePullSecrets` | 镜像拉取secret名称列表 | `[]` | -| `securityContext` | 容器 Security Context | `{}` | -| `replicaCount` | Number of pod replicas | `2` | -| `hostAliases` | Add deployment host aliases | `[]` | -| `resources.limits` | The resources limits for containers | `{}` | -| `resources.requests` | The requested resources for containers | `{}` | -| `affinity` | Affinity for pod assignment (evaluated as a template) | `{}` | -| `containerSecurityContext.enabled` | Enable containers' Security Context | `false` | -| `containerSecurityContext.runAsUser` | Containers' Security Context | `1001` | -| `containerSecurityContext.runAsNonRoot` | Containers' Security Context Non Root | `true` | -| `nodeAffinityPreset.key` | Node label key to match Ignored if `affinity` is set. | `""` | -| `nodeAffinityPreset.type` | Node affinity preset type. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `""` | -| `nodeAffinityPreset.values` | Node label values to match. Ignored if `affinity` is set. | `[]` | -| `nodeSelector` | Node labels for pod assignment | `{}` (evaluated as a template) | -| `podLabels` | Add additional labels to the pod (evaluated as a template) | `nil` | -| `podAnnotations` | Pod annotations | `{}` (evaluated as a template) | -| `podAffinityPreset` | Pod affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `""` | -| `podAntiAffinityPreset` | Pod anti-affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `""` | -| `podSecurityContext.enabled` | Enable pod security context | `true` | -| `podSecurityContext.fsGroup` | fsGroup ID for the pod | `1001` | -| `priorityClassName` | Define the priority class name for the pod. | `""` | -| `tolerations` | Tolerations for pod assignment | `[]` (evaluated as a template) | - -### RBAC配置 - -|参数|描述|默认值 | -|---|---|---| -| `rbac.create` | If true, create & use RBAC resources | `true` | -| `serviceAccount.annotations` | Annotations for service account | `{}` | -| `serviceAccount.create` | If true, create a service account | `false` | -| `serviceAccount.name` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template. | `` | - -### ingress 配置 - -|参数|描述|默认值 | -|---|---|---| -| `ingress.enabled` | 是否创建ingress | `true` | -| `annotations` | ingress标注 | Check `values.yaml` | - -### nginx-ingress-controller 配置 - -默认将部署`nginx-ingress-controller`,如果不需要可以关闭。 -相关配置请参考[bitnami/nginx-ingress-controller](https://github.com/bitnami/charts/tree/master/bitnami/) - -|参数|描述|默认值 | -|---|---|---| -| `nginx-ingress-controller.enabled` | 是否部署nginx ingress controller | `true` | -| `nginx-ingress-controller.defaultBackend.enabled` | nginx ingress controller默认backend | `false` | - -### mongodb 配置 -默认将部署mongodb,如果不需要可以关闭。 -相关配置请参考[bitnami/mongodb](https://github.com/bitnami/charts/blob/master/bitnami/mongodb) - -|参数|描述|默认值 | -|---|---|---| -| `mongodb.enabled` | 是否部署mognodb。如果需要使用外部数据库,设置为`false`并配置`externalMongodb` | `true` | -| `mongodb.auth.enabled` | 是否开启认证 | `true` | -| `mongodb.auth.database` | mongodb数据库名称 | `bkrepo` | -| `mongodb.auth.username` | mongodb认证用户名 | `bkrepo` | -| `mongodb.auth.password` | mongodb密码 | `bkrepo` | -| `externalMongodb.uri` | 外部mongodb服务的连接地址。当`mongodb.enabled`配置为`false`时,bkrepo将使用此参数连接外部mongodb | `mongodb://bkrepo:bkrepo@localhost:27017/bkrepo` | - -> 如果需要持久化mongodb数据,请参考[bitnami/mongodb](https://github.com/bitnami/charts/blob/master/bitnami/mongodb)配置存储卷 - -### 数据持久化配置 - -数据持久化配置, 当使用filesystem方式存储时需要配置。 - -|参数|描述|默认值 | -|---|---|---| -| `persistence.enabled` | 是否开启数据持久化,false则使用emptyDir类型volume, pod结束后数据将被清空,无法持久化 | `true` | -| `persistence.accessMode` | PVC Access Mode for bkrepo data volume | `ReadWriteOnce` | -| `persistence.size` | PVC Storage Request for bkrepo data volume | `100Gi` | -| `persistence.storageClass` | 指定storageClass。如果设置为"-", 则禁用动态卷供应; 如果不设置, 将使用默认的storageClass(minikube上是standard) | `nil` | -| `persistence.existingClaim` | 如果开启持久化并且定义了该项,则绑定k8s集群中已存在的pvc | `nil` | - -> 如果开启数据持久化,并且没有配置`existingClaim`,将使用[动态卷供应](https://kubernetes.io/docs/concepts/storage/dynamic-provisioning/)提供存储,使用`storageClass`定义的存储类。**在删除该声明后,这个卷也会被销毁(用于单节点环境,生产环境不推荐)。**。 - -### bkrepo公共配置 - -|参数|描述|默认值 | -|---|---|---| -| `common.imageRegistry` | bkrepo镜像仓库全局配置, 具有最高优先级 | `""` | -| `common.imageTag` | bkrepo镜像tag全局配置, 具有最高优先级 | `""` | -| `common.region` | 部署区域, 可不填 | `""` | -| `common.jvmOption` | jvm启动选项, 如-Xms1024M -Xmx1024M | `""` | -| `common.springProfile` | SpringBoot active profile | `dev` | -| `common.username` | bkrepo初始用户名 | `admin` | -| `common.password` | bkrepo初始密码 | `blueking` | -| `common.mountPath` | pod volume挂载路径 | `/data/storage` | -| `common.config.storage.type` | 存储类型,支持filesystem/cos/s3/hdfs | `filesystem` | -| `common.config.storage.filesystem.path` | filesystem存储方式配置,存储路径 | `/data/storage` | -| `common.config.storage.cos` | cos存储方式配置 | `nil` | -| `common.config.storage.s3` | s3存储方式配置 | `nil` | -| `common.config.storage.hdfs` | hdfs存储方式配置 | `nil` | - -### 数据初始化job配置 - -|参数|描述|默认值 | -|---|---|---| -| `init.mongodb.enabled` | 是否初始化mongodb数据,支持幂等执行 | `true` | -| `init.mongodb.image` | mongodb job镜像拉取相关配置 | Check `values.yaml` | - - -### 网关配置 - -**以下为除Kubernetes组件通用配置之外的配置列表** - -|参数|描述|默认值 | -|---|---|---| -| `gateway.service.type` | 服务类型 | `ClusterIP` | -| `gateway.service.port` | 服务类型为`ClusterIP`时端口设置 | `80` | -| `gateway.service.nodePort` | 服务类型为`NodePort`时端口设置 | `80` | -| `gateway.host` | bkrepo 地址 | `bkrepo.example.com` | -| `gateway.dnsServer` | dns服务器地址,用于配置nginx resolver | `local=on`(openrestry语法,取本机`/etc/resolv.conf`配置) | -| `gateway.authorization` | 网关访问微服务认证信息 | `"Platform MThiNjFjOWMtOTAxYi00ZWEzLTg5YzMtMWY3NGJlOTQ0YjY2OlVzOFpHRFhQcWs4NmN3TXVrWUFCUXFDWkxBa00zSw=="` | -| `gateway.deployMode` | 部署模式,standalone: 独立模式,ci: 与ci搭配模式 | `standalone` | - -### repository服务配置 - -**以下为除Kubernetes组件通用配置之外的配置列表** - -|参数|描述|默认值 | -|---|---|---| -| `repository.config.deletedNodeReserveDays` | 节点被删除后多久清理数据 | `15` | - -### auth服务配置 - -**以下为除Kubernetes组件通用配置之外的配置列表** - -|参数|描述|默认值 | -|---|---|---| -| `auth.config.realm` | 认证realm类型,支持local/devops | `local` | - -### generic服务配置 - -**以下为除Kubernetes组件通用配置之外的配置列表** - -|参数|描述|默认值 | -|---|---|---| -| `generic.enabled` | 是否部署generic | `true` | -| `generic.config.domain` | generic domain地址 | `${gateway.host}/generic` | - -### docker registry服务配置 - -**以下为除Kubernetes组件通用配置之外的配置列表** - -|参数|描述|默认值 | -|---|---|---| -| `docker.enabled` | 是否部署docker | `false` | -| `docker.config ` | docker配置 | `{}` | - -### npm registry服务配置 - -**以下为除Kubernetes组件通用配置之外的配置列表** - -|参数|描述|默认值 | -|---|---|---| -| `npm.enabled` | 是否部署npm | `false` | -| `npm.config.domain` | npm domain地址 | `${gateway.host}/npm` | - -### pypi registry服务配置 - -**以下为除Kubernetes组件通用配置之外的配置列表** - -|参数|描述|默认值 | -|---|---|---| -| `pypi.enabled` | 是否部署pypi | `false` | -| `pypi.config.domain` | pypi domain地址 | `${gateway.host}/pypi` | - -### helm registry服务配置 - -**以下为除Kubernetes组件通用配置之外的配置列表** - -|参数|描述|默认值 | -|---|---|---| -| `helm.enabled` | 是否部署helm | `false` | -| `helm.config` | helm配置 | `{}` | - - -您可以通过`--set key=value[,key=value]`来指定参数进行安装。例如, - -```shell -$ helm install bkrepo bkee/bkrepo \ - --set global.imageRegistry=your.registry.com \ - --set gateway.host=bkrepo.example.com -``` - - -另外,也可以通过指定`YAML`文件的方式来提供参数, - -```shell -$ helm install bkrepo bkee/bkrepo -f values -``` - -可以使用`helm show values`来获取默认配置, - -```shell -# 查看默认配置 -$ helm show values bkee/bkrepo - -# 保存默认配置到文件values.yaml -$ helm show values bkee/bkrepo > values.yaml -``` - -## 配置案例 - -### 1. 使用已有的mongodb -``` -# 关闭mongodb部署 -mongodb.enabled=false -# 设置已有的mongod连接字符串 -common.mongodb.uri=mongodb://user:pass@mongodb-server:27017/bkrepo -``` - -### 2. 使用已有的ingress-controller -``` -# 关闭nginx-ingress-controller部署 -nginx-ingress-controller.enabled=false - -# 根据需要配置ingress annotations -# ingress.annotations.key=value -``` - -### 3. 使用动态卷分配 - -通过使用storageClass动态绑定pv,假设我们创建了一个`storageClassName`为`standard`的pv, - -```yaml -# pv.yaml -apiVersion: v1 -kind: PersistentVolume -metadata: - name: bkrepo-pv -spec: - capacity: - storage: 100Gi - accessModes: - - ReadWriteOnce - storageClassName: "standard" # minikube默认使用storageClass是standard - hostPath: - path: "/data/bkrepo" -``` - -```shell -$ kubectl create -f pv.yaml -``` - -因为在minikube默认使用storageClass是standard,所以使用默认配置进行部署,bkrepo以及mongodb的pvc将自动绑定到这个pv上。 - -同时,我们也可以指定自定义的`storageClass`, - -``` -# 开启数据持久化 -persistence.enabled=true -persistence.storageClass=standard -persistence.accessModes=访问模式 -persistence.size=pvc大小 - -# 如果有需要,同时配置mongodb持久化 -mongodb.persistence.enabled=true -mongodb.persistence.storageClass=standard -``` - -也可以设置全局`storageClass`,将同时应用到bkrepo和mongodb中 -``` -global.storageClass=standard -``` - -### 4. 使用已有的pvc - -``` -# 开启数据持久化 -persistence.enabled=true -persistence.existingClaim=your-persistent-volume-claim -persistence.accessModes=访问模式 -persistence.size=pvc大小 - -# 如果有需要,同时配置mongodb持久化 -mongodb.persistence.enabled=true -mongodb.persistence.existingClaim=your-persistent-volume-claim -``` - -### 5. 内网环境下,使用代理镜像仓库 - -- 单独修改 -``` -# 修改mongodb镜像仓库 -mongodb.image.registry=xxx -# 修改nginx-ingress-controller镜像仓库 -nginx-ingress-controller.image.registry=xxx -# 修改bkrepo镜像仓库,xxx代表服务名称 -xxx.image.registry=xxx -``` - -- 全局修改,应用到所有Charts -``` -global.imageRegistry=xxx -``` - -### 6. 配置不同的服务暴露方式 - -默认通过Ingress暴露服务,也可以使用以下方式: - -- 使用NodePort直接访问 - -``` -ingress.enabled=false -nginx-ingress-controller.enabled=false -gateway.service.type=NodePort -gateway.service.nodePort=30000 -``` -部署成功后,即可通过 bkrepo.example.com:\ 访问(您仍需要配置dns解析) - -- 使用port-forward访问 -``` -ingress.enabled=false -nginx-ingress-controller.enabled=false -gateway.service.type=ClusterIP -``` - -部署成功后,通过`kubectl port-forward`将`bkrepo-gateway`服务暴露出去,即可通过 bkrepo.example.com:\ 访问(您仍需要配置dns解析) -```shell -kubectl port-forward service/bkrepo-gateway :80 -``` - -## 常见问题 - -**1. 首次启动失败,是bkrepo Chart有问题吗** - -答: bkrepo的Chart依赖了`mongodb`和`nignx-ingress-controller`, 这两个依赖的Chart默认从docker.io拉镜像,如果网络不通或被docker hub限制,将导致镜像拉取失败,可以参考配置列表修改镜像地址。 - -**2. 首次启动时间过长,且READY状态为`0/1`?** - -答: 如果选择了部署`mongodb Chart`,需要等待`mongodb`部署完成后,`bkrepo`相关容器才会启动;启动过程涉及到数据表以及索引创建,这个期间容器状态为`Not Ready`。 - -**3. 我卸载了Release立即重新部署,Pod状态一直为`Pending`?** - -答: 如果选择了默认方式使用动态卷供应,当使用`helm uninstall`卸载Release,随后创建的pvc也会被删除,如果在pvc被删除之前重新部署,新启动的`Pod`会进入`Pending`状态。 - -**4. 如何查看日志?** - -答: 有两种方式可以查看日志: 1. kubectl logs pod 查看实时日志 2.日志保存在/data/workspace/logs目录下,可以进入容器内查看 - -**5. 为什么卸载之后重新安装,mongodb以及文件数据都没了?** - -答: 默认创建的pv其`RECLAIM POLICY`为`DELETE`, 在删除该声明后,卷也会被销毁。如果需要数据持久化,请提前创建pvc好并设置`persistence`, \ No newline at end of file diff --git a/docs/storage/repository/client.md b/docs/storage/repository/client.md deleted file mode 100644 index 3ccb3caaa06..00000000000 --- a/docs/storage/repository/client.md +++ /dev/null @@ -1,6 +0,0 @@ -### client容器启动方式 - -```sh -docker run -ti -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker bkrepo/client:latest /bin/bash -``` -- 需要把母机的docker挂载进去,方便再容器中执行docker命令 \ No newline at end of file diff --git a/docs/storage/repository/composer.md b/docs/storage/repository/composer.md deleted file mode 100644 index f6360196366..00000000000 --- a/docs/storage/repository/composer.md +++ /dev/null @@ -1,98 +0,0 @@ -## composer仓库使用指引 - -#### 添加仓库: -```bash -#composer 不支持virtual仓库 -curl -X POST http://{bk_repo_addr}/repository/repo/create \ --H 'Content-Type: application/json' \ --d '{ - "projectId": "projectName", - "name": "repositoryName", - "type": "COMPOSER", - "category": "LOCAL|REMOTE", - "public": true, - "configuration": {"type": "local|remote"} -}' -``` - -**目前支持包文件压缩格式后缀:tar , zip , tar.gz , tgz** - -全局换源 - -```bash -#首先把默认的源给禁用掉 -composer config -g secure-http false -#再修改镜像源 -composer config -g repo.packagist composer http://{bk_repo_addr}/{projectId}/{repoName} -#修改成功后可以先查看一下配置 -composer config -g -l -#第二行repositories.packagist.org.url -``` - - - -1、局部换源(仅对当前项目有效) - -在当前项目下的composer.json中添加 - -```json -{ - "repositories": [ - { - "type": "composer", - "url": "http://{bk_repo_addr}/{projectId}/{repoName}" - } - ] -} -``` - - - -#### upload: - -```bash -#通过curl 上传 -curl -u {username}:{password} "http://{bk_repo_addr}/{projectId}/{repoName}/fileName" -T filePath -#Example -curl -u admin:password "http://{bk_repo_addr}/{projectId}/{repoName}/monolog-2.0.3.tar.gz" -T ~/Users/abc/monolog-2.0.3.tar.gz - -``` - - - -#### install: - -在php项目下执行: - -```bash -composer.phar install -``` - -在项目中添加依赖: - -```json -{ - "name": "canway/test", - "repositories": [{ - "type": "composer", - "url": "http://{bk_repo_addr}/{projectId}/{repoName}" //添加依赖源 - } - ], - "config": { - "secure-http" : false //http支持 - }, - "require": { - "php-http/httplug" : "2.0.0" //添加依赖的php包 - }, - "version": "1.0.0" -} -``` - - - -#### search: - -```bash -composer search packageName -``` - diff --git a/docs/storage/repository/helm.md b/docs/storage/repository/helm.md deleted file mode 100644 index 019d23d06f2..00000000000 --- a/docs/storage/repository/helm.md +++ /dev/null @@ -1,60 +0,0 @@ -### 操作指引 - -______ - -1、新建项目和仓库 test/helm-local - -2、helm添加仓库源 - -```powershell -$ helm repo add localhost http://localhost:10021/test/helm-local/ -``` - -3、显示仓库列表 - -```powershell -$ helm repo list -``` - -4、上传包 - -```powershell -# 创建helm包 -$ helm create mychart -# 打包 -$ helm package ./ -# 上传 -$ helm push mychart-0.1.0.tgz localhost -``` - -5、install - -```powershell -# 下载会提示先执行repo update操作 -$ helm repo update -# 下载指定包 -$ helm install localhost/mychart -``` - -6、查询相关接口 - -```powershell -# 通过postman测试即可 - -# 查询仓库所有chart -# GET /api/charts - list all charts -$ http://localhost:10021/test/helm-local/api/charts - -# 查询某个chart -# GET /api/charts/ - list all versions of a chart -$ http://localhost:10021/test/helm-local/api/charts/mychart - -# 查询指定版本的chart -# GET /api/charts// - describe a chart version -$ http://localhost:10021/test/helm-local/api/charts/mychart/0.1.0 - - -HEAD /api/charts/ - check if chart exists (any versions) -HEAD /api/charts// - check if chart version exists -``` - diff --git a/docs/storage/repository/maven-ext.md b/docs/storage/repository/maven-ext.md deleted file mode 100644 index 8959eb2b121..00000000000 --- a/docs/storage/repository/maven-ext.md +++ /dev/null @@ -1,69 +0,0 @@ -# maven 扩展接口 - - - -## GAVC 搜索接口 - -- API: GET /ext/search/gavc/{projectId}?g={groupId}&a={artifactId}&v={version}&c{classifier}&repos={repo[,repo]} - -- API 名称: gavc_search - -- 功能说明: - - - 中文:maven 制品 gavc 搜索 - - English:search maven artifact with gavc - -- 请求体 - 此接口请求体为空 - -- 请求字段说明 - - **g ,a ,v ,c 四个查询条件不能全为空** - - | 字段 | 类型 | 是否必须 | 默认值 | 说明 | Description | - | --------- | ------ | -------- | ------ | ---------- | ------------ | - | projectId | string | 是 | 无 | 项目名称 | project name | - | g | string | 否 | 无 | groupID | groupID | - | a | string | 否 | 无 | artifactId | artifactId | - | v | string | 否 | 无 | version | version | - | c | string | 否 | 无 | classifier | classifier | - | repos | string | 否 | 无 | 仓库名列表 | repo list | - -- 响应体 - - ```json - { - "code": 0, - "message": null, - "data": { - "pageNumber": 1, - "pageSize": 20, - "totalRecords": 4, - "totalPages": 1, - "records": [ - { - "uri": "http://127.0.0.1/maven/test/maven/com/mycompany/app/my-app/1.0-3/my-app-1.0-3.jar" - }, - { - "uri": "http://127.0.0.1/maven/test/maven/com/mycompany/app/my-app/1.0-3/my-app-1.0-3.pom" - }, - { - "uri": "http://127.0.0.1/maven/test/maven1/com/mycompany/app/my-app/1.0-3/my-app-1.0-3.jar" - }, - { - "uri": "http://127.0.0.1/maven/test/maven1/com/mycompany/app/my-app/1.0-3/my-app-1.0-3.pom" - } - ], - "page": 1, - "count": 4 - }, - "traceId": "" - } - ``` - -- data字段说明 - - | 字段 | 类型 | 说明 | Description | - | ---- | ------ | ------------ | ------------ | - | uri | string | 文件下载链接 | artifact uri | - diff --git a/docs/storage/repository/maven.md b/docs/storage/repository/maven.md deleted file mode 100644 index a9b1db4bad3..00000000000 --- a/docs/storage/repository/maven.md +++ /dev/null @@ -1,56 +0,0 @@ -## maven仓库使用指引 - -#### 添加仓库: -```bash -curl -X POST http://{bk_repo_addr}/repository/repo/create \ --H 'Content-Type: application/json' \ --d '{ - "projectId": "projectName", - "name": "repositoryName", - "type": "MAVEN", - "category": "LOCAL|REMOTE|VIRTUAL", - "public": true, - "configuration": { - "type": "local|remote|virtual", - "settings": { - "SNAPSHOT_BEHAVIOR": 0|1, - } - } -}' -``` - -#### deploy jar: - -```bash -mvn deploy:deploy-file --Dfile={filePath} --DgroupId={group} --DartifactId={artifact} --Dversion={version} --Dpackaging={packageType} -#[-DrepositoryId=file-http] 如果仓库有鉴权需带上该参数 --Durl={repositoryUrl} - -# Example -mvn deploy:deploy-file --Dfile=/abc/bcd/example-1.0.0.jar --DgroupId=com.xxx.yyy.zzz --DartifactId=example --Dversion=1.0.0 --Dpackaging=jar --DrepositoryId=file-http --Durl=http://{bk_repo_addr}/{projectId}/{repoName} -``` - -mvn `conf/settings.xml` 对应账户密码设置: - -```xml - - - file-http - admin - password - - -``` - diff --git a/docs/storage/repository/npm.md b/docs/storage/repository/npm.md deleted file mode 100644 index a89a4d53fc7..00000000000 --- a/docs/storage/repository/npm.md +++ /dev/null @@ -1,48 +0,0 @@ -1、新建三个仓库 - -2、npm设置registry - -```powershell -$ npm config set registry http://artifact.mac.cn:10001/test/npm-virtual/ -``` - -3、npm下载包 - -```powershell -$ npm -loglevel info i underscore -registry=http://artifact.mac.cn:10001/test/npm-virtual/ -``` - -4、npm上传包 - -```powershell -# 上报本地的包需要先进行登录,注意这里的地址是使用本地仓库 -$ npm login -registry=http://artifact.mac.cn:10001/test/npm-local/ - -# 发布包 -$ npm -loglevel info publish -registry=http://artifact.mac.cn:10001/test/npm-local/ - -# dist-tag 发布带指定tag的包 -$ npm publish --tag beta - -# 将该tag包转换为正式的最新版本 -# 作用是将1.0.2这个版本的包作为latest的最新包 -$ npm dist-tag add jfrog-npm-publish@1.0.2 latest -regsitry=http://artifact.canwaysoft.cn/api/test/npm-local/ -``` - -5、包的废弃 - -```powershell -# 废弃包 -npm -loglevel info deprecate helloworld-npm-publish@"< 1.0.2" "critical bug fixed in v1.0.2" -registry=http://artifact.mac.cn:10001/test/npm-local/ -``` - - - - - - - - - - - diff --git a/docs/storage/repository/oci.md b/docs/storage/repository/oci.md deleted file mode 100644 index 9ea77028a4a..00000000000 --- a/docs/storage/repository/oci.md +++ /dev/null @@ -1,46 +0,0 @@ -### helm oci仓库操作指引 - ---- - -1、新建项目和仓库 [{projectId}/{repoName}] - -2、登录到oci仓库 (手动输入密码) -```shell script -$ helm registry login -u {userName} {helm.registry} -Password: -Login succeeded -``` - -3、从仓库注销登录 -```shell script -$ helm registry logout {helm.registry} -Logout succeeded -``` - -4、helm chart创建包 -```shell script -# 创建helm包 -$ helm create hello-world -``` - -5、helm 保存chart目录到本地缓存 -```shell script -# 前面项目名称和仓库名称固定,后面目录结构可自定义 -$ helm chart save hello-world/ {helm.registry}/{projectId}/{repoName}/hello-world:1.0.0 -``` - -6、helm chart push 推送chart到远程 -```shell script -$ helm chart push {helm.registry}/{projectId}/{repoName}/hello-world:1.0.0 -``` - -7、pull 从远程拉取chart -```shell script -$ helm chart pull {helm.registry}/{projectId}/{repoName}/hello-world:1.0.0 -``` - -8、列举出所有的chart -```shell script -$ helm chart list -``` - diff --git a/docs/storage/repository/pypi.md b/docs/storage/repository/pypi.md deleted file mode 100644 index 83b6b6826a9..00000000000 --- a/docs/storage/repository/pypi.md +++ /dev/null @@ -1,100 +0,0 @@ -## pypi仓库使用指引 - -#### 添加仓库: - -```bash -curl -X POST http://{bk_repo_addr}/repository/repo/create \ --H 'Content-Type: application/json' \ --d '{ - "projectId": "projectName", - "name": "repositoryName", - "type": "PYPI", - "category": "LOCAL|REMOTE|VIRTUAL|COMPOSITE", - "public": true, - "configuration": {"type": "local|remote|virtual|composite"} -}' - -#remote 仓库 -curl -X POST http://{bk_repo_addr}/repository/repo \ --H 'Content-Type: application/json' \ --d '{ - "projectId": "projectName", - "name": "repositoryName", - "type": "PYPI", - "category": "REMOTE", - "public": true, - "configuration":{ - "type":"remote", - "url":"https://pypi.org/" - } -}' -``` - -默认在Python3下运行   - -**全局依赖源配置:** -配置文件路径:`~/.pip/pip.conf` -```conf -[bkrepo] -index-url = http://{bk_repo_addr}/{projectId}/{repoName}/simple -username = {user} -password = {password} -``` - -**依赖源地址需要加上`/simple`** - -#### upload: - -配置仓库地址和认证信息:$HOME/.pypirc - -配置仓库地址和认证信息 -```txt -[distutils] -index-servers = bkrepo -[bkrepo] -repository = http://{bk_repo_addr}/{projectId}/{repoName}/simple -username = {user} -password = {password} -``` - -```bash -#使用twine作为上传工具 -python3 -m twine upload -r {bkrepo} dist/* -``` - -#### install - -替换默认依赖源地址 - -- MacOS/Linux配置目录 : $HOME/.pip/pip.conf -- Windows配置目录 : %HOME%/pip/pip.ini - ```txt - [global] - index-url = http://{admin}:{PASSWORD}@{bk_repo_addr}/{projectId}/{repoName}/simple - [install] - trusted-host=http://{bk_repo_addr} - ``` -- 执行下面命令: - ```bash - pip3 install {packageName}=={version} - ``` - -指定依赖源下载 -```bash -pip3 install -i http://{bk_repo_addr}/{projectId}/{repoName} {package}=={version} -``` - -#### Search - -```bash -#查看已安装的包 -pip3 list -#删除安装包 -pip3 uninstall package -#search -pip3 search -i http://{bk_repo_addr}/{projectId}/{repoName} {package}|{summary} - -``` - - - diff --git a/docs/storage/repository/rpm.md b/docs/storage/repository/rpm.md deleted file mode 100644 index c3d06eb79c2..00000000000 --- a/docs/storage/repository/rpm.md +++ /dev/null @@ -1,201 +0,0 @@ -## rpm仓库使用指引 - -#### 创建仓库: - -```bash -curl -X POST http://{bk_repo_addr}/repository/repo/create \ --H 'Content-Type: application/json' \ --d '{ - "projectId": "{project}", - "name": "{repo}", - "type": "RPM", - "category": "COMPOSITE", - "public": true, - "configuration": { - "type": "local", - "settings": { - "enabledFileLists": false, - "repodataDepth": 1, - "groupXmlSet": [ - "groups.xml", - "bkrepos.xml" - ] - } - }, - "description": "for bkdevops test" -}' -``` - - - -```bash -#新增仓库配置分组文件名 -curl -X PUT http://{bk_repo_addr}/{projectId}/{repoName}/rpm/configuration/{project}/{repo}/ \ --H 'Content-Type: application/json' \ --d '[ - "abc.xml", - "bkrepo.xml" - ]' - -#移除仓库配置分组文件名 -curl -X DELETE http://{bk_repo_addr}/{projectId}/{repoName}/rpm/configuration/{project}/{repo}/ \ --H 'Content-Type: application/json' \ --d '[ - "abc.xml", - "bkrepos.xml" - ]' -``` - - - - - -仓库地址配置: -======= -仓库地址配置: - -配置文件目录:/etc/yum.repos.d/ - -全局默认配置文件:CentOS-Base.repo - -或者自定义:{name}.repo - -参考数据格式: - -```txt -[bkrepo] -name=bkrepo //仓库名 -baseurl=http://admin:password@{bk_repo_addr}/{projectId}/{repoName}/$releasever/os/$basearch //仓库地址,如果有开启认证,需要在请求前添加 用户名:密码 -keepcache=0 //是否开启缓存,测试阶段推荐开启,否则上传后,yum install 时会优先去本地缓存找 -enabled=1 //地址授信,如果非 https 环境必须设为1 -gpgcheck=0 //设为0,目前还不支持gpg签名 -metadata_expire=1m //本地元数据过期时间 ,测试阶段数据量不大的话,时间越短测试越方便 -``` - -```shell -#发布 -curl -u{admin}:{password} -XPUT http://{bk_repo_addr}/{projectId}/{repoName} -T {文件路径} - -#下载 -yum install -y {package} -# 添加源后快速使源生效 -yum check-update -#从指定源下载 -yum install nginx --enablerepo={源名称} -#删除包 -yum erase -y {package} -#清除缓存的包 -yum clean packages --enablerepo={源名称} -#清除对应仓库的元数据 -yum clean metadata --enablerepo={源名称} - -#上传组文件,必须上传至仓库repodata 目录 -curl -u{admin}:{password} -XPUT http://{bk_repo_addr}/{projectId}/{repoName}/{repodata}/ -T {文件路径} - -#group 列表 -yum grouplist -#下载组包含的包 -yum groupinstall {group} -#在系统中移除组,不会移除安装的包 -yum groups mark remove {group} -#移除通过组安装的包,在系统中组依然是被安装 -yum groupremove {group} -#升级group下所有包 -yum groupupdate {groupName} -``` - -
- -#### repodataDepth 解释: - -repodataDepth: 代表索引生成的目录的位置(对应请求的层级),当rpm构件`deploy`请求路径参数小于repodataDepth大小时(project, repo 不包含在请求路径中),不会计算构件索引。 - -## rpm仓库属性解释: - -**repodataDepth**: 代表索引生成的目录的位置(对应请求的层级),当rpm构件`deploy`请求路径参数小于repodataDepth大小时(project, repo 不包含在请求路径中),不会计算构件索引。 - -例如:repodataDepth:2 ,项目名:bkrepo ,仓库名:rpm-local。 - -请求1:`curl -uadmin:password -XPUT http://{host}:{port}/bkrepo/rpm-local/a/b/ -T {filePath}` - -请求2:`curl -uadmin:password -XPUT http://{host}:{port}/bkrepo/rpm-local/a/ -T {filePath}` - -请求3:`curl -uadmin:password -XPUT http://{host}:{port}/bkrepo/rpm-local/a/b/c/ -T {filePath}` - --- 请求1的构件将会计算索引,`yum install` 可以下载到,索引目录:`/a/b/repodata` - --- 请求2的构件不会计算索引,`yum install` 下载不到,但是包会保存在服务器上。 - --- 请求3的构件将会计算索引,`yum install` 可以下载到,索引目录:`/a/b/repodata` - - - -**enabledFileLists**: 是否启用单独的filelists.xml 索引,开启后rpm包的filelists信息会单独保存在filelists.xml中,否则部分文件信息保存在primary.xml中。 - - - -**groupXmlSet**: 仓库分组设置,添加仓库允许的分组文件列表,只有出现在列表中的分组文件才会被计算索引,客户端才可以下载到。 - - - -## rpm package - -官方文档:[RPM Packaging Guide](https://rpm-packaging-guide.github.io/) - -```shell -#安装打包工具 -yum install gcc rpm-build rpm-devel rpmlint make python bash coreutils diffutils patch rpmdevtools - -#在一个空白目录新建一个`.spec`文件 -touch xxx.spec -#打包 -rpmdev-setuptree -rpmbuild -ba hello-world.spec -``` - - - -参考数据: - -```txt -Name: bkrepo-test -Version: 1.1 -Release: 1 -Summary: Test same artifactUri but different content! -License: FIXME - -%description -This is my first RPM package, which does nothing. - -%prep -# we have no source, so nothing here - -%build -cat > bkrepo-test.sh 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ʻw}hEfn7|kS#ZY_8>Ar!rr&d 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 KRm+sE(EkJPo#$@= diff --git a/docs/storage/scanner/deployment.md b/docs/storage/scanner/deployment.md deleted file mode 100644 index 6e496db55ae..00000000000 --- a/docs/storage/scanner/deployment.md +++ /dev/null @@ -1,41 +0,0 @@ -# 服务部署 - -## scanner服务 - -### 配置 - -```yaml -# 上报的扫描结果比较大的时候需要配置 -spring: - servlet: - multipart: - max-request-size: 100MB - -# 用于存储详细扫描报告 -scanner: - spring: - data: - mongodb: - uri: mongoUri -``` - -## scanner-executor服务 - -### 配置 - -```yaml -scanner: - executor: - docker: - enabled: true - host: unix:///var/run/docker.sock - version: 1.23 - connect-timeout: 5000 - read-timeout: 1200000 -``` - -### 依赖 - -- docker daemon -- 扫描器依赖容器镜像时机器上要有对应的容器镜像,不存在镜像但是可以拉取到时scanner-executor服务会自动拉取 -- 运行服务器最好是8C/16G 以上的配置,因为扫描器目前还比较消耗资源 diff --git a/docs/storage/scanner/overview.md b/docs/storage/scanner/overview.md deleted file mode 100644 index 846ea142afe..00000000000 --- a/docs/storage/scanner/overview.md +++ /dev/null @@ -1,61 +0,0 @@ -# 制品扫描介绍 - -制品扫描功能主要由`scanner`和`scanner-executor`两个服务构成 - -`scanner`服务负责管理扫描器、扫描任务、扫描报告存取 - -`scanner-executor`是实际执行扫描任务的服务,通过`scanner`服务创建的任务最终都将由`scanner-executor`执行, -执行完后再将扫描结果上报到`scanner`服务 - -# 如何执行扫描 - -下面提到的接口详情见api文档 - -1. 通过`/api/scanner/api/scanners`接口创建扫描器 -2. 通过`/api/scan`接口指定使用的扫描器和要扫描的文件,创建扫描任务 -3. 通过`/api/scan/tasks/{taskId}`接口获取扫描任务信息,查看当前任务状态和进度 -4. 扫描结束后可以通过`api/scan/reports/overview`接口获取指定文件的扫描结果预览信息, 或者通过`/api/scan/reports/detail/{artifactUri}`获取指定文件的详细扫描报告 - -# 相关设计 - -## 扫描器 - -制品扫描对扫描器做了抽象,可以根据不同的扫描器类型编写对应的实现,现在支持了科恩实验室提供的制品扫描器 - -不同扫描器实现可以自定义扫描器的配置、如何执行扫描、扫描结果如何存取 - -## 扫描任务 - -通过指定扫描器和要扫描的文件可以创建一个扫描任务,一个扫描任务扫描的每个文件都对应一个子扫描任务 - -所有子扫描任务完成后则扫描任务完成 - -### 扫描任务状态 - -1. 扫描任务刚创建时处于PENDING状态 -2. 创建后会立即提交扫描调度器,开始提交子任务,此时处于SCANNING_SUBMITTING状态 -3. 所有子任务提交完后改变为SCANNING_SUBMITTED状态 -4. 所有子任务扫描完成结果上报后扫描任务改变为FINISHED状态 - -会有定时任务将处于PENDING和SCANNING_SUBMITTING超过指定时间的扫描任务重新提交扫描 - -### 子扫描任务状态 - -子扫描任务创建后会保存在数据库的任务队列中,如果有其他任务队列实现也会被加入到对应的队列中 - -1. 子任务刚创建时处于CREATED状态 -2. 子任务被主动拉取时处于PULLED状态 -3. 子任务加入扫描任务队列后处于ENQUEUED状态 -4. 扫描执行器开始执行任务后子任务处于EXECUTING状态 -5. 扫描结束上报结果后子任务从数据库的队列中移除 - -会定时查询数据库中的子扫描任务队列,将CREATED或者处于PULLED、ENQUEUED、EXECUTING这三个状态很久的任务重新提交执行, -一个子扫描任务最多执行次数有限制,超过限制后会被从数据库中的扫描任务队列移除,不再重试 - -## 扫描结果 - -每个文件使用指定版本的扫描器都有一个扫描结果,当使用同一扫描器版本扫描同一个文件时会复用之前的扫描结果,不会实际执行扫描 - -类似漏洞数量、敏感信息数量这种统计类型数据会存储到通用的扫描结果表中 - -特定类型扫描器特有的扫描结果会根据不同的扫描器实现进行存取,比如目前实现的arrowhead扫描器结果存储在单独的数据库中 diff --git a/support-files/storage/README.md b/support-files/storage/README.md deleted file mode 100644 index 33f04559426..00000000000 --- a/support-files/storage/README.md +++ /dev/null @@ -1 +0,0 @@ -# support-files diff --git a/support-files/storage/grafana/dashboard-bkrepo.json b/support-files/storage/grafana/dashboard-bkrepo.json deleted file mode 100644 index 0b88c76227b..00000000000 --- a/support-files/storage/grafana/dashboard-bkrepo.json +++ /dev/null @@ -1,1213 +0,0 @@ -{ - "__inputs": [ - { - "name": "DS_BKREPO-METRICS-PROD", - "label": "bkrepo-metrics-prod", - "description": "", - "type": "datasource", - "pluginId": "influxdb", - "pluginName": "InfluxDB" - } - ], - "__requires": [ - { - "type": "grafana", - "id": "grafana", - "name": "Grafana", - "version": "7.1.3" - }, - { - "type": "panel", - "id": "graph", - "name": "Graph", - "version": "" - }, - { - "type": "datasource", - "id": "influxdb", - "name": "InfluxDB", - "version": "1.0.0" - }, - { - "type": "panel", - "id": "stat", - "name": "Stat", - "version": "" - } - ], - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "limit": 100, - "name": "Annotations & Alerts", - "showIn": 0, - "type": "dashboard" - } - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "id": null, - "iteration": 1615295398208, - "links": [], - "panels": [ - { - "collapsed": false, - "datasource": null, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 19, - "panels": [], - "title": "制品库传输当日总览", - "type": "row" - }, - { - "cacheTimeout": null, - "datasource": "${DS_BKREPO-METRICS-PROD}", - "fieldConfig": { - "defaults": { - "custom": { - "align": null - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "bytes" - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 6, - "x": 0, - "y": 1 - }, - "id": 21, - "interval": null, - "links": [], - "maxDataPoints": 3, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "reduceOptions": { - "calcs": [ - "sum" - ], - "fields": "", - "values": false - }, - "textMode": "value" - }, - "pluginVersion": "7.1.3", - "targets": [ - { - "groupBy": [ - { - "params": [ - "$interval" - ], - "type": "time" - } - ], - "measurement": "artifact_uploaded_consume", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT sum(\"value\") FROM \"artifact_uploaded_consume\" WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/) AND time > now()-1d GROUP BY time(1d) ORDER BY DESC LIMIT 1", - "rawQuery": true, - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "sum" - } - ] - ], - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - } - ], - "timeFrom": null, - "timeShift": null, - "title": "当日上传数据", - "type": "stat" - }, - { - "cacheTimeout": null, - "datasource": "${DS_BKREPO-METRICS-PROD}", - "fieldConfig": { - "defaults": { - "custom": { - "align": null - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "none" - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 6, - "x": 6, - "y": 1 - }, - "id": 22, - "interval": null, - "links": [], - "maxDataPoints": 3, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "reduceOptions": { - "calcs": [ - "sum" - ], - "fields": "", - "values": false - }, - "textMode": "value" - }, - "pluginVersion": "7.1.3", - "targets": [ - { - "groupBy": [], - "measurement": "artifact_uploaded_consume", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT sum(\"count\") FROM \"artifact_uploaded_consume\" WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/) AND time > now()-1d GROUP BY time(1d) ORDER BY DESC LIMIT 1", - "rawQuery": true, - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - } - ] - ], - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - } - ], - "timeFrom": null, - "timeShift": null, - "title": "当日上传数量", - "type": "stat" - }, - { - "cacheTimeout": null, - "datasource": "${DS_BKREPO-METRICS-PROD}", - "description": "", - "fieldConfig": { - "defaults": { - "custom": { - "align": null - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "bytes" - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 6, - "x": 12, - "y": 1 - }, - "id": 23, - "interval": null, - "links": [], - "maxDataPoints": 3, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "reduceOptions": { - "calcs": [ - "sum" - ], - "fields": "", - "values": false - }, - "textMode": "value" - }, - "pluginVersion": "7.1.3", - "targets": [ - { - "groupBy": [ - { - "params": [ - "$interval" - ], - "type": "time" - } - ], - "measurement": "artifact_uploaded_consume", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT sum(\"value\") FROM \"artifact_downloaded_consume\" WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/) AND time > now()-1d GROUP BY time(1d) ORDER BY DESC LIMIT 1", - "rawQuery": true, - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "sum" - } - ] - ], - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - } - ], - "timeFrom": null, - "timeShift": null, - "title": "当日下载数据", - "type": "stat" - }, - { - "cacheTimeout": null, - "datasource": "${DS_BKREPO-METRICS-PROD}", - "fieldConfig": { - "defaults": { - "custom": { - "align": null - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "none" - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 6, - "x": 18, - "y": 1 - }, - "id": 24, - "interval": null, - "links": [], - "maxDataPoints": 3, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "horizontal", - "reduceOptions": { - "calcs": [ - "sum" - ], - "fields": "", - "values": false - }, - "textMode": "value" - }, - "pluginVersion": "7.1.3", - "targets": [ - { - "groupBy": [], - "measurement": "artifact_uploaded_consume", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT sum(\"count\") FROM \"artifact_downloaded_consume\" WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/) AND time > now()-1d GROUP BY time(1d) ORDER BY DESC LIMIT 1", - "rawQuery": true, - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - } - ] - ], - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - } - ], - "timeFrom": null, - "timeShift": null, - "title": "当日下载数量", - "type": "stat" - }, - { - "collapsed": false, - "datasource": "${DS_BKREPO-METRICS-PROD}", - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 4 - }, - "id": 12, - "panels": [], - "title": "制品库传输状态", - "type": "row" - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_BKREPO-METRICS-PROD}", - "description": "IO传输平均流量", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 5 - }, - "hiddenSeries": false, - "id": 17, - "interval": "1m", - "legend": { - "avg": true, - "current": true, - "max": true, - "min": false, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null as zero", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.1.3", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "下载", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "linear" - ], - "type": "fill" - } - ], - "measurement": "artifact_downloaded_consume", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT sum(\"value\")/60 FROM \"artifact_downloaded_consume\" WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/ AND \"type\" = 'size') AND $timeFilter GROUP BY time($__interval) fill(linear)", - "rawQuery": true, - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - }, - { - "condition": "AND", - "key": "type", - "operator": "=", - "value": "size" - } - ] - }, - { - "alias": "上传", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "linear" - ], - "type": "fill" - } - ], - "measurement": "artifact_uploaded_consume", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT sum(\"value\")/60 FROM \"artifact_uploaded_consume\" WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/ AND \"type\" = 'size') AND $timeFilter GROUP BY time($__interval) fill(linear)", - "rawQuery": true, - "refId": "B", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - }, - { - "condition": "AND", - "key": "type", - "operator": "=", - "value": "size" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "IO传输平均流量", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_BKREPO-METRICS-PROD}", - "decimals": null, - "description": "平均每秒传输数量", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 5 - }, - "hiddenSeries": false, - "id": 14, - "interval": "1m", - "legend": { - "avg": true, - "current": true, - "max": true, - "min": false, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null as zero", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.1.3", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "下载", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "measurement": "artifact_downloaded_consume", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT sum(\"count\")/60 FROM \"artifact_downloaded_consume\" WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/) AND $timeFilter GROUP BY time($__interval) fill(none)", - "rawQuery": true, - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "count" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - }, - { - "alias": "上传", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "measurement": "artifact_uploaded_consume", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT sum(\"count\")/60 FROM \"artifact_uploaded_consume\" WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/) AND $timeFilter GROUP BY time($__interval) fill(none)", - "rawQuery": true, - "refId": "B", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "count" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "平均传输数量", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "collapsed": false, - "datasource": "${DS_BKREPO-METRICS-PROD}", - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 13 - }, - "id": 7, - "panels": [], - "title": "异步任务状态", - "type": "row" - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_BKREPO-METRICS-PROD}", - "description": "异步任务实时数量", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 14 - }, - "hiddenSeries": false, - "id": 9, - "legend": { - "avg": false, - "current": true, - "max": true, - "min": false, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null as zero", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.1.3", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "count", - "groupBy": [], - "measurement": "async_task_active_count", - "orderByTime": "ASC", - "policy": "default", - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - } - ] - ], - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "异步任务实时数量", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_BKREPO-METRICS-PROD}", - "description": "异步任务队列大小", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 14 - }, - "hiddenSeries": false, - "id": 10, - "legend": { - "avg": false, - "current": true, - "max": true, - "min": false, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null as zero", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.1.3", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "大小", - "groupBy": [], - "measurement": "async_task_queue_size", - "orderByTime": "ASC", - "policy": "default", - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - } - ] - ], - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "异步任务队列大小", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - } - ], - "refresh": "1m", - "schemaVersion": 26, - "style": "dark", - "tags": [ - "bkrepo" - ], - "templating": { - "list": [ - { - "allFormat": "glob", - "allValue": "*", - "current": {}, - "datasource": "${DS_BKREPO-METRICS-PROD}", - "definition": "", - "error": null, - "hide": 0, - "includeAll": true, - "label": "服务", - "multi": true, - "name": "service", - "options": [], - "query": "show tag values from jvm_memory_used with key = \"service\"", - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 1, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allFormat": "glob", - "allValue": "*", - "current": {}, - "datasource": "${DS_BKREPO-METRICS-PROD}", - "definition": "", - "error": null, - "hide": 0, - "includeAll": true, - "label": "实例", - "multi": true, - "name": "instance", - "options": [], - "query": "show tag values from jvm_memory_used with key = \"instance\" where service = '$service'", - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - } - ] - }, - "time": { - "from": "now-1h", - "to": "now" - }, - "timepicker": { - "refresh_intervals": [ - "5s", - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ] - }, - "timezone": "browser", - "title": "制品库运行监控大盘", - "uid": "thcm04JGz", - "version": 2 -} \ No newline at end of file diff --git a/support-files/storage/grafana/dashboard-jvm.json b/support-files/storage/grafana/dashboard-jvm.json deleted file mode 100644 index c882bb2ac65..00000000000 --- a/support-files/storage/grafana/dashboard-jvm.json +++ /dev/null @@ -1,5647 +0,0 @@ -{ - "__inputs": [ - { - "name": "DS_INFLUXDB", - "label": "InfluxDB", - "description": "", - "type": "datasource", - "pluginId": "influxdb", - "pluginName": "InfluxDB" - } - ], - "__requires": [ - { - "type": "grafana", - "id": "grafana", - "name": "Grafana", - "version": "7.1.3" - }, - { - "type": "panel", - "id": "graph", - "name": "Graph", - "version": "" - }, - { - "type": "datasource", - "id": "influxdb", - "name": "InfluxDB", - "version": "1.0.0" - }, - { - "type": "panel", - "id": "stat", - "name": "Stat", - "version": "" - } - ], - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "limit": 100, - "name": "Annotations & Alerts", - "showIn": 0, - "type": "dashboard" - } - ] - }, - "description": "Dashboard for Micrometer instrumented applications", - "editable": true, - "gnetId": null, - "graphTooltip": 1, - "id": null, - "iteration": 1614606548741, - "links": [ - { - "icon": "external link", - "tags": [], - "title": "MicroMeter", - "type": "link", - "url": "http://micrometer.io/" - } - ], - "panels": [ - { - "collapsed": false, - "datasource": "${DS_INFLUXDB}", - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 125, - "panels": [], - "repeat": null, - "title": "概览", - "type": "row" - }, - { - "datasource": "${DS_INFLUXDB}", - "description": "JVM进程启动时长", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": {}, - "decimals": 1, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "clockms" - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 6, - "x": 0, - "y": 1 - }, - "id": 63, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "textMode": "auto" - }, - "pluginVersion": "7.1.3", - "targets": [ - { - "groupBy": [], - "measurement": "process_uptime", - "orderByTime": "ASC", - "policy": "default", - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "last" - } - ] - ], - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - } - ], - "timeFrom": null, - "timeShift": null, - "title": "进程启动时长", - "type": "stat" - }, - { - "datasource": "${DS_INFLUXDB}", - "description": "JVM进程启动时间", - "fieldConfig": { - "defaults": { - "custom": {}, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "dateTimeAsUS" - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 6, - "x": 6, - "y": 1 - }, - "id": 92, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "textMode": "auto" - }, - "pluginVersion": "7.1.3", - "targets": [ - { - "groupBy": [], - "measurement": "process_start_time", - "orderByTime": "ASC", - "policy": "default", - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "last" - } - ] - ], - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - } - ], - "timeFrom": null, - "timeShift": null, - "title": "进程启动时间", - "type": "stat" - }, - { - "datasource": "${DS_INFLUXDB}", - "description": "JVM堆内存使用率", - "fieldConfig": { - "defaults": { - "custom": {}, - "decimals": 2, - "mappings": [ - { - "id": 0, - "op": "=", - "text": "N/A", - "type": 1, - "value": "null" - } - ], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "rgba(50, 172, 45, 0.97)", - "value": null - }, - { - "color": "rgba(237, 129, 40, 0.89)", - "value": 70 - }, - { - "color": "rgba(245, 54, 54, 0.9)", - "value": 90 - } - ] - }, - "unit": "percentunit" - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 6, - "x": 12, - "y": 1 - }, - "id": 65, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "textMode": "auto" - }, - "pluginVersion": "7.1.3", - "targets": [ - { - "alias": "used", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "previous" - ], - "type": "fill" - } - ], - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT mean(\"value\") FROM \"autogen\".\"jvm_memory_used\" WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/ AND \"area\" = 'heap') AND $timeFilter GROUP BY time($interval) fill(previous)", - "rawQuery": true, - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "tags": [] - }, - { - "alias": "max", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "previous" - ], - "type": "fill" - } - ], - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT mean(\"value\") FROM \"autogen\".\"jvm_memory_max\" WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/ AND \"area\" = 'heap') AND $timeFilter GROUP BY time($interval) fill(previous)", - "rawQuery": true, - "refId": "B", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "tags": [] - } - ], - "timeFrom": null, - "timeShift": null, - "title": "堆内存使用率", - "transformations": [ - { - "id": "calculateField", - "options": { - "alias": "value", - "binary": { - "left": "used", - "operator": "/", - "reducer": "sum", - "right": "max" - }, - "mode": "binary", - "reduce": { - "reducer": "sum" - }, - "replaceFields": true - } - } - ], - "type": "stat" - }, - { - "datasource": "${DS_INFLUXDB}", - "description": "JVM非堆内存使用率", - "fieldConfig": { - "defaults": { - "custom": {}, - "decimals": 2, - "mappings": [ - { - "id": 0, - "op": "=", - "text": "N/A", - "type": 1, - "value": "null" - } - ], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "rgba(50, 172, 45, 0.97)", - "value": null - }, - { - "color": "rgba(237, 129, 40, 0.89)", - "value": 70 - }, - { - "color": "rgba(245, 54, 54, 0.9)", - "value": 90 - } - ] - }, - "unit": "percentunit" - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 6, - "x": 18, - "y": 1 - }, - "id": 134, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "textMode": "auto" - }, - "pluginVersion": "7.1.3", - "targets": [ - { - "alias": "used", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "previous" - ], - "type": "fill" - } - ], - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT mean(\"value\") FROM \"autogen\".\"jvm_memory_used\" WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/ AND \"area\" = 'nonheap') AND $timeFilter GROUP BY time($interval) fill(previous)", - "rawQuery": true, - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "tags": [] - }, - { - "alias": "max", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "previous" - ], - "type": "fill" - } - ], - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT mean(\"value\") FROM \"autogen\".\"jvm_memory_max\" WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/ AND \"area\" = 'nonheap') AND $timeFilter GROUP BY time($interval) fill(previous)", - "rawQuery": true, - "refId": "B", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "tags": [] - } - ], - "timeFrom": null, - "timeShift": null, - "title": "非堆内存使用率", - "transformations": [ - { - "id": "calculateField", - "options": { - "alias": "value", - "binary": { - "left": "used", - "operator": "/", - "reducer": "sum", - "right": "max" - }, - "mode": "binary", - "reduce": { - "reducer": "sum" - }, - "replaceFields": true - } - } - ], - "type": "stat" - }, - { - "collapsed": false, - "datasource": "${DS_INFLUXDB}", - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 4 - }, - "id": 126, - "panels": [], - "repeat": null, - "title": "HTTP Overview", - "type": "row" - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_INFLUXDB}", - "description": "平均每分钟处理的请求数", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 5 - }, - "hiddenSeries": false, - "id": 111, - "interval": "", - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "hideEmpty": false, - "hideZero": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null as zero", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.1.3", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "$tag_method", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "method" - ], - "type": "tag" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "measurement": "http_server_requests", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT mean(\"count\") FROM \"http_server_requests\" WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/) AND $timeFilter GROUP BY time($__interval), \"method\" fill(none)", - "rawQuery": false, - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "count" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "平均请求量", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": null, - "format": "opm", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_INFLUXDB}", - "description": "平均每分钟错误请求数", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 8, - "y": 5 - }, - "hiddenSeries": false, - "id": 112, - "legend": { - "avg": false, - "current": true, - "max": false, - "min": false, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null as zero", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.1.3", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "HTTP - 4XX", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "measurement": "http_server_requests", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT mean(\"count\") FROM \"http_server_requests\" WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/ AND \"status\" =~ /^4.*$/) AND $timeFilter GROUP BY time($__interval) fill(null)", - "rawQuery": false, - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "count" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - }, - { - "condition": "AND", - "key": "status", - "operator": "=~", - "value": "/^4.*$/" - } - ] - }, - { - "alias": "HTTP - 5XX", - "groupBy": [ - { - "params": [ - "$interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "measurement": "http_server_requests", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT mean(\"count\") FROM \"http_server_requests\" WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/ AND \"status\" =~ /^5.*$/) AND $timeFilter GROUP BY time($__interval) fill(null)", - "rawQuery": false, - "refId": "B", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "count" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - }, - { - "condition": "AND", - "key": "status", - "operator": "=~", - "value": "/^5.*$/" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "平均错误数", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "decimals": null, - "format": "opm", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_INFLUXDB}", - "description": "平均请求耗时", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 16, - "y": 5 - }, - "hiddenSeries": false, - "id": 113, - "legend": { - "avg": false, - "current": true, - "max": false, - "min": false, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null as zero", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.1.3", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "HTTP - AVG", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "null" - ], - "type": "fill" - } - ], - "hide": false, - "measurement": "http_server_requests", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT mean(\"sum\")/mean(\"count\") FROM \"http_server_requests\" WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/) AND $timeFilter GROUP BY time($__interval) fill(none)", - "rawQuery": true, - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "sum" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ], - [ - { - "params": [ - "count" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "平均请求耗时", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "ms", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "collapsed": false, - "datasource": "${DS_INFLUXDB}", - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 12 - }, - "id": 127, - "panels": [], - "repeat": null, - "title": "JVM 内存", - "type": "row" - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_INFLUXDB}", - "description": "JVM堆内存使用情况", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": { - "leftLogBase": 1, - "leftMax": null, - "leftMin": null, - "rightLogBase": 1, - "rightMax": null, - "rightMin": null - }, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 13 - }, - "hiddenSeries": false, - "id": 24, - "legend": { - "avg": false, - "current": true, - "hideZero": false, - "max": true, - "min": false, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.1.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "used", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "measurement": "jvm_memory_used", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT SUM(val) FROM (SELECT mean(value) AS val FROM jvm_memory_used WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/ AND \"area\" = 'heap') AND $timeFilter GROUP BY time($__interval) ,*) GROUP BY time($__interval) fill(linear)", - "rawQuery": true, - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "sum" - } - ] - ], - "step": 2400, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - }, - { - "condition": "AND", - "key": "area", - "operator": "=", - "value": "heap" - } - ] - }, - { - "alias": "committed", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "measurement": "jvm_memory_committed", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT SUM(val) FROM (SELECT mean(value) AS val FROM jvm_memory_committed WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/ AND \"area\" = 'heap') AND $timeFilter GROUP BY time($__interval) ,*) GROUP BY time($__interval) fill(linear)", - "rawQuery": true, - "refId": "B", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "step": 2400, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - }, - { - "condition": "AND", - "key": "area", - "operator": "=", - "value": "heap" - } - ] - }, - { - "alias": "max", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "measurement": "jvm_memory_max", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT SUM(val) FROM (SELECT mean(value) AS val FROM jvm_memory_max WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/ AND \"area\" = 'heap') AND $timeFilter GROUP BY time($__interval) ,*) GROUP BY time($__interval) fill(linear)", - "rawQuery": true, - "refId": "D", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "sum" - } - ] - ], - "step": 2400, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - }, - { - "condition": "AND", - "key": "area", - "operator": "=", - "value": "heap" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "堆内存", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "x-axis": true, - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "y-axis": true, - "y_formats": [ - "mbytes", - "short" - ], - "yaxes": [ - { - "decimals": null, - "format": "decbytes", - "label": "", - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_INFLUXDB}", - "description": "JVM非堆内存使用情况", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": { - "leftLogBase": 1, - "leftMax": null, - "leftMin": null, - "rightLogBase": 1, - "rightMax": null, - "rightMin": null - }, - "gridPos": { - "h": 7, - "w": 8, - "x": 8, - "y": 13 - }, - "hiddenSeries": false, - "id": 155, - "legend": { - "avg": false, - "current": true, - "hideZero": false, - "max": true, - "min": false, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.1.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "used", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "measurement": "jvm_memory_used", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT SUM(val) FROM (SELECT mean(value) AS val FROM jvm_memory_used WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/ AND \"area\" = 'nonheap') AND $timeFilter GROUP BY time($__interval) ,*) GROUP BY time($__interval) fill(linear)", - "rawQuery": true, - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "sum" - } - ] - ], - "step": 2400, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - }, - { - "condition": "AND", - "key": "area", - "operator": "=", - "value": "heap" - } - ] - }, - { - "alias": "committed", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "measurement": "jvm_memory_committed", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT SUM(val) FROM (SELECT mean(value) AS val FROM jvm_memory_committed WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/ AND \"area\" = 'nonheap') AND $timeFilter GROUP BY time($__interval) ,*) GROUP BY time($__interval) fill(linear)", - "rawQuery": true, - "refId": "B", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "step": 2400, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - }, - { - "condition": "AND", - "key": "area", - "operator": "=", - "value": "heap" - } - ] - }, - { - "alias": "max", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "measurement": "jvm_memory_max", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT SUM(val) FROM (SELECT mean(value) AS val FROM jvm_memory_max WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/ AND \"area\" = 'nonheap') AND $timeFilter GROUP BY time($__interval) ,*) GROUP BY time($__interval) fill(linear)", - "rawQuery": true, - "refId": "D", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "sum" - } - ] - ], - "step": 2400, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - }, - { - "condition": "AND", - "key": "area", - "operator": "=", - "value": "heap" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "非堆内存", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "x-axis": true, - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "y-axis": true, - "y_formats": [ - "mbytes", - "short" - ], - "yaxes": [ - { - "decimals": null, - "format": "decbytes", - "label": "", - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_INFLUXDB}", - "description": "JVM总内存使用情况", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": { - "leftLogBase": 1, - "leftMax": null, - "leftMin": null, - "rightLogBase": 1, - "rightMax": null, - "rightMin": null - }, - "gridPos": { - "h": 7, - "w": 8, - "x": 16, - "y": 13 - }, - "hiddenSeries": false, - "id": 156, - "legend": { - "avg": false, - "current": true, - "hideZero": false, - "max": true, - "min": false, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.1.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "used", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "measurement": "jvm_memory_used", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT SUM(val) FROM (SELECT mean(value) AS val FROM jvm_memory_used WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/) AND $timeFilter GROUP BY time($__interval) ,*) GROUP BY time($__interval) fill(linear)", - "rawQuery": true, - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "sum" - } - ] - ], - "step": 2400, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - }, - { - "condition": "AND", - "key": "area", - "operator": "=", - "value": "heap" - } - ] - }, - { - "alias": "committed", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "measurement": "jvm_memory_committed", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT SUM(val) FROM (SELECT mean(value) AS val FROM jvm_memory_committed WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/) AND $timeFilter GROUP BY time($__interval) ,*) GROUP BY time($__interval) fill(linear)", - "rawQuery": true, - "refId": "B", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "step": 2400, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - }, - { - "condition": "AND", - "key": "area", - "operator": "=", - "value": "heap" - } - ] - }, - { - "alias": "max", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "measurement": "jvm_memory_max", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT SUM(val) FROM (SELECT mean(value) AS val FROM jvm_memory_max WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/) AND $timeFilter GROUP BY time($__interval) ,*) GROUP BY time($__interval) fill(linear)", - "rawQuery": true, - "refId": "D", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "sum" - } - ] - ], - "step": 2400, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - }, - { - "condition": "AND", - "key": "area", - "operator": "=", - "value": "heap" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "总内存", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "x-axis": true, - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "y-axis": true, - "y_formats": [ - "mbytes", - "short" - ], - "yaxes": [ - { - "decimals": null, - "format": "decbytes", - "label": "", - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "collapsed": false, - "datasource": "${DS_INFLUXDB}", - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 20 - }, - "id": 128, - "panels": [], - "repeat": null, - "title": "JVM 负载", - "type": "row" - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_INFLUXDB}", - "description": "JVM系统CPU使用率", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": { - "leftLogBase": 1, - "leftMax": null, - "leftMin": null, - "rightLogBase": 1, - "rightMax": null, - "rightMin": null - }, - "gridPos": { - "h": 7, - "w": 6, - "x": 0, - "y": 21 - }, - "hiddenSeries": false, - "id": 106, - "legend": { - "avg": false, - "current": true, - "max": true, - "min": false, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.1.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "system", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "hide": false, - "measurement": "system_cpu_usage", - "orderByTime": "ASC", - "policy": "default", - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "step": 2400, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - }, - { - "alias": "process", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "hide": false, - "measurement": "process_cpu_usage", - "orderByTime": "ASC", - "policy": "default", - "refId": "B", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - }, - { - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "null" - ], - "type": "fill" - } - ], - "hide": true, - "orderByTime": "ASC", - "policy": "default", - "refId": "C", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "tags": [] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "CPU 使用率", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "x-axis": true, - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "y-axis": true, - "y_formats": [ - "short", - "short" - ], - "yaxes": [ - { - "decimals": 1, - "format": "percentunit", - "label": "", - "logBase": 1, - "max": "1", - "min": 0, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_INFLUXDB}", - "description": "CPU负载", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": { - "leftLogBase": 1, - "leftMax": null, - "leftMin": null, - "rightLogBase": 1, - "rightMax": null, - "rightMin": null - }, - "gridPos": { - "h": 7, - "w": 6, - "x": 6, - "y": 21 - }, - "hiddenSeries": false, - "id": 93, - "legend": { - "avg": false, - "current": true, - "max": true, - "min": false, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.1.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "load1m", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "measurement": "system_load_average_1m", - "orderByTime": "ASC", - "policy": "default", - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "step": 2400, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - }, - { - "alias": "cpu核数", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "measurement": "system_cpu_count", - "orderByTime": "ASC", - "policy": "default", - "refId": "B", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Load", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "x-axis": true, - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "y-axis": true, - "y_formats": [ - "short", - "short" - ], - "yaxes": [ - { - "decimals": 1, - "format": "short", - "label": "", - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_INFLUXDB}", - "description": "系统线程使用情况", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": { - "leftLogBase": 1, - "leftMax": null, - "leftMin": null, - "rightLogBase": 1, - "rightMax": null, - "rightMin": null - }, - "gridPos": { - "h": 7, - "w": 6, - "x": 12, - "y": 21 - }, - "hiddenSeries": false, - "id": 32, - "legend": { - "avg": false, - "current": true, - "max": true, - "min": false, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.1.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "live", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "measurement": "jvm_threads_live", - "orderByTime": "ASC", - "policy": "default", - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "step": 2400, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - }, - { - "alias": "daemon", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "measurement": "jvm_threads_daemon", - "orderByTime": "ASC", - "policy": "default", - "refId": "B", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "step": 2400, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - }, - { - "alias": "peak", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "measurement": "jvm_threads_peak", - "orderByTime": "ASC", - "policy": "default", - "refId": "C", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "step": 2400, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "线程数", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "x-axis": true, - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "y-axis": true, - "y_formats": [ - "short", - "short" - ], - "yaxes": [ - { - "decimals": 0, - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": { - "blocked": "#bf1b00", - "new": "#fce2de", - "runnable": "#7eb26d", - "terminated": "#511749", - "timed-waiting": "#c15c17", - "waiting": "#eab839" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_INFLUXDB}", - "description": "需特别关注blocked的线程数, 这意味着线程被阻塞了, 如果线程全部是blocked状态, 则系统无法处理新请求", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 6, - "x": 18, - "y": 21 - }, - "hiddenSeries": false, - "id": 124, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "hideEmpty": false, - "hideZero": false, - "max": true, - "min": false, - "rightSide": false, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.1.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "$tag_state", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "state" - ], - "type": "tag" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "measurement": "jvm_threads_states", - "orderByTime": "ASC", - "policy": "default", - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "各状态线程数", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": { - "debug": "#1F78C1", - "error": "#BF1B00", - "info": "#508642", - "trace": "#6ED0E0", - "warn": "#EAB839" - }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_INFLUXDB}", - "description": "Logback日志数量", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": { - "leftLogBase": 1, - "leftMax": null, - "leftMin": null, - "rightLogBase": 1, - "rightMax": null, - "rightMin": null - }, - "gridPos": { - "h": 7, - "w": 12, - "x": 0, - "y": 28 - }, - "height": "", - "hiddenSeries": false, - "id": 91, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "hideEmpty": false, - "hideZero": false, - "max": true, - "min": false, - "rightSide": false, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": true, - "pluginVersion": "7.1.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [ - { - "alias": "error", - "yaxis": 1 - }, - { - "alias": "warn", - "yaxis": 1 - } - ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "$tag_level", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "level" - ], - "type": "tag" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "interval": "", - "measurement": "logback_events", - "orderByTime": "ASC", - "policy": "default", - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "step": 1200, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Logback日志数", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "x-axis": true, - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "y-axis": true, - "y_formats": [ - "short", - "short" - ], - "yaxes": [ - { - "decimals": 0, - "format": "opm", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_INFLUXDB}", - "description": "JVM打开的文件描述符数量", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": { - "leftLogBase": 1, - "leftMax": null, - "leftMin": null, - "rightLogBase": 1, - "rightMax": null, - "rightMin": null - }, - "gridPos": { - "h": 7, - "w": 12, - "x": 12, - "y": 28 - }, - "hiddenSeries": false, - "id": 61, - "legend": { - "avg": false, - "current": true, - "max": true, - "min": false, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.1.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "open", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "hide": false, - "measurement": "process_files_open", - "orderByTime": "ASC", - "policy": "default", - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "step": 2400, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - }, - { - "alias": "max", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "hide": false, - "measurement": "process_files_max", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT mean(\"value\") FROM \"process_files_max\" WHERE (\"service\" = 'select tag value') AND $timeFilter GROUP BY time($__interval) fill(null)", - "rawQuery": false, - "refId": "B", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "step": 2400, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "文件描述符", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "x-axis": true, - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "y-axis": true, - "y_formats": [ - "short", - "short" - ], - "yaxes": [ - { - "decimals": 0, - "format": "short", - "label": null, - "logBase": 10, - "max": null, - "min": 0, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "collapsed": false, - "datasource": "${DS_INFLUXDB}", - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 35 - }, - "id": 129, - "panels": [], - "repeat": null, - "title": "JVM 堆内存详细", - "type": "row" - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_INFLUXDB}", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": { - "leftLogBase": 1, - "leftMax": null, - "leftMin": null, - "rightLogBase": 1, - "rightMax": null, - "rightMin": null - }, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 36 - }, - "hiddenSeries": false, - "id": 3, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": false, - "rightSide": false, - "show": false, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "maxPerRow": 3, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.1.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": "jvm_memory_pool_heap", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "used", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "hide": false, - "interval": "", - "measurement": "jvm_memory_used", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT mean(\"value\") FROM \"jvm_memory_committed\" WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/ AND \"id\" =~ /^$jvm_memory_pool_nonheap$/) AND $timeFilter GROUP BY time($__interval) fill(null)", - "rawQuery": false, - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "step": 1800, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - }, - { - "condition": "AND", - "key": "id", - "operator": "=~", - "value": "/^$jvm_memory_pool_nonheap$/" - } - ] - }, - { - "alias": "max", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "hide": false, - "interval": "", - "measurement": "jvm_memory_max", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT mean(\"value\") FROM \"jvm_memory_used\" WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/ AND \"id\" =~ 'select tag value') AND $timeFilter GROUP BY time($__interval) fill(null)", - "rawQuery": false, - "refId": "B", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "step": 1800, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - }, - { - "condition": "AND", - "key": "id", - "operator": "=~", - "value": "/^$jvm_memory_pool_heap$/" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "$jvm_memory_pool_heap", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "x-axis": true, - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "y-axis": true, - "y_formats": [ - "mbytes", - "short" - ], - "yaxes": [ - { - "format": "bytes", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "collapsed": false, - "datasource": "${DS_INFLUXDB}", - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 43 - }, - "id": 130, - "panels": [], - "repeat": null, - "title": "JVM 非堆内存详细", - "type": "row" - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_INFLUXDB}", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": { - "leftLogBase": 1, - "leftMax": null, - "leftMin": null, - "rightLogBase": 1, - "rightMax": null, - "rightMin": null - }, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 44 - }, - "hiddenSeries": false, - "id": 78, - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "max": true, - "min": false, - "rightSide": false, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [], - "maxPerRow": 3, - "nullPointMode": "null as zero", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.1.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": "jvm_memory_pool_nonheap", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "used", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "hide": false, - "interval": "", - "measurement": "jvm_memory_used", - "orderByTime": "ASC", - "policy": "default", - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "step": 1800, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - }, - { - "condition": "AND", - "key": "id", - "operator": "=~", - "value": "/^$jvm_memory_pool_nonheap$/" - } - ] - }, - { - "alias": "commited", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "hide": false, - "interval": "", - "measurement": "jvm_memory_committed", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT mean(\"value\") FROM \"jvm_memory_committed\" WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/ AND \"id\" =~ /^$jvm_memory_pool_nonheap$/) AND $timeFilter GROUP BY time($__interval) fill(none)", - "rawQuery": false, - "refId": "B", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "step": 1800, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - }, - { - "condition": "AND", - "key": "id", - "operator": "=~", - "value": "/^$jvm_memory_pool_nonheap$/" - } - ] - }, - { - "alias": "max", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "hide": false, - "interval": "", - "measurement": "jvm_memory_max", - "orderByTime": "ASC", - "policy": "default", - "refId": "C", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "step": 1800, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - }, - { - "condition": "AND", - "key": "id", - "operator": "=~", - "value": "/^$jvm_memory_pool_nonheap$/" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "$jvm_memory_pool_nonheap", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "x-axis": true, - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "y-axis": true, - "y_formats": [ - "mbytes", - "short" - ], - "yaxes": [ - { - "format": "bytes", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "collapsed": false, - "datasource": "${DS_INFLUXDB}", - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 51 - }, - "id": 131, - "panels": [], - "repeat": null, - "title": "垃圾回收(GC)", - "type": "row" - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_INFLUXDB}", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 0, - "y": 52 - }, - "hiddenSeries": false, - "id": 98, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.1.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "$tag_action($tag_cause)", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "action" - ], - "type": "tag" - }, - { - "params": [ - "cause" - ], - "type": "tag" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "hide": false, - "measurement": "jvm_gc_pause", - "orderByTime": "ASC", - "policy": "default", - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "count" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "GC 次数", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "opm", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "format": "short", - "label": "", - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_INFLUXDB}", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 8, - "y": 52 - }, - "hiddenSeries": false, - "id": 101, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null as zero", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.1.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "avg $tag_action ($tag_cause)", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "action" - ], - "type": "tag" - }, - { - "params": [ - "cause" - ], - "type": "tag" - }, - { - "params": [ - "null" - ], - "type": "fill" - } - ], - "hide": false, - "instant": false, - "measurement": "jvm_gc_pause", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT sum(\"sum\") FROM \"jvm_gc_pause\" WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/) AND $timeFilter GROUP BY time($__interval), \"action\", \"cause\" fill(none)", - "rawQuery": false, - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "sum" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - }, - { - "alias": "max $tag_action ($tag_cause)", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "action" - ], - "type": "tag" - }, - { - "params": [ - "cause" - ], - "type": "tag" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "hide": false, - "instant": false, - "measurement": "jvm_gc_pause", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT mean(\"value\") FROM \"jvm_gc_pause\" WHERE (\"service\" =~ /^$service$/ AND \"instance\" = 'select tag value') AND $timeFilter GROUP BY time($__interval), \"action\", \"cause\" fill(none)", - "rawQuery": false, - "refId": "B", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "upper" - ], - "type": "field" - }, - { - "params": [], - "type": "max" - } - ] - ], - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "GC暂停时间", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "ms", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "format": "short", - "label": "", - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_INFLUXDB}", - "description": "内存分配的大小, 以及从新生代晋升到老年代的内存大小", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 8, - "x": 16, - "y": 52 - }, - "hiddenSeries": false, - "id": 99, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null as zero", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.1.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "allocated", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "null" - ], - "type": "fill" - } - ], - "interval": "", - "measurement": "jvm_gc_memory_allocated", - "orderByTime": "ASC", - "policy": "default", - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - }, - { - "alias": "promoted", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "null" - ], - "type": "fill" - } - ], - "interval": "", - "orderByTime": "ASC", - "policy": "default", - "refId": "B", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "tags": [] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "内存分配/晋升", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "Bps", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "collapsed": false, - "datasource": "${DS_INFLUXDB}", - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 59 - }, - "id": 132, - "panels": [], - "repeat": null, - "title": "类加载", - "type": "row" - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_INFLUXDB}", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": { - "leftLogBase": 1, - "leftMax": null, - "leftMin": null, - "rightLogBase": 1, - "rightMax": null, - "rightMin": null - }, - "gridPos": { - "h": 7, - "w": 12, - "x": 0, - "y": 60 - }, - "hiddenSeries": false, - "id": 37, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.1.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "loaded", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "measurement": "jvm_classes_loaded", - "orderByTime": "ASC", - "policy": "default", - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "step": 1200, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "已加载的类的数量", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "x-axis": true, - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "y-axis": true, - "y_formats": [ - "short", - "short" - ], - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_INFLUXDB}", - "description": "可能增加或减少, 在Java中使用一些脚本语言例如groovy时, 需要关注, 防止因为逻辑异常产生大量的类, 进而导致metaspace满, 而metaspace满会触发full gc, 如无法释放则会导致JVM hang住", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": { - "leftLogBase": 1, - "leftMax": null, - "leftMin": null, - "rightLogBase": 1, - "rightMax": null, - "rightMin": null - }, - "gridPos": { - "h": 7, - "w": 12, - "x": 12, - "y": 60 - }, - "hiddenSeries": false, - "id": 38, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.1.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "delta-1m", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "hide": false, - "interval": "", - "measurement": "jvm_classes_loaded", - "orderByTime": "ASC", - "policy": "default", - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - }, - { - "params": [], - "type": "difference" - } - ] - ], - "step": 1200, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "加载类数量变化", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "x-axis": true, - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "y-axis": true, - "y_formats": [ - "ops", - "short" - ], - "yaxes": [ - { - "decimals": null, - "format": "short", - "label": "", - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "collapsed": false, - "datasource": "${DS_INFLUXDB}", - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 67 - }, - "id": 133, - "panels": [], - "repeat": null, - "title": "Buffer Pools", - "type": "row" - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_INFLUXDB}", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": { - "leftLogBase": 1, - "leftMax": null, - "leftMin": null, - "rightLogBase": 1, - "rightMax": null, - "rightMin": null - }, - "gridPos": { - "h": 7, - "w": 6, - "x": 0, - "y": 68 - }, - "hiddenSeries": false, - "id": 33, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null as zero", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.1.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "used", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "measurement": "jvm_buffer_memory_used", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT mean(\"value\") FROM \"jvm_buffer_memory_used\" WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/ AND \"id\" = 'direct') AND $timeFilter GROUP BY time($__interval) fill(none)", - "rawQuery": false, - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "step": 2400, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - }, - { - "condition": "AND", - "key": "id", - "operator": "=", - "value": "direct" - } - ] - }, - { - "alias": "capacity", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "measurement": "jvm_buffer_total_capacity", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT mean(\"value\") FROM \"jvm_buffer_memory_used\" WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/ AND \"id\" = 'direct') AND $timeFilter GROUP BY time($__interval) fill(none)", - "rawQuery": false, - "refId": "B", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "step": 2400, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - }, - { - "condition": "AND", - "key": "id", - "operator": "=", - "value": "direct" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Direct Buffers", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "x-axis": true, - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "y-axis": true, - "y_formats": [ - "short", - "short" - ], - "yaxes": [ - { - "format": "bytes", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_INFLUXDB}", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": { - "leftLogBase": 1, - "leftMax": null, - "leftMin": null, - "rightLogBase": 1, - "rightMax": null, - "rightMin": null - }, - "gridPos": { - "h": 7, - "w": 6, - "x": 6, - "y": 68 - }, - "hiddenSeries": false, - "id": 83, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null as zero", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.1.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "count", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "measurement": "jvm_buffer_count", - "orderByTime": "ASC", - "policy": "default", - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "step": 2400, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - }, - { - "condition": "AND", - "key": "id", - "operator": "=", - "value": "direct" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Direct Buffers", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "x-axis": true, - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "y-axis": true, - "y_formats": [ - "short", - "short" - ], - "yaxes": [ - { - "decimals": 0, - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_INFLUXDB}", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": { - "leftLogBase": 1, - "leftMax": null, - "leftMin": null, - "rightLogBase": 1, - "rightMax": null, - "rightMin": null - }, - "gridPos": { - "h": 7, - "w": 6, - "x": 12, - "y": 68 - }, - "hiddenSeries": false, - "id": 149, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null as zero", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.1.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "used", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "measurement": "jvm_buffer_memory_used", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT mean(\"value\") FROM \"jvm_buffer_memory_used\" WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/ AND \"id\" = 'direct') AND $timeFilter GROUP BY time($__interval) fill(none)", - "rawQuery": false, - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "step": 2400, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - }, - { - "condition": "AND", - "key": "id", - "operator": "=", - "value": "mapped" - } - ] - }, - { - "alias": "capacity", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "measurement": "jvm_buffer_total_capacity", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT mean(\"value\") FROM \"jvm_buffer_memory_used\" WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/ AND \"id\" = 'direct') AND $timeFilter GROUP BY time($__interval) fill(none)", - "rawQuery": false, - "refId": "B", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "step": 2400, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - }, - { - "condition": "AND", - "key": "id", - "operator": "=", - "value": "mapped" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Mapped Buffers", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "x-axis": true, - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "y-axis": true, - "y_formats": [ - "short", - "short" - ], - "yaxes": [ - { - "format": "bytes", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_INFLUXDB}", - "editable": true, - "error": false, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "grid": { - "leftLogBase": 1, - "leftMax": null, - "leftMin": null, - "rightLogBase": 1, - "rightMax": null, - "rightMin": null - }, - "gridPos": { - "h": 7, - "w": 6, - "x": 18, - "y": 68 - }, - "hiddenSeries": false, - "id": 150, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "links": [], - "nullPointMode": "null as zero", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.1.3", - "pointradius": 5, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "count", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "none" - ], - "type": "fill" - } - ], - "measurement": "jvm_buffer_count", - "orderByTime": "ASC", - "policy": "default", - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "step": 2400, - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - }, - { - "condition": "AND", - "key": "id", - "operator": "=", - "value": "mapped" - } - ] - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Mapped Buffers", - "tooltip": { - "msResolution": false, - "shared": true, - "sort": 0, - "value_type": "cumulative" - }, - "type": "graph", - "x-axis": true, - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "y-axis": true, - "y_formats": [ - "short", - "short" - ], - "yaxes": [ - { - "decimals": 0, - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - } - ], - "refresh": false, - "schemaVersion": 26, - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "allValue": null, - "current": {}, - "datasource": "${DS_INFLUXDB}", - "definition": "", - "error": null, - "hide": 0, - "includeAll": false, - "label": "服务", - "multi": false, - "name": "service", - "options": [], - "query": "show tag values from jvm_memory_used with key = \"service\"", - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allFormat": "glob", - "allValue": null, - "current": {}, - "datasource": "${DS_INFLUXDB}", - "definition": "", - "error": null, - "hide": 0, - "includeAll": false, - "label": "实例", - "multi": false, - "multiFormat": "glob", - "name": "instance", - "options": [], - "query": "show tag values from jvm_memory_used with key = \"instance\" where service = '$service'", - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allFormat": "glob", - "allValue": null, - "current": {}, - "datasource": "${DS_INFLUXDB}", - "definition": "", - "error": null, - "hide": 0, - "includeAll": true, - "label": "JVM Memory Pools Heap", - "multi": false, - "multiFormat": "glob", - "name": "jvm_memory_pool_heap", - "options": [], - "query": "show tag values from jvm_memory_used with key = \"id\" where service = '$service' and instance =~ /^$instance$/ and area = 'heap'", - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 1, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allFormat": "glob", - "allValue": null, - "current": {}, - "datasource": "${DS_INFLUXDB}", - "definition": "", - "error": null, - "hide": 0, - "includeAll": true, - "label": "JVM Memory Pools Non-Heap", - "multi": false, - "multiFormat": "glob", - "name": "jvm_memory_pool_nonheap", - "options": [], - "query": "show tag values from jvm_memory_used with key = \"id\" where service = '$service' and instance =~ /^$instance$/ and area = 'nonheap'", - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 2, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - } - ] - }, - "time": { - "from": "now-24h", - "to": "now" - }, - "timepicker": { - "now": true, - "refresh_intervals": [ - "5s", - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ], - "time_options": [ - "5m", - "15m", - "1h", - "6h", - "12h", - "24h", - "2d", - "7d", - "30d" - ] - }, - "timezone": "browser", - "title": "制品库JVM监控大盘", - "uid": "UOJjh1SMZ", - "version": 1 -} \ No newline at end of file diff --git a/support-files/storage/grafana/dashboard-transfer.json b/support-files/storage/grafana/dashboard-transfer.json deleted file mode 100644 index d0f48000c1a..00000000000 --- a/support-files/storage/grafana/dashboard-transfer.json +++ /dev/null @@ -1,658 +0,0 @@ -{ - "__inputs": [ - { - "name": "DS_INFLUXDB", - "label": "InfluxDB", - "description": "", - "type": "datasource", - "pluginId": "influxdb", - "pluginName": "InfluxDB" - } - ], - "__requires": [ - { - "type": "grafana", - "id": "grafana", - "name": "Grafana", - "version": "7.1.3" - }, - { - "type": "panel", - "id": "graph", - "name": "Graph", - "version": "" - }, - { - "type": "datasource", - "id": "influxdb", - "name": "InfluxDB", - "version": "1.0.0" - }, - { - "type": "panel", - "id": "table", - "name": "Table", - "version": "" - } - ], - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": true, - "gnetId": null, - "graphTooltip": 0, - "id": null, - "iteration": 1614606643201, - "links": [], - "panels": [ - { - "collapsed": false, - "datasource": "${DS_INFLUXDB}", - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 6, - "panels": [], - "repeat": "type", - "title": "$type", - "type": "row" - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "${DS_INFLUXDB}", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 1 - }, - "hiddenSeries": false, - "id": 4, - "interval": "10s", - "legend": { - "alignAsTable": false, - "avg": false, - "current": true, - "hideZero": false, - "max": true, - "min": true, - "rightSide": false, - "show": true, - "total": true, - "values": true - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null as zero", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.1.3", - "pointradius": 2, - "points": false, - "renderer": "flot", - "repeat": null, - "repeatDirection": "v", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "alias": "$tag_storage", - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "storage" - ], - "type": "tag" - }, - { - "params": [ - "null" - ], - "type": "fill" - } - ], - "measurement": "artifact_transfer_record", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT count(\"average\") FROM \"artifact_transfer_record\" WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/ AND \"storage\" =~ /^$storage$/ AND \"type\" =~ /^$type$/ AND bytes >= $bytes*1024*1024 AND average < $average*1024*1024 ) AND $timeFilter GROUP BY time($__interval), \"storage\" fill(null)", - "rawQuery": true, - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "average" - ], - "type": "field" - }, - { - "params": [], - "type": "count" - } - ] - ], - "tags": [ - { - "key": "service", - "operator": "=~", - "value": "/^$service$/" - }, - { - "condition": "AND", - "key": "instance", - "operator": "=~", - "value": "/^$instance$/" - }, - { - "condition": "AND", - "key": "storage", - "operator": "=~", - "value": "/^$storage$/" - }, - { - "condition": "AND", - "key": "type", - "operator": "=~", - "value": "/^$type$/" - } - ] - } - ], - "thresholds": [ - { - "colorMode": "critical", - "fill": true, - "line": true, - "op": "gt", - "value": 5, - "yaxis": "left" - } - ], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "传输数量", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "datasource": "${DS_INFLUXDB}", - "description": "", - "fieldConfig": { - "defaults": { - "custom": { - "align": "center", - "displayMode": "auto", - "filterable": true - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "时间" - }, - "properties": [ - { - "id": "custom.width", - "value": 155 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "服务" - }, - "properties": [ - { - "id": "custom.width", - "value": 115 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "服务实例" - }, - "properties": [ - { - "id": "custom.width", - "value": 260 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "存储实例" - }, - "properties": [ - { - "id": "custom.width", - "value": 100 - }, - { - "id": "custom.displayMode", - "value": "color-text" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "传输类型" - }, - "properties": [ - { - "id": "custom.width", - "value": 100 - }, - { - "id": "custom.displayMode", - "value": "color-text" - }, - { - "id": "color", - "value": { - "mode": "palette-classic" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "大小" - }, - "properties": [ - { - "id": "custom.width", - "value": 120 - }, - { - "id": "unit", - "value": "bytes" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "耗时" - }, - "properties": [ - { - "id": "unit", - "value": "ns" - }, - { - "id": "custom.width", - "value": 120 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "平均速度" - }, - "properties": [ - { - "id": "unit", - "value": "Bps" - }, - { - "id": "custom.displayMode", - "value": "gradient-gauge" - }, - { - "id": "color", - "value": { - "mode": "continuous-YlRd" - } - }, - { - "id": "custom.width", - "value": 450 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "文件sha256" - }, - "properties": [ - { - "id": "custom.width", - "value": 150 - } - ] - } - ] - }, - "gridPos": { - "h": 10, - "w": 24, - "x": 0, - "y": 9 - }, - "id": 2, - "options": { - "showHeader": true, - "sortBy": [] - }, - "pluginVersion": "7.1.3", - "targets": [ - { - "alias": "", - "groupBy": [], - "hide": false, - "measurement": "artifact_transfer_record", - "orderByTime": "ASC", - "policy": "default", - "query": "SELECT * FROM \"artifact_transfer_record\" WHERE (\"service\" =~ /^$service$/ AND \"instance\" =~ /^$instance$/ AND \"storage\" =~ /^$storage$/ AND \"type\" =~ /^$type$/) AND $timeFilter AND bytes >= $bytes*1024*1024 AND average < $average*1024*1024", - "rawQuery": true, - "refId": "A", - "resultFormat": "logs", - "select": [ - [ - { - "params": [ - "value" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - } - ] - ], - "tags": [] - } - ], - "timeFrom": null, - "timeShift": null, - "title": "传输记录", - "transformations": [ - { - "id": "organize", - "options": { - "excludeByName": { - "Time": false, - "sha256": false, - "type": false - }, - "indexByName": { - "Time": 0, - "average": 7, - "bytes": 5, - "elapsed": 6, - "instance": 2, - "service": 1, - "sha256": 8, - "storage": 3, - "type": 4 - }, - "renameByName": { - "Time": "时间", - "average": "平均速度", - "bytes": "大小", - "elapsed": "耗时", - "instance": "服务实例", - "service": "服务", - "sha256": "文件sha256", - "storage": "存储实例", - "type": "传输类型" - } - } - } - ], - "type": "table" - } - ], - "refresh": false, - "schemaVersion": 26, - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "allFormat": "glob", - "allValue": null, - "current": {}, - "datasource": "${DS_INFLUXDB}", - "definition": "", - "error": null, - "hide": 0, - "includeAll": true, - "label": "服务", - "multi": true, - "name": "service", - "options": [], - "query": "show tag values from artifact_transfer_record with key = \"service\"", - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allFormat": "glob", - "allValue": ".*", - "current": {}, - "datasource": "${DS_INFLUXDB}", - "definition": "", - "error": null, - "hide": 0, - "includeAll": true, - "label": "服务实例", - "multi": true, - "name": "instance", - "options": [], - "query": "show tag values from artifact_transfer_record with key = \"instance\" where service = '$service'", - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allFormat": "glob", - "allValue": ".*", - "current": {}, - "datasource": "${DS_INFLUXDB}", - "definition": "", - "error": null, - "hide": 0, - "includeAll": true, - "label": "存储实例", - "multi": true, - "name": "storage", - "options": [], - "query": "show tag values from artifact_transfer_record with key = \"storage\"", - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allFormat": "glob", - "allValue": ".*", - "current": {}, - "datasource": "${DS_INFLUXDB}", - "definition": "", - "error": null, - "hide": 0, - "includeAll": true, - "label": "传输类型", - "multi": true, - "name": "type", - "options": [], - "query": "show tag values from artifact_transfer_record with key = \"type\"", - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - }, - { - "allFormat": "glob", - "current": { - "selected": false, - "text": "5", - "value": "5" - }, - "datasource": null, - "error": null, - "hide": 0, - "label": "文件大小(MB)>=", - "name": "bytes", - "options": [ - { - "selected": true, - "text": "5", - "value": "5" - } - ], - "query": "5", - "skipUrlSync": false, - "type": "textbox" - }, - { - "allFormat": "glob", - "current": { - "selected": false, - "text": "1", - "value": "1" - }, - "datasource": null, - "error": null, - "hide": 0, - "label": "传输速度(MB/s)<=", - "name": "average", - "options": [ - { - "selected": true, - "text": "1", - "value": "1" - } - ], - "query": "1", - "skipUrlSync": false, - "type": "textbox" - } - ] - }, - "time": { - "from": "now-1h", - "to": "now" - }, - "timepicker": {}, - "timezone": "browser", - "title": "构件传输记录", - "uid": "UXBOxybGk", - "version": 3 -} \ No newline at end of file diff --git a/support-files/storage/kubernetes/README.md b/support-files/storage/kubernetes/README.md deleted file mode 100644 index adcb3c70cd6..00000000000 --- a/support-files/storage/kubernetes/README.md +++ /dev/null @@ -1 +0,0 @@ -# Kubernetes部署 \ No newline at end of file diff --git a/support-files/storage/kubernetes/charts/bkrepo/.helmignore b/support-files/storage/kubernetes/charts/bkrepo/.helmignore deleted file mode 100644 index 0e8a0eb36f4..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# Patterns to ignore when building packages. -# This supports shell glob matching, relative path matching, and -# negation (prefixed with !). Only one pattern per line. -.DS_Store -# Common VCS dirs -.git/ -.gitignore -.bzr/ -.bzrignore -.hg/ -.hgignore -.svn/ -# Common backup files -*.swp -*.bak -*.tmp -*.orig -*~ -# Various IDEs -.project -.idea/ -*.tmproj -.vscode/ diff --git a/support-files/storage/kubernetes/charts/bkrepo/Chart.lock b/support-files/storage/kubernetes/charts/bkrepo/Chart.lock deleted file mode 100644 index 3eee262feaa..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/Chart.lock +++ /dev/null @@ -1,12 +0,0 @@ -dependencies: -- name: common - repository: https://charts.bitnami.com/bitnami - version: 1.4.1 -- name: nginx-ingress-controller - repository: https://charts.bitnami.com/bitnami - version: 7.4.8 -- name: mongodb - repository: https://charts.bitnami.com/bitnami - version: 10.10.2 -digest: sha256:e869a478871055f2945be0298ea1577d2bcaa91442d6a6749b8d4fe605e1797d -generated: "2021-03-18T17:11:06.342424+08:00" diff --git a/support-files/storage/kubernetes/charts/bkrepo/Chart.yaml b/support-files/storage/kubernetes/charts/bkrepo/Chart.yaml deleted file mode 100644 index 0aa01f4b460..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/Chart.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: v2 -name: bkrepo -description: A Helm chart for BlueKing Repository -type: application -version: 1.1.1 -appVersion: 1.1.1 - -dependencies: - - name: common - version: 1.4.1 - repository: https://charts.bitnami.com/bitnami - - name: nginx-ingress-controller - version: 7.4.8 - repository: https://charts.bitnami.com/bitnami - condition: nginx-ingress-controller.enabled - - name: mongodb - version: 10.10.2 - repository: https://charts.bitnami.com/bitnami - condition: mongodb.enabled diff --git a/support-files/storage/kubernetes/charts/bkrepo/README.md b/support-files/storage/kubernetes/charts/bkrepo/README.md deleted file mode 100644 index 4f922e8c26f..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/README.md +++ /dev/null @@ -1,419 +0,0 @@ -# BK-REPO - -此Chart用于在Kubernetes集群中通过helm部署bkrepo - -## 环境要求 -- Kubernetes 1.12+ -- Helm 3+ -- PV provisioner - -## 安装Chart -使用以下命令安装名称为`bkrepo`的release, 其中``代表helm仓库地址: - -```shell -$ helm repo add bkee -$ helm install bkrepo bkee/bkrepo -``` - -上述命令将使用默认配置在Kubernetes集群中部署bkrepo, 并输出访问指引。 - -## 卸载Chart -使用以下命令卸载`bkrepo`: - -```shell -$ helm uninstall bkrepo -``` - -上述命令将移除所有和bkrepo相关的Kubernetes组件,并删除release。 - -## Chart依赖 -- [bitnami/nginx-ingress-controller](https://github.com/bitnami/charts/tree/master/bitnami/nginx-ingress-controller) -- [bitnami/mongodb](https://github.com/bitnami/charts/blob/master/bitnami/mongodb) - -## 配置说明 -下面展示了可配置的参数列表以及默认值 - -### Charts 全局设置 - -|参数|描述|默认值 | -|---|---|---| -| `global.imageRegistry` | Global Docker image registry | `nil` | -| `global.imagePullSecrets` | Global Docker registry secret names as an array | `[]` (does not add image pull secrets to deployed pods) | -| `global.storageClass` | Global storage class for dynamic provisioning | `nil` | - -### Kubernetes组件公共配置 - -下列参数用于配置Kubernetes组件的公共属性,一份配置作用到每个组件 - -|参数|描述|默认值 | -|---|---|---| -| `commonAnnotations` | Annotations to add to all deployed objects | `{}` | -| `commonLabels` | Labels to add to all deployed objects | `{}` | - -### Kubernetes组件通用配置 - -下列参数表示Kubernetes组件的通用配置,每个微服务进行单独配置。能够配置的微服务有: - -- gateway -- repository -- auth -- generic -- docker -- npm -- pypi -- helm - -|参数|描述|默认值 | -|---|---|---| -| `image.registry` | 镜像仓库 | `mirrors.tencent.com` | -| `image.repository` | 镜像名称 | `bkrepo/xxx` | -| `image.tag` | 镜像tag | `{TAG_NAME}` | -| `image.pullPolicy` | 镜像拉取策略 | `IfNotPresent` | -| `image.pullSecrets` | 镜像拉取Secret名称数组 | `[]` | -| `imagePullSecrets` | 镜像拉取secret名称列表 | `[]` | -| `securityContext` | 容器 Security Context | `{}` | -| `replicaCount` | Number of pod replicas | `2` | -| `hostAliases` | Add deployment host aliases | `[]` | -| `resources.limits` | The resources limits for containers | `{}` | -| `resources.requests` | The requested resources for containers | `{}` | -| `affinity` | Affinity for pod assignment (evaluated as a template) | `{}` | -| `containerSecurityContext.enabled` | Enable containers' Security Context | `false` | -| `containerSecurityContext.runAsUser` | Containers' Security Context | `1001` | -| `containerSecurityContext.runAsNonRoot` | Containers' Security Context Non Root | `true` | -| `nodeAffinityPreset.key` | Node label key to match Ignored if `affinity` is set. | `""` | -| `nodeAffinityPreset.type` | Node affinity preset type. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `""` | -| `nodeAffinityPreset.values` | Node label values to match. Ignored if `affinity` is set. | `[]` | -| `nodeSelector` | Node labels for pod assignment | `{}` (evaluated as a template) | -| `podLabels` | Add additional labels to the pod (evaluated as a template) | `nil` | -| `podAnnotations` | Pod annotations | `{}` (evaluated as a template) | -| `podAffinityPreset` | Pod affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `""` | -| `podAntiAffinityPreset` | Pod anti-affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `""` | -| `podSecurityContext.enabled` | Enable pod security context | `true` | -| `podSecurityContext.fsGroup` | fsGroup ID for the pod | `1001` | -| `priorityClassName` | Define the priority class name for the pod. | `""` | -| `tolerations` | Tolerations for pod assignment | `[]` (evaluated as a template) | - -### RBAC配置 - -|参数|描述|默认值 | -|---|---|---| -| `rbac.create` | If true, create & use RBAC resources | `true` | -| `serviceAccount.annotations` | Annotations for service account | `{}` | -| `serviceAccount.create` | If true, create a service account | `false` | -| `serviceAccount.name` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template. | `` | - -### ingress 配置 - -|参数|描述|默认值 | -|---|---|---| -| `ingress.enabled` | 是否创建ingress | `true` | -| `annotations` | ingress标注 | Check `values.yaml` | - -### nginx-ingress-controller 配置 - -默认将部署`nginx-ingress-controller`,如果不需要可以关闭。 -相关配置请参考[bitnami/nginx-ingress-controller](https://github.com/bitnami/charts/tree/master/bitnami/) - -|参数|描述|默认值 | -|---|---|---| -| `nginx-ingress-controller.enabled` | 是否部署nginx ingress controller | `true` | -| `nginx-ingress-controller.defaultBackend.enabled` | nginx ingress controller默认backend | `false` | - -### mongodb 配置 -默认将部署mongodb,如果不需要可以关闭。 -相关配置请参考[bitnami/mongodb](https://github.com/bitnami/charts/blob/master/bitnami/mongodb) - -|参数|描述|默认值 | -|---|---|---| -| `mongodb.enabled` | 是否部署mognodb。如果需要使用外部数据库,设置为`false`并配置`externalMongodb` | `true` | -| `mongodb.auth.enabled` | 是否开启认证 | `true` | -| `mongodb.auth.database` | mongodb数据库名称 | `bkrepo` | -| `mongodb.auth.username` | mongodb认证用户名 | `bkrepo` | -| `mongodb.auth.password` | mongodb密码 | `bkrepo` | -| `externalMongodb.uri` | 外部mongodb服务的连接地址。当`mongodb.enabled`配置为`false`时,bkrepo将使用此参数连接外部mongodb | `mongodb://bkrepo:bkrepo@localhost:27017/bkrepo` | - -> 如果需要持久化mongodb数据,请参考[bitnami/mongodb](https://github.com/bitnami/charts/blob/master/bitnami/mongodb)配置存储卷 - -### 数据持久化配置 - -数据持久化配置, 当使用filesystem方式存储时需要配置。 - -|参数|描述|默认值 | -|---|---|---| -| `persistence.enabled` | 是否开启数据持久化,false则使用emptyDir类型volume, pod结束后数据将被清空,无法持久化 | `true` | -| `persistence.accessMode` | PVC Access Mode for bkrepo data volume | `ReadWriteOnce` | -| `persistence.size` | PVC Storage Request for bkrepo data volume | `100Gi` | -| `persistence.storageClass` | 指定storageClass。如果设置为"-", 则禁用动态卷供应; 如果不设置, 将使用默认的storageClass(minikube上是standard) | `nil` | -| `persistence.existingClaim` | 如果开启持久化并且定义了该项,则绑定k8s集群中已存在的pvc | `nil` | - -> 如果开启数据持久化,并且没有配置`existingClaim`,将使用[动态卷供应](https://kubernetes.io/docs/concepts/storage/dynamic-provisioning/)提供存储,使用`storageClass`定义的存储类。**在删除该声明后,这个卷也会被销毁(用于单节点环境,生产环境不推荐)。**。 - -### bkrepo公共配置 - -|参数|描述|默认值 | -|---|---|---| -| `common.imageRegistry` | bkrepo镜像仓库全局配置, 具有最高优先级 | `""` | -| `common.imageTag` | bkrepo镜像tag全局配置, 具有最高优先级 | `""` | -| `common.region` | 部署区域, 可不填 | `""` | -| `common.jvmOption` | jvm启动选项, 如-Xms1024M -Xmx1024M | `""` | -| `common.springProfile` | SpringBoot active profile | `dev` | -| `common.username` | bkrepo初始用户名 | `admin` | -| `common.password` | bkrepo初始密码 | `blueking` | -| `common.mountPath` | pod volume挂载路径 | `/data/storage` | -| `common.config.storage.type` | 存储类型,支持filesystem/cos/s3/hdfs | `filesystem` | -| `common.config.storage.filesystem.path` | filesystem存储方式配置,存储路径 | `/data/storage` | -| `common.config.storage.cos` | cos存储方式配置 | `nil` | -| `common.config.storage.s3` | s3存储方式配置 | `nil` | -| `common.config.storage.hdfs` | hdfs存储方式配置 | `nil` | - -### 数据初始化job配置 - -|参数|描述|默认值 | -|---|---|---| -| `init.mongodb.enabled` | 是否初始化mongodb数据,支持幂等执行 | `true` | -| `init.mongodb.image` | mongodb job镜像拉取相关配置 | Check `values.yaml` | - - -### 网关配置 - -**以下为除Kubernetes组件通用配置之外的配置列表** - -|参数|描述|默认值 | -|---|---|---| -| `gateway.service.type` | 服务类型 | `ClusterIP` | -| `gateway.service.port` | 服务类型为`ClusterIP`时端口设置 | `80` | -| `gateway.service.nodePort` | 服务类型为`NodePort`时端口设置 | `80` | -| `gateway.host` | bkrepo 地址 | `bkrepo.example.com` | -| `gateway.dnsServer` | dns服务器地址,用于配置nginx resolver | `local=on`(openrestry语法,取本机`/etc/resolv.conf`配置) | -| `gateway.authorization` | 网关访问微服务认证信息 | `"Platform MThiNjFjOWMtOTAxYi00ZWEzLTg5YzMtMWY3NGJlOTQ0YjY2OlVzOFpHRFhQcWs4NmN3TXVrWUFCUXFDWkxBa00zSw=="` | -| `gateway.deployMode` | 部署模式,standalone: 独立模式,ci: 与ci搭配模式 | `standalone` | - -### repository服务配置 - -**以下为除Kubernetes组件通用配置之外的配置列表** - -|参数|描述|默认值 | -|---|---|---| -| `repository.config.deletedNodeReserveDays` | 节点被删除后多久清理数据 | `15` | - -### auth服务配置 - -**以下为除Kubernetes组件通用配置之外的配置列表** - -|参数|描述|默认值 | -|---|---|---| -| `auth.config.realm` | 认证realm类型,支持local/devops | `local` | - -### generic服务配置 - -**以下为除Kubernetes组件通用配置之外的配置列表** - -|参数|描述|默认值 | -|---|---|---| -| `generic.enabled` | 是否部署generic | `true` | -| `generic.config.domain` | generic domain地址 | `${gateway.host}/generic` | - -### docker registry服务配置 - -**以下为除Kubernetes组件通用配置之外的配置列表** - -|参数|描述|默认值 | -|---|---|---| -| `docker.enabled` | 是否部署docker | `false` | -| `docker.config ` | docker配置 | `{}` | - -### npm registry服务配置 - -**以下为除Kubernetes组件通用配置之外的配置列表** - -|参数|描述|默认值 | -|---|---|---| -| `npm.enabled` | 是否部署npm | `false` | -| `npm.config.domain` | npm domain地址 | `${gateway.host}/npm` | - -### pypi registry服务配置 - -**以下为除Kubernetes组件通用配置之外的配置列表** - -|参数|描述|默认值 | -|---|---|---| -| `pypi.enabled` | 是否部署pypi | `false` | -| `pypi.config.domain` | pypi domain地址 | `${gateway.host}/pypi` | - -### helm registry服务配置 - -**以下为除Kubernetes组件通用配置之外的配置列表** - -|参数|描述|默认值 | -|---|---|---| -| `helm.enabled` | 是否部署helm | `false` | -| `helm.config` | helm配置 | `{}` | - - -您可以通过`--set key=value[,key=value]`来指定参数进行安装。例如, - -```shell -$ helm install bkrepo bkee/bkrepo \ - --set global.imageRegistry=your.registry.com \ - --set gateway.host=bkrepo.example.com -``` - - -另外,也可以通过指定`YAML`文件的方式来提供参数, - -```shell -$ helm install bkrepo bkee/bkrepo -f values -``` - -可以使用`helm show values`来获取默认配置, - -```shell -# 查看默认配置 -$ helm show values bkee/bkrepo - -# 保存默认配置到文件values.yaml -$ helm show values bkee/bkrepo > values.yaml -``` - -## 配置案例 - -### 1. 使用已有的mongodb -``` -# 关闭mongodb部署 -mongodb.enabled=false -# 设置已有的mongod连接字符串 -common.mongodb.uri=mongodb://user:pass@mongodb-server:27017/bkrepo -``` - -### 2. 使用已有的ingress-controller -``` -# 关闭nginx-ingress-controller部署 -nginx-ingress-controller.enabled=false - -# 根据需要配置ingress annotations -# ingress.annotations.key=value -``` - -### 3. 使用动态卷分配 - -通过使用storageClass动态绑定pv,假设我们创建了一个`storageClassName`为`standard`的pv, - -```yaml -# pv.yaml -apiVersion: v1 -kind: PersistentVolume -metadata: - name: bkrepo-pv -spec: - capacity: - storage: 100Gi - accessModes: - - ReadWriteOnce - storageClassName: "standard" # minikube默认使用storageClass是standard - hostPath: - path: "/data/bkrepo" -``` - -```shell -$ kubectl create -f pv.yaml -``` - -因为在minikube默认使用storageClass是standard,所以使用默认配置进行部署,bkrepo以及mongodb的pvc将自动绑定到这个pv上。 - -同时,我们也可以指定自定义的`storageClass`, - -``` -# 开启数据持久化 -persistence.enabled=true -persistence.storageClass=standard -persistence.accessModes=访问模式 -persistence.size=pvc大小 - -# 如果有需要,同时配置mongodb持久化 -mongodb.persistence.enabled=true -mongodb.persistence.storageClass=standard -``` - -也可以设置全局`storageClass`,将同时应用到bkrepo和mongodb中 -``` -global.storageClass=standard -``` - -### 4. 使用已有的pvc - -``` -# 开启数据持久化 -persistence.enabled=true -persistence.existingClaim=your-persistent-volume-claim -persistence.accessModes=访问模式 -persistence.size=pvc大小 - -# 如果有需要,同时配置mongodb持久化 -mongodb.persistence.enabled=true -mongodb.persistence.existingClaim=your-persistent-volume-claim -``` - -### 5. 内网环境下,使用代理镜像仓库 - -- 单独修改 -``` -# 修改mongodb镜像仓库 -mongodb.image.registry=xxx -# 修改nginx-ingress-controller镜像仓库 -nginx-ingress-controller.image.registry=xxx -# 修改bkrepo镜像仓库,xxx代表服务名称 -xxx.image.registry=xxx -``` - -- 全局修改,应用到所有Charts -``` -global.imageRegistry=xxx -``` - -### 6. 配置不同的服务暴露方式 - -默认通过Ingress暴露服务,也可以使用以下方式: - -- 使用NodePort直接访问 - -``` -ingress.enabled=false -nginx-ingress-controller.enabled=false -gateway.service.type=NodePort -gateway.service.nodePort=30000 -``` -部署成功后,即可通过 bkrepo.example.com:\ 访问(您仍需要配置dns解析) - -- 使用port-forward访问 -``` -ingress.enabled=false -nginx-ingress-controller.enabled=false -gateway.service.type=ClusterIP -``` - -部署成功后,通过`kubectl port-forward`将`bkrepo-gateway`服务暴露出去,即可通过 bkrepo.example.com:\ 访问(您仍需要配置dns解析) -```shell -kubectl port-forward service/bkrepo-gateway :80 -``` - -## 常见问题 - -**1. 首次启动失败,是bkrepo Chart有问题吗** - -答: bkrepo的Chart依赖了`mongodb`和`nignx-ingress-controller`, 这两个依赖的Chart默认从docker.io拉镜像,如果网络不通或被docker hub限制,将导致镜像拉取失败,可以参考配置列表修改镜像地址。 - -**2. 首次启动时间过长,且READY状态为`0/1`?** - -答: 如果选择了部署`mongodb Chart`,需要等待`mongodb`部署完成后,`bkrepo`相关容器才会启动;启动过程涉及到数据表以及索引创建,这个期间容器状态为`Not Ready`。 - -**3. 我卸载了Release立即重新部署,Pod状态一直为`Pending`?** - -答: 如果选择了默认方式使用动态卷供应,当使用`helm uninstall`卸载Release,随后创建的pvc也会被删除,如果在pvc被删除之前重新部署,新启动的`Pod`会进入`Pending`状态。 - -**4. 如何查看日志?** - -答: 有两种方式可以查看日志: 1. kubectl logs pod 查看实时日志 2.日志保存在/data/workspace/logs目录下,可以进入容器内查看 - -**5. 为什么卸载之后重新安装,mongodb以及文件数据都没了?** - -答: 默认创建的pv其`RECLAIM POLICY`为`DELETE`, 在删除该声明后,卷也会被销毁。如果需要数据持久化,请提前创建pvc好并设置`persistence`, \ No newline at end of file diff --git a/support-files/storage/kubernetes/charts/bkrepo/charts/common-1.4.1.tgz b/support-files/storage/kubernetes/charts/bkrepo/charts/common-1.4.1.tgz deleted file mode 100644 index 110cf10636c084a920c9cbd8c77c9a3bb0368cad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12484 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 O0RR6Us#Y@qLID6$ubF88 diff --git a/support-files/storage/kubernetes/charts/bkrepo/charts/mongodb-10.10.2.tgz b/support-files/storage/kubernetes/charts/bkrepo/charts/mongodb-10.10.2.tgz deleted file mode 100644 index a72f27b6d7aa05f4e2298f351286894842aaa259..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55452 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 H#1 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 aU(a99U(Z+g{C@xd0RR7)H;ZKeoCN>`JG__x diff --git a/support-files/storage/kubernetes/charts/bkrepo/charts/nginx-ingress-controller-7.4.8.tgz b/support-files/storage/kubernetes/charts/bkrepo/charts/nginx-ingress-controller-7.4.8.tgz deleted file mode 100644 index 943e3229daf4e3c7db62f7a1fb49f52328a37fc8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32922 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为您的Ingress外部ip - - echo " {{ .Values.gateway.host }}" >> /etc/hosts - {{- if .Values.docker.enabled }} - echo " {{ .Values.gateway.dockerHost }}" >> /etc/hosts - {{- end }} - {{- if .Values.helm.enabled }} - echo " {{ .Values.gateway.helmHost }}" >> /etc/hosts - {{- end }} - - {{- else if contains "NodePort" .Values.gateway.service.type }} - - 添加映射记录到/etc/hosts - - export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "common.names.fullname" . }}-gateway) - export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") - - echo "$NODE_IP {{ .Values.gateway.host }}" >> /etc/hosts - {{- if .Values.docker.enabled }} - echo "$NODE_IP {{ .Values.gateway.dockerHost }}" >> /etc/hosts - {{- end }} - {{- if .Values.helm.enabled }} - echo "$NODE_IP {{ .Values.gateway.helmHost }}" >> /etc/hosts - {{- end }} - {{- else if contains "ClusterIP" .Values.gateway.service.type }} - - 通过port-forward暴露repo-gateway - - kubectl port-forward --namespace {{ .Release.Namespace }} service/{{ include "common.names.fullname" . }}-gateway 80:80 - - - 添加映射记录到/etc/hosts - - echo "127.0.0.1 {{ .Values.gateway.host }}" >> /etc/hosts - {{- if .Values.docker.enabled }} - echo "127.0.0.1 {{ .Values.gateway.dockerHost }}" >> /etc/hosts - {{- end }} - {{- if .Values.helm.enabled }} - echo "127.0.0.1 helm.{{ .Values.gateway.helmHost }}" >> /etc/hosts - {{- end }} - {{- end }} - -2. 访问http://{{ .Values.gateway.host }}/ui/ 验证服务能否正常访问 - - **TIP** 如果使用NodePort或port-forward方式访问,通过http://:{{ .Values.gateway.service.nodePort }}/方式访问文件服务 - - 初始用户名/密码: {{ $username }}/{{ $password }} - 初始项目: blueking - -3. 更多说明请参考页面操作指引以及API文档 - diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/_helpers.tpl b/support-files/storage/kubernetes/charts/bkrepo/templates/_helpers.tpl deleted file mode 100644 index a7bec0c8bdd..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/_helpers.tpl +++ /dev/null @@ -1,90 +0,0 @@ -{{/* -Return the proper Docker Image Registry Secret Names -*/}} -{{- define "bkrepo.imagePullSecrets" -}} -{{- include "common.images.pullSecrets" (dict "images" (list .Values.gateway.image .Values.repository.image .Values.auth.image .Values.init.mongodb.image .Values.generic.image .Values.docker.image .Values.npm.image .Values.pypi.image .Values.helm.image) "global" .Values.global) -}} -{{- end -}} - -{{/* -Create the name of the service account to use -*/}} -{{- define "bkrepo.serviceAccountName" -}} -{{- if .Values.serviceAccount.create -}} - {{ default (printf "%s-foo" (include "common.names.fullname" .)) .Values.serviceAccount.name }} -{{- else -}} - {{ default "default" .Values.serviceAccount.name }} -{{- end -}} -{{- end -}} - - - -{{/* -Create a default fully qualified mongodb subchart. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -*/}} -{{- define "bkrepo.mongodb.fullname" -}} -{{- if .Values.mongodb.fullnameOverride -}} -{{- .Values.mongodb.fullnameOverride | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- $name := default "mongodb" .Values.mongodb.nameOverride -}} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} -{{- end -}} - -{{/* -Return the mongodb connection uri -*/}} -{{- define "bkrepo.mongodbUri" -}} -{{- if eq .Values.mongodb.enabled true -}} -{{- printf "mongodb://%s:%s@%s:27017/%s" .Values.mongodb.auth.username .Values.mongodb.auth.password (include "bkrepo.mongodb.fullname" .) .Values.mongodb.auth.database -}} -{{- else -}} -{{- .Values.externalMongodb.uri -}} -{{- end -}} -{{- end -}} - -{{/* -Return the label key of bk-repo scope -*/}} -{{- define "bkrepo.labelValues.scope" -}} - {{- printf "bk.repo.scope" -}} -{{- end -}} - -{{/* -Return the label value of bk-repo scope backend -*/}} -{{- define "bkrepo.labelValues.scope.backend" -}} - {{- printf "backend" -}} -{{- end -}} - -{{/* -Return the label value of bk-repo scope gateway -*/}} -{{- define "bkrepo.labelValues.scope.gateway" -}} - {{- printf "gateway" -}} -{{- end -}} - -{{/* -Return the proper image name -{{ include "bkrepo.images.image" ( dict "imageRoot" .Values.path.to.the.image "global" $) }} -*/}} -{{- define "bkrepo.images.image" -}} -{{- $registryName := .imageRoot.registry -}} -{{- $repositoryName := .imageRoot.repository -}} -{{- $tag := .imageRoot.tag | toString -}} -{{- if .global }} - {{- if .global.imageRegistry }} - {{- $registryName = .global.imageRegistry -}} - {{- end -}} -{{- end -}} -{{- if .bkrepo.imageRegistry }} - {{- $registryName = .bkrepo.imageRegistry -}} -{{- end -}} -{{- if .bkrepo.imageTag }} - {{- $tag = .bkrepo.imageTag -}} -{{- end -}} -{{- if $registryName }} -{{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} -{{- else -}} -{{- printf "%s:%s" $repositoryName $tag -}} -{{- end -}} -{{- end -}} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/auth/configmap.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/auth/configmap.yaml deleted file mode 100644 index 3a110319f82..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/auth/configmap.yaml +++ /dev/null @@ -1,18 +0,0 @@ -kind: ConfigMap -apiVersion: v1 -metadata: - name: {{ include "common.names.fullname" . }}-auth - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: auth - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -data: - application.yml: |- - auth: - {{- if keys $.Values.auth.config }} - {{- toYaml .Values.auth.config | nindent 6 }} - {{- end}} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/auth/deployment.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/auth/deployment.yaml deleted file mode 100644 index 6fe32eb3717..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/auth/deployment.yaml +++ /dev/null @@ -1,107 +0,0 @@ -apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }} -kind: Deployment -metadata: - name: {{ include "common.names.fullname" . }}-auth - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: auth - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -spec: - selector: - matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} - app.kubernetes.io/component: auth - replicas: {{ default 1 .Values.auth.replicaCount }} - template: - metadata: - labels: {{- include "common.labels.standard" . | nindent 8 }} - app.kubernetes.io/component: auth - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - {{- if .Values.auth.podLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.auth.podLabels "context" $) | nindent 8 }} - {{- end }} - spec: - serviceAccountName: {{ template "bkrepo.serviceAccountName" . }} - {{- include "bkrepo.imagePullSecrets" . | nindent 6 }} - {{- if .Values.auth.hostAliases }} - hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.auth.hostAliases "context" $) | nindent 8 }} - {{- end }} - {{- if .Values.auth.affinity }} - affinity: {{- include "common.tplvalues.render" ( dict "value" .Values.auth.affinity "context" $) | nindent 8 }} - {{- else }} - affinity: - podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.auth.podAffinityPreset "component" "auth" "context" $) | nindent 10 }} - podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.auth.podAntiAffinityPreset "component" "auth" "context" $) | nindent 10 }} - nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.auth.nodeAffinityPreset.type "key" .Values.auth.nodeAffinityPreset.key "values" .Values.auth.nodeAffinityPreset.values) | nindent 10 }} - {{- end }} - {{- if .Values.auth.nodeSelector }} - nodeSelector: {{- include "common.tplvalues.render" ( dict "value" .Values.auth.nodeSelector "context" $) | nindent 8 }} - {{- end }} - {{- if .Values.auth.tolerations }} - tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.auth.tolerations "context" .) | nindent 8 }} - {{- end }} - {{- if .Values.auth.priorityClassName }} - priorityClassName: {{ .Values.auth.priorityClassName | quote }} - {{- end }} - {{- if .Values.auth.podSecurityContext.enabled }} - securityContext: {{- omit .Values.auth.podSecurityContext "enabled" | toYaml | nindent 8 }} - {{- end }} - {{- if .Values.mongodb.enabled }} - initContainers: - - name: wait-for-mongodb - image: {{ include "bkrepo.images.image" ( dict "imageRoot" .Values.init.mongodb.image "global" .Values.global "bkrepo" .Values.common) }} - imagePullPolicy: {{ .Values.init.mongodb.image.pullPolicy }} - command: - - "/bin/sh" - - "-c" - - | - until getent hosts {{ include "bkrepo.mongodb.fullname" . }} - do - echo waiting for {{ include "bkrepo.mongodb.fullname" . }}; - sleep 2; - done - echo "Mongodb is available"; - {{- end }} - containers: - - name: auth - image: {{ include "bkrepo.images.image" ( dict "imageRoot" .Values.auth.image "global" .Values.global "bkrepo" .Values.common) }} - imagePullPolicy: {{ .Values.auth.image.pullPolicy }} - {{- if .Values.auth.containerSecurityContext.enabled }} - securityContext: {{- omit .Values.auth.containerSecurityContext "enabled" | toYaml | nindent 12 }} - {{- end }} - {{- if .Values.auth.resources }} - resources: {{- toYaml .Values.auth.resources | nindent 12 }} - {{- end }} - env: - - name: BK_REPO_JVM_OPTION - value: {{ .Values.common.jvmOption }} - - name: BK_REPO_PROFILE - value: {{ .Values.common.springProfile }} - - name: BK_REPO_SERVICE_PREFIX - value: {{ include "common.names.fullname" . }}- - ports: - - name: http - containerPort: 25902 - protocol: TCP - livenessProbe: - httpGet: - path: /actuator/health/livenessState - port: http - initialDelaySeconds: 120 - periodSeconds: 15 - timeoutSeconds: 10 - failureThreshold: 5 - successThreshold: 1 - readinessProbe: - httpGet: - path: /actuator/health/readinessState - port: http - initialDelaySeconds: 60 - periodSeconds: 15 - timeoutSeconds: 10 - failureThreshold: 5 - successThreshold: 1 diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/auth/service.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/auth/service.yaml deleted file mode 100644 index 85e00082996..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/auth/service.yaml +++ /dev/null @@ -1,22 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ include "common.names.fullname" . }}-auth - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: auth - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -spec: - type: ClusterIP - ports: - - name: http - port: 80 - targetPort: http - protocol: TCP - selector: {{- include "common.labels.matchLabels" . | nindent 4 }} - app.kubernetes.io/component: auth diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/bklog.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/bklog.yaml deleted file mode 100644 index 2d6cdcf1553..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/bklog.yaml +++ /dev/null @@ -1,58 +0,0 @@ -{{- if .Values.bkLogConfig.enabled }} - -# service log -apiVersion: bk.tencent.com/v1alpha1 -kind: BkLogConfig -metadata: - name: bk-repo-service-log-config -spec: - dataId: {{ .Values.bkLogConfig.service.dataId }} - logConfigType: container_log_config - namespace: {{ .Release.Namespace }} - labelSelector: - matchLabels: {{- include "common.labels.standard" . | nindent 6 }} - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - path: - - /data/workspace/logs/*.log - encoding: 'utf-8' - extMeta: - logSourceType: "service" - ---- -# gateway access log -apiVersion: bk.tencent.com/v1alpha1 -kind: BkLogConfig -metadata: - name: bk-repo-gateway-acsess-log-config -spec: - dataId: {{ .Values.bkLogConfig.gatewayAccess.dataId }} - logConfigType: container_log_config - namespace: {{ .Release.Namespace }} - labelSelector: - matchLabels: {{- include "common.labels.standard" . | nindent 6 }} - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.gateway" . }} - path: - - /data/workspace/logs/nginx/bkrepo.access.*.log - extMeta: - logSourceType: "gateway-access" - ---- -# gateway error log -apiVersion: bk.tencent.com/v1alpha1 -kind: BkLogConfig -metadata: - name: bk-repo-gateway-error-log-config -spec: - dataId: {{ .Values.bkLogConfig.gatewayError.dataId }} - - logConfigType: container_log_config - namespace: {{ .Release.Namespace }} - labelSelector: - matchLabels: {{- include "common.labels.standard" . | nindent 6 }} - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.gateway" . }} - path: - - /data/workspace/logs/nginx/*.error.log - extMeta: - logSourceType: "gateway-error" - -{{- end }} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/bkmonitor.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/bkmonitor.yaml deleted file mode 100644 index c0b72ef79d4..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/bkmonitor.yaml +++ /dev/null @@ -1,34 +0,0 @@ -{{- if .Values.serviceMonitor.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: bk-repo -spec: - endpoints: - - basicAuth: - password: - name: bkrepo-basic-auth - key: password - username: - name: bkrepo-basic-auth - key: user - interval: 30s # 采集周期 - path: /actuator/prometheus # 指标接口路径 - port: http # service的端口名,必须使用端口名,不能使用数字 - namespaceSelector: - any: true - selector: # 过滤出需要采集的service - matchLabels: {{- include "common.labels.standard" . | nindent 6 }} - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - ---- -apiVersion: v1 -kind: Secret -metadata: - name: bkrepo-basic-auth -data: - password: {{ .Values.common.password | b64enc }} - user: {{ .Values.common.username | b64enc }} -type: Opaque - -{{- end }} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/configmap-common.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/configmap-common.yaml deleted file mode 100644 index d2beaffc1c6..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/configmap-common.yaml +++ /dev/null @@ -1,29 +0,0 @@ -kind: ConfigMap -apiVersion: v1 -metadata: - name: {{ include "common.names.fullname" . }}-common - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: repository - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -data: - application.yml: |- - logging: - config: classpath:logback-config.xml - path: /data/workspace/logs - spring: - data: - mongodb: - uri: {{ include "bkrepo.mongodbUri" . }} - transaction: - enabled: false - service.prefix: {{ include "common.names.fullname" . }}- - cluster: - region: {{ .Values.common.region }} - self: - url: {{ .Values.gateway.host }} - {{- toYaml .Values.common.config | nindent 4 }} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/docker/configmap.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/docker/configmap.yaml deleted file mode 100644 index 7aad592b7ba..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/docker/configmap.yaml +++ /dev/null @@ -1,32 +0,0 @@ -{{- if .Values.docker.enabled -}} -kind: ConfigMap -apiVersion: v1 -metadata: - name: {{ include "common.names.fullname" . }}-docker - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: docker - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -data: - application.yml: |- - docker: - domain: {{ .Values.gateway.dockerHost }} - {{- if .Values.ingress.tls }} - http: false - {{- else }} - http: true - {{- end }} - auth: - {{- if .Values.ingress.tls }} - url: https://{{ .Values.gateway.host }}/docker/v2/auth - {{- else }} - url: http://{{ .Values.gateway.host }}/docker/v2/auth - {{- end }} - {{- if keys $.Values.docker.config }} - {{- toYaml .Values.docker.config | nindent 6 }} - {{- end}} -{{- end }} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/docker/deployment.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/docker/deployment.yaml deleted file mode 100644 index 8d9c96d2a18..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/docker/deployment.yaml +++ /dev/null @@ -1,112 +0,0 @@ -{{- if .Values.docker.enabled -}} -apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }} -kind: Deployment -metadata: - name: {{ include "common.names.fullname" . }}-docker - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: docker - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -spec: - selector: - matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} - app.kubernetes.io/component: docker - replicas: {{ default 1 .Values.docker.replicaCount }} - template: - metadata: - labels: {{- include "common.labels.standard" . | nindent 8 }} - app.kubernetes.io/component: docker - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - {{- if .Values.docker.podLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.docker.podLabels "context" $) | nindent 8 }} - {{- end }} - spec: - serviceAccountName: {{ template "bkrepo.serviceAccountName" . }} - {{- include "bkrepo.imagePullSecrets" . | nindent 6 }} - {{- if .Values.docker.hostAliases }} - hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.docker.hostAliases "context" $) | nindent 8 }} - {{- end }} - {{- if .Values.docker.affinity }} - affinity: {{- include "common.tplvalues.render" ( dict "value" .Values.docker.affinity "context" $) | nindent 8 }} - {{- else }} - affinity: - {{- if eq .Values.persistence.accessMode "ReadWriteOnce" }} - podAffinity: {{- include "common.affinities.pods" (dict "type" "hard" "component" "repository" "context" $) | nindent 10 }} - {{- else }} - podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.repository.podAffinityPreset "component" "docker" "context" $) | nindent 10 }} - {{- end }} - podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.docker.podAntiAffinityPreset "component" "docker" "context" $) | nindent 10 }} - nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.docker.nodeAffinityPreset.type "key" .Values.docker.nodeAffinityPreset.key "values" .Values.docker.nodeAffinityPreset.values) | nindent 10 }} - {{- end }} - {{- if .Values.docker.nodeSelector }} - nodeSelector: {{- include "common.tplvalues.render" ( dict "value" .Values.docker.nodeSelector "context" $) | nindent 8 }} - {{- end }} - {{- if .Values.docker.tolerations }} - tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.docker.tolerations "context" .) | nindent 8 }} - {{- end }} - {{- if .Values.docker.priorityClassName }} - priorityClassName: {{ .Values.docker.priorityClassName | quote }} - {{- end }} - {{- if .Values.docker.podSecurityContext.enabled }} - securityContext: {{- omit .Values.docker.podSecurityContext "enabled" | toYaml | nindent 8 }} - {{- end }} - containers: - - name: docker - image: {{ include "bkrepo.images.image" ( dict "imageRoot" .Values.docker.image "global" .Values.global "bkrepo" .Values.common) }} - imagePullPolicy: {{ .Values.docker.image.pullPolicy }} - {{- if .Values.docker.containerSecurityContext.enabled }} - securityContext: {{- omit .Values.docker.containerSecurityContext "enabled" | toYaml | nindent 12 }} - {{- end }} - {{- if .Values.docker.resources }} - resources: {{- toYaml .Values.docker.resources | nindent 12 }} - {{- end }} - env: - - name: BK_REPO_JVM_OPTION - value: {{ .Values.common.jvmOption }} - - name: BK_REPO_PROFILE - value: {{ .Values.common.springProfile }} - - name: BK_REPO_SERVICE_PREFIX - value: {{ include "common.names.fullname" . }}- - ports: - - name: http - containerPort: 25802 - protocol: TCP - livenessProbe: - httpGet: - path: /actuator/health/livenessState - port: http - initialDelaySeconds: 120 - periodSeconds: 15 - timeoutSeconds: 10 - failureThreshold: 5 - successThreshold: 1 - readinessProbe: - httpGet: - path: /actuator/health/readinessState - port: http - initialDelaySeconds: 60 - periodSeconds: 15 - timeoutSeconds: 10 - failureThreshold: 5 - successThreshold: 1 - volumeMounts: - - name: storage - mountPath: {{ .Values.common.mountPath }} - volumes: - - name: storage - {{- if .Values.common.config.storage.nfs.enabled }} - nfs: - path: {{ .Values.common.config.storage.nfs.path }} - server: {{ .Values.common.config.storage.nfs.server }} - {{- else if .Values.persistence.enabled }} - persistentVolumeClaim: - claimName: {{ if .Values.persistence.existingClaim }}{{ .Values.persistence.existingClaim }}{{- else }}{{ template "common.names.fullname" . }}-storage{{- end }} - {{- else }} - emptyDir: {} - {{- end }} -{{- end }} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/docker/service.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/docker/service.yaml deleted file mode 100644 index fbdf888c1f3..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/docker/service.yaml +++ /dev/null @@ -1,24 +0,0 @@ -{{- if .Values.docker.enabled -}} -apiVersion: v1 -kind: Service -metadata: - name: {{ include "common.names.fullname" . }}-docker - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: docker - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -spec: - type: ClusterIP - ports: - - name: http - port: 80 - targetPort: http - protocol: TCP - selector: {{- include "common.labels.matchLabels" . | nindent 4 }} - app.kubernetes.io/component: docker -{{- end}} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/gateway/deployment.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/gateway/deployment.yaml deleted file mode 100644 index 7bb0357629a..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/gateway/deployment.yaml +++ /dev/null @@ -1,116 +0,0 @@ -apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }} -kind: Deployment -metadata: - name: {{ include "common.names.fullname" . }}-gateway - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: gateway - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.gateway" . }} - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -spec: - selector: - matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} - app.kubernetes.io/component: gateway - replicas: {{ default 1 .Values.gateway.replicaCount }} - template: - metadata: - labels: {{- include "common.labels.standard" . | nindent 8 }} - app.kubernetes.io/component: gateway - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.gateway" . }} - {{- if .Values.gateway.podLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.gateway.podLabels "context" $) | nindent 8 }} - {{- end }} - spec: - serviceAccountName: {{ template "bkrepo.serviceAccountName" . }} - {{- include "bkrepo.imagePullSecrets" . | nindent 6 }} - {{- if .Values.gateway.hostAliases }} - hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.gateway.hostAliases "context" $) | nindent 8 }} - {{- end }} - {{- if .Values.gateway.affinity }} - affinity: {{- include "common.tplvalues.render" ( dict "value" .Values.gateway.affinity "context" $) | nindent 8 }} - {{- else }} - affinity: - podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.gateway.podAffinityPreset "component" "gateway" "context" $) | nindent 10 }} - podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.gateway.podAntiAffinityPreset "component" "gateway" "context" $) | nindent 10 }} - nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.gateway.nodeAffinityPreset.type "key" .Values.gateway.nodeAffinityPreset.key "values" .Values.gateway.nodeAffinityPreset.values) | nindent 10 }} - {{- end }} - {{- if .Values.gateway.nodeSelector }} - nodeSelector: {{- include "common.tplvalues.render" ( dict "value" .Values.gateway.nodeSelector "context" $) | nindent 8 }} - {{- end }} - {{- if .Values.gateway.tolerations }} - tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.gateway.tolerations "context" .) | nindent 8 }} - {{- end }} - {{- if .Values.gateway.priorityClassName }} - priorityClassName: {{ .Values.gateway.priorityClassName | quote }} - {{- end }} - {{- if .Values.gateway.podSecurityContext.enabled }} - securityContext: {{- omit .Values.gateway.podSecurityContext "enabled" | toYaml | nindent 8 }} - {{- end }} - containers: - - name: gateway - image: {{ include "bkrepo.images.image" ( dict "imageRoot" .Values.gateway.image "global" .Values.global "bkrepo" .Values.common) }} - imagePullPolicy: {{ .Values.gateway.image.pullPolicy }} - {{- if .Values.gateway.containerSecurityContext.enabled }} - securityContext: {{- omit .Values.gateway.containerSecurityContext "enabled" | toYaml | nindent 12 }} - {{- end }} - {{- if .Values.gateway.resources }} - resources: {{- toYaml .Values.gateway.resources | nindent 12 }} - {{- end }} - env: - - name: NAMESPACE - value: {{ .Release.Namespace }} - - name: BK_REPO_SERVICE_PREFIX - value: {{ include "common.names.fullname" . }}- - - name: BK_REPO_HOST - value: {{ .Values.gateway.host }} - - name: BK_REPO_HTTP_PORT - value: "80" - - name: BK_REPO_GATEWAY_DNS_ADDR - value: {{ .Values.gateway.dnsServer }} - - name: BK_REPO_AUTHORIZATION - value: {{ .Values.gateway.authorization }} - - name: BK_REPO_DEPLOY_MODE - value: {{ .Values.gateway.deployMode }} - - name: BK_REPO_DOCKER_HTTP_PORT - value: "80" - - name: BK_REPO_DOCKER_HOST - value: {{ .Values.gateway.dockerHost }} - - name: BK_REPO_HELM_HTTP_PORT - value: "80" - - name: BK_REPO_HELM_HOST - value: {{ .Values.gateway.helmHost }} - ports: - - name: http - containerPort: 80 - protocol: TCP - - name: gateway - containerPort: 8081 - protocol: TCP - livenessProbe: - httpGet: - path: /ui/ - port: http - httpHeaders: - - name: Host - value: {{ .Values.gateway.host }} - initialDelaySeconds: 60 - periodSeconds: 15 - timeoutSeconds: 10 - failureThreshold: 5 - successThreshold: 1 - readinessProbe: - httpGet: - path: /ui/ - port: http - httpHeaders: - - name: Host - value: {{ .Values.gateway.host }} - initialDelaySeconds: 30 - periodSeconds: 15 - timeoutSeconds: 10 - failureThreshold: 5 - successThreshold: 1 diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/gateway/service.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/gateway/service.yaml deleted file mode 100644 index 7b71e71f9e7..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/gateway/service.yaml +++ /dev/null @@ -1,33 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ include "common.names.fullname" . }}-gateway - labels: {{- include "common.labels.standard" . | nindent 4 }} - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - annotations: - {{- if .Values.commonAnnotations }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -spec: - selector: {{- include "common.labels.matchLabels" . | nindent 4 }} - app.kubernetes.io/component: gateway - type: {{ .Values.gateway.service.type }} - {{- if eq .Values.gateway.service.type "LoadBalancer" }} - {{- if .Values.gateway.service.loadBalancerIP }} - loadBalancerIP: {{ default "" .Values.gateway.service.loadBalancerIP | quote }} - {{- end }} - {{- end }} - ports: - - name: http - port: {{ .Values.gateway.service.port }} - targetPort: 80 - - name: node - port: 8081 - {{- if and .Values.gateway.service.nodePort (or (eq .Values.gateway.service.type "NodePort") (eq .Values.gateway.service.type "LoadBalancer")) }} - nodePort: {{ .Values.gateway.service.nodePort }} - {{- else }} - nodePort: null - {{- end }} - targetPort: 8081 diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/generic/configmap.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/generic/configmap.yaml deleted file mode 100644 index 61d014bd909..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/generic/configmap.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{- if .Values.generic.enabled -}} -kind: ConfigMap -apiVersion: v1 -metadata: - name: {{ include "common.names.fullname" . }}-generic - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: generic - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -data: - application.yml: |- - generic: - domain: {{ .Values.gateway.host }}/generic - {{- if keys $.Values.generic.config }} - {{- toYaml .Values.generic.config | nindent 6 }} - {{- end}} -{{- end }} \ No newline at end of file diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/generic/deployment.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/generic/deployment.yaml deleted file mode 100644 index 0031cff9f9b..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/generic/deployment.yaml +++ /dev/null @@ -1,112 +0,0 @@ -{{- if .Values.generic.enabled -}} -apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }} -kind: Deployment -metadata: - name: {{ include "common.names.fullname" . }}-generic - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: generic - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -spec: - selector: - matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} - app.kubernetes.io/component: generic - replicas: {{ default 1 .Values.generic.replicaCount }} - template: - metadata: - labels: {{- include "common.labels.standard" . | nindent 8 }} - app.kubernetes.io/component: generic - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - {{- if .Values.generic.podLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.generic.podLabels "context" $) | nindent 8 }} - {{- end }} - spec: - serviceAccountName: {{ template "bkrepo.serviceAccountName" . }} - {{- include "bkrepo.imagePullSecrets" . | nindent 6 }} - {{- if .Values.generic.hostAliases }} - hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.generic.hostAliases "context" $) | nindent 8 }} - {{- end }} - {{- if .Values.generic.affinity }} - affinity: {{- include "common.tplvalues.render" ( dict "value" .Values.generic.affinity "context" $) | nindent 8 }} - {{- else }} - affinity: - {{- if eq .Values.persistence.accessMode "ReadWriteOnce" }} - podAffinity: {{- include "common.affinities.pods" (dict "type" "hard" "component" "repository" "context" $) | nindent 10 }} - {{- else }} - podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.repository.podAffinityPreset "component" "generic" "context" $) | nindent 10 }} - {{- end }} - podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.generic.podAntiAffinityPreset "component" "generic" "context" $) | nindent 10 }} - nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.generic.nodeAffinityPreset.type "key" .Values.generic.nodeAffinityPreset.key "values" .Values.generic.nodeAffinityPreset.values) | nindent 10 }} - {{- end }} - {{- if .Values.generic.nodeSelector }} - nodeSelector: {{- include "common.tplvalues.render" ( dict "value" .Values.generic.nodeSelector "context" $) | nindent 8 }} - {{- end }} - {{- if .Values.generic.tolerations }} - tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.generic.tolerations "context" .) | nindent 8 }} - {{- end }} - {{- if .Values.generic.priorityClassName }} - priorityClassName: {{ .Values.generic.priorityClassName | quote }} - {{- end }} - {{- if .Values.generic.podSecurityContext.enabled }} - securityContext: {{- omit .Values.generic.podSecurityContext "enabled" | toYaml | nindent 8 }} - {{- end }} - containers: - - name: generic - image: {{ include "bkrepo.images.image" ( dict "imageRoot" .Values.generic.image "global" .Values.global "bkrepo" .Values.common) }} - imagePullPolicy: {{ .Values.generic.image.pullPolicy }} - {{- if .Values.generic.containerSecurityContext.enabled }} - securityContext: {{- omit .Values.generic.containerSecurityContext "enabled" | toYaml | nindent 12 }} - {{- end }} - {{- if .Values.generic.resources }} - resources: {{- toYaml .Values.generic.resources | nindent 12 }} - {{- end }} - env: - - name: BK_REPO_JVM_OPTION - value: {{ .Values.common.jvmOption }} - - name: BK_REPO_PROFILE - value: {{ .Values.common.springProfile }} - - name: BK_REPO_SERVICE_PREFIX - value: {{ include "common.names.fullname" . }}- - ports: - - name: http - containerPort: 25801 - protocol: TCP - livenessProbe: - httpGet: - path: /actuator/health/livenessState - port: http - initialDelaySeconds: 120 - periodSeconds: 15 - timeoutSeconds: 10 - failureThreshold: 5 - successThreshold: 1 - readinessProbe: - httpGet: - path: /actuator/health/readinessState - port: http - initialDelaySeconds: 60 - periodSeconds: 15 - timeoutSeconds: 10 - failureThreshold: 5 - successThreshold: 1 - volumeMounts: - - name: storage - mountPath: {{ .Values.common.mountPath }} - volumes: - - name: storage - {{- if .Values.common.config.storage.nfs.enabled }} - nfs: - path: {{ .Values.common.config.storage.nfs.path }} - server: {{ .Values.common.config.storage.nfs.server }} - {{- else if .Values.persistence.enabled }} - persistentVolumeClaim: - claimName: {{ if .Values.persistence.existingClaim }}{{ .Values.persistence.existingClaim }}{{- else }}{{ template "common.names.fullname" . }}-storage{{- end }} - {{- else }} - emptyDir: {} - {{- end }} -{{- end }} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/generic/service.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/generic/service.yaml deleted file mode 100644 index 13094a683df..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/generic/service.yaml +++ /dev/null @@ -1,24 +0,0 @@ -{{- if .Values.generic.enabled -}} -apiVersion: v1 -kind: Service -metadata: - name: {{ include "common.names.fullname" . }}-generic - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: generic - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -spec: - type: ClusterIP - ports: - - name: http - port: 80 - targetPort: http - protocol: TCP - selector: {{- include "common.labels.matchLabels" . | nindent 4 }} - app.kubernetes.io/component: generic -{{- end }} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/helm/configmap.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/helm/configmap.yaml deleted file mode 100644 index 1a6808a2b36..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/helm/configmap.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{- if .Values.helm.enabled -}} -kind: ConfigMap -apiVersion: v1 -metadata: - name: {{ include "common.names.fullname" . }}-helm - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: helm - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -data: - application.yml: |- - helm: - domain: helm.{{ .Values.gateway.host }} - {{- if keys $.Values.helm.config }} - {{- toYaml .Values.helm.config | nindent 6 }} - {{- end}} -{{- end }} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/helm/deployment.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/helm/deployment.yaml deleted file mode 100644 index 2b6367bb5d8..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/helm/deployment.yaml +++ /dev/null @@ -1,112 +0,0 @@ -{{- if .Values.helm.enabled -}} -apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }} -kind: Deployment -metadata: - name: {{ include "common.names.fullname" . }}-helm - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: helm - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -spec: - selector: - matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} - app.kubernetes.io/component: helm - replicas: {{ default 1 .Values.helm.replicaCount }} - template: - metadata: - labels: {{- include "common.labels.standard" . | nindent 8 }} - app.kubernetes.io/component: helm - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - {{- if .Values.helm.podLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.helm.podLabels "context" $) | nindent 8 }} - {{- end }} - spec: - serviceAccountName: {{ template "bkrepo.serviceAccountName" . }} - {{- include "bkrepo.imagePullSecrets" . | nindent 6 }} - {{- if .Values.helm.hostAliases }} - hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.helm.hostAliases "context" $) | nindent 8 }} - {{- end }} - {{- if .Values.helm.affinity }} - affinity: {{- include "common.tplvalues.render" ( dict "value" .Values.helm.affinity "context" $) | nindent 8 }} - {{- else }} - affinity: - {{- if eq .Values.persistence.accessMode "ReadWriteOnce" }} - podAffinity: {{- include "common.affinities.pods" (dict "type" "hard" "component" "repository" "context" $) | nindent 10 }} - {{- else }} - podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.repository.podAffinityPreset "component" "helm" "context" $) | nindent 10 }} - {{- end }} - podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.helm.podAntiAffinityPreset "component" "helm" "context" $) | nindent 10 }} - nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.helm.nodeAffinityPreset.type "key" .Values.helm.nodeAffinityPreset.key "values" .Values.helm.nodeAffinityPreset.values) | nindent 10 }} - {{- end }} - {{- if .Values.helm.nodeSelector }} - nodeSelector: {{- include "common.tplvalues.render" ( dict "value" .Values.helm.nodeSelector "context" $) | nindent 8 }} - {{- end }} - {{- if .Values.helm.tolerations }} - tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.helm.tolerations "context" .) | nindent 8 }} - {{- end }} - {{- if .Values.helm.priorityClassName }} - priorityClassName: {{ .Values.helm.priorityClassName | quote }} - {{- end }} - {{- if .Values.helm.podSecurityContext.enabled }} - securityContext: {{- omit .Values.helm.podSecurityContext "enabled" | toYaml | nindent 8 }} - {{- end }} - containers: - - name: helm - image: {{ include "bkrepo.images.image" ( dict "imageRoot" .Values.helm.image "global" .Values.global "bkrepo" .Values.common) }} - imagePullPolicy: {{ .Values.helm.image.pullPolicy }} - {{- if .Values.helm.containerSecurityContext.enabled }} - securityContext: {{- omit .Values.helm.containerSecurityContext "enabled" | toYaml | nindent 12 }} - {{- end }} - {{- if .Values.helm.resources }} - resources: {{- toYaml .Values.helm.resources | nindent 12 }} - {{- end }} - env: - - name: BK_REPO_JVM_OPTION - value: {{ .Values.common.jvmOption }} - - name: BK_REPO_PROFILE - value: {{ .Values.common.springProfile }} - - name: BK_REPO_SERVICE_PREFIX - value: {{ include "common.names.fullname" . }}- - ports: - - name: http - containerPort: 25806 - protocol: TCP - livenessProbe: - httpGet: - path: /actuator/health/livenessState - port: http - initialDelaySeconds: 120 - periodSeconds: 15 - timeoutSeconds: 10 - failureThreshold: 5 - successThreshold: 1 - readinessProbe: - httpGet: - path: /actuator/health/readinessState - port: http - initialDelaySeconds: 60 - periodSeconds: 15 - timeoutSeconds: 10 - failureThreshold: 5 - successThreshold: 1 - volumeMounts: - - name: storage - mountPath: {{ .Values.common.mountPath }} - volumes: - - name: storage - {{- if .Values.common.config.storage.nfs.enabled }} - nfs: - path: {{ .Values.common.config.storage.nfs.path }} - server: {{ .Values.common.config.storage.nfs.server }} - {{- else if .Values.persistence.enabled }} - persistentVolumeClaim: - claimName: {{ if .Values.persistence.existingClaim }}{{ .Values.persistence.existingClaim }}{{- else }}{{ template "common.names.fullname" . }}-storage{{- end }} - {{- else }} - emptyDir: {} - {{- end }} -{{- end }} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/helm/service.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/helm/service.yaml deleted file mode 100644 index b7b14499e94..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/helm/service.yaml +++ /dev/null @@ -1,24 +0,0 @@ -{{- if .Values.helm.enabled -}} -apiVersion: v1 -kind: Service -metadata: - name: {{ include "common.names.fullname" . }}-helm - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: helm - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -spec: - type: ClusterIP - ports: - - name: http - port: 80 - targetPort: http - protocol: TCP - selector: {{- include "common.labels.matchLabels" . | nindent 4 }} - app.kubernetes.io/component: helm -{{- end }} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/ingress.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/ingress.yaml deleted file mode 100644 index a9b9f6f3c55..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/ingress.yaml +++ /dev/null @@ -1,51 +0,0 @@ -{{- if .Values.ingress.enabled }} -apiVersion: {{ include "common.capabilities.ingress.apiVersion" . }} -kind: Ingress -metadata: - name: {{ include "common.names.fullname" . }}-ingress - labels: {{- include "common.labels.standard" . | nindent 4 }} - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - annotations: - {{- if .Values.commonAnnotations }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} - {{- range $key, $value := .Values.ingress.annotations }} - {{ $key }}: {{ include "common.tplvalues.render" (dict "value" $value "context" $) | quote }} - {{- end }} -spec: - {{- if .Values.ingress.tls }} - tls: - - hosts: - - {{ .Values.gateway.host }} - - {{ .Values.gateway.dockerHost }} - - {{ .Values.gateway.helmHost }} - secretName: bkrepo-tls - {{- end }} - rules: - - host: {{ .Values.gateway.dockerHost }} - http: - paths: - - path: / - {{- if eq "true" (include "common.ingress.supportsPathType" .) }} - pathType: Prefix - {{- end }} - backend: {{- include "common.ingress.backend" (dict "serviceName" (printf "%s-gateway" (include "common.names.fullname" .)) "servicePort" 80 "context" $) | nindent 14 }} - - host: {{ .Values.gateway.helmHost }} - http: - paths: - - path: / - {{- if eq "true" (include "common.ingress.supportsPathType" .) }} - pathType: Prefix - {{- end }} - backend: {{- include "common.ingress.backend" (dict "serviceName" (printf "%s-gateway" (include "common.names.fullname" .)) "servicePort" 80 "context" $) | nindent 14 }} - - host: {{ .Values.gateway.host }} - http: - paths: - - path: / - {{- if eq "true" (include "common.ingress.supportsPathType" .) }} - pathType: Prefix - {{- end }} - backend: {{- include "common.ingress.backend" (dict "serviceName" (printf "%s-gateway" (include "common.names.fullname" .)) "servicePort" 80 "context" $) | nindent 14 }} -{{- end }} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/job/init-mongodb.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/job/init-mongodb.yaml deleted file mode 100644 index 593cd85e579..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/job/init-mongodb.yaml +++ /dev/null @@ -1,53 +0,0 @@ -{{- if .Values.init.mongodb.enabled -}} -apiVersion: batch/v1 -kind: Job -metadata: - name: {{ include "common.names.fullname" . }}-init-mongodb - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: init-mongodb - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - annotations: - "helm.sh/hook": post-install,post-upgrade - "helm.sh/hook-weight": "-5" - "helm.sh/hook-delete-policy": before-hook-creation - {{- if .Values.commonAnnotations }} - {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} - {{- end }} -spec: - template: - metadata: - labels: {{- include "common.labels.standard" . | nindent 8 }} - app.kubernetes.io/component: init-mongodb - spec: - {{- if .Values.mongodb.enabled }} - initContainers: - - name: wait-for-mongodb - image: {{ include "bkrepo.images.image" ( dict "imageRoot" .Values.init.mongodb.image "global" .Values.global "bkrepo" .Values.common) }} - imagePullPolicy: {{ .Values.init.mongodb.image.pullPolicy }} - command: - - "/bin/sh" - - "-c" - - | - until getent hosts {{ include "bkrepo.mongodb.fullname" . }} - do - echo waiting for {{ include "bkrepo.mongodb.fullname" . }}; - sleep 2; - done - echo "Mongodb is available"; - {{- end }} - containers: - - name: init-mongodb - image: {{ include "bkrepo.images.image" ( dict "imageRoot" .Values.init.mongodb.image "global" .Values.global "bkrepo" .Values.common) }} - imagePullPolicy: {{ .Values.init.mongodb.image.pullPolicy }} - command: ['/bin/sh','-c','/data/workspace/init-mongodb.sh'] - env: - - name: BK_REPO_USERNAME - value: {{ .Values.common.username }} - - name: BK_REPO_PASSWORD - value: {{ .Values.common.password }} - - name: BK_REPO_MONGODB_URI - value: {{ include "bkrepo.mongodbUri" . }} - restartPolicy: OnFailure -{{- end }} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/npm/configmap.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/npm/configmap.yaml deleted file mode 100644 index a6cbab591c7..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/npm/configmap.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{- if .Values.npm.enabled -}} -kind: ConfigMap -apiVersion: v1 -metadata: - name: {{ include "common.names.fullname" . }}-npm - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: npm - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -data: - application.yml: |- - npm: - domain: {{ .Values.gateway.host }}/npm - {{- if keys $.Values.npm.config }} - {{- toYaml .Values.npm.config | nindent 6 }} - {{- end}} -{{- end }} \ No newline at end of file diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/npm/deployment.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/npm/deployment.yaml deleted file mode 100644 index 07b7fcafc8c..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/npm/deployment.yaml +++ /dev/null @@ -1,112 +0,0 @@ -{{- if .Values.npm.enabled -}} -apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }} -kind: Deployment -metadata: - name: {{ include "common.names.fullname" . }}-npm - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: npm - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -spec: - selector: - matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} - app.kubernetes.io/component: npm - replicas: {{ default 1 .Values.npm.replicaCount }} - template: - metadata: - labels: {{- include "common.labels.standard" . | nindent 8 }} - app.kubernetes.io/component: npm - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - {{- if .Values.npm.podLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.npm.podLabels "context" $) | nindent 8 }} - {{- end }} - spec: - serviceAccountName: {{ template "bkrepo.serviceAccountName" . }} - {{- include "bkrepo.imagePullSecrets" . | nindent 6 }} - {{- if .Values.npm.hostAliases }} - hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.npm.hostAliases "context" $) | nindent 8 }} - {{- end }} - {{- if .Values.npm.affinity }} - affinity: {{- include "common.tplvalues.render" ( dict "value" .Values.npm.affinity "context" $) | nindent 8 }} - {{- else }} - affinity: - {{- if eq .Values.persistence.accessMode "ReadWriteOnce" }} - podAffinity: {{- include "common.affinities.pods" (dict "type" "hard" "component" "repository" "context" $) | nindent 10 }} - {{- else }} - podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.repository.podAffinityPreset "component" "npm" "context" $) | nindent 10 }} - {{- end }} - podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.npm.podAntiAffinityPreset "component" "npm" "context" $) | nindent 10 }} - nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.npm.nodeAffinityPreset.type "key" .Values.npm.nodeAffinityPreset.key "values" .Values.npm.nodeAffinityPreset.values) | nindent 10 }} - {{- end }} - {{- if .Values.npm.nodeSelector }} - nodeSelector: {{- include "common.tplvalues.render" ( dict "value" .Values.npm.nodeSelector "context" $) | nindent 8 }} - {{- end }} - {{- if .Values.npm.tolerations }} - tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.npm.tolerations "context" .) | nindent 8 }} - {{- end }} - {{- if .Values.npm.priorityClassName }} - priorityClassName: {{ .Values.npm.priorityClassName | quote }} - {{- end }} - {{- if .Values.npm.podSecurityContext.enabled }} - securityContext: {{- omit .Values.npm.podSecurityContext "enabled" | toYaml | nindent 8 }} - {{- end }} - containers: - - name: npm - image: {{ include "bkrepo.images.image" ( dict "imageRoot" .Values.npm.image "global" .Values.global "bkrepo" .Values.common) }} - imagePullPolicy: {{ .Values.npm.image.pullPolicy }} - {{- if .Values.npm.containerSecurityContext.enabled }} - securityContext: {{- omit .Values.npm.containerSecurityContext "enabled" | toYaml | nindent 12 }} - {{- end }} - {{- if .Values.npm.resources }} - resources: {{- toYaml .Values.npm.resources | nindent 12 }} - {{- end }} - env: - - name: BK_REPO_JVM_OPTION - value: {{ .Values.common.jvmOption }} - - name: BK_REPO_PROFILE - value: {{ .Values.common.springProfile }} - - name: BK_REPO_SERVICE_PREFIX - value: {{ include "common.names.fullname" . }}- - ports: - - name: http - containerPort: 25804 - protocol: TCP - livenessProbe: - httpGet: - path: /actuator/health/livenessState - port: http - initialDelaySeconds: 120 - periodSeconds: 15 - timeoutSeconds: 10 - failureThreshold: 5 - successThreshold: 1 - readinessProbe: - httpGet: - path: /actuator/health/readinessState - port: http - initialDelaySeconds: 60 - periodSeconds: 15 - timeoutSeconds: 10 - failureThreshold: 5 - successThreshold: 1 - volumeMounts: - - name: storage - mountPath: {{ .Values.common.mountPath }} - volumes: - - name: storage - {{- if .Values.common.config.storage.nfs.enabled }} - nfs: - path: {{ .Values.common.config.storage.nfs.path }} - server: {{ .Values.common.config.storage.nfs.server }} - {{- else if .Values.persistence.enabled }} - persistentVolumeClaim: - claimName: {{ if .Values.persistence.existingClaim }}{{ .Values.persistence.existingClaim }}{{- else }}{{ template "common.names.fullname" . }}-storage{{- end }} - {{- else }} - emptyDir: {} - {{- end }} -{{- end }} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/npm/service.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/npm/service.yaml deleted file mode 100644 index bdf9b33791b..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/npm/service.yaml +++ /dev/null @@ -1,24 +0,0 @@ -{{- if .Values.npm.enabled -}} -apiVersion: v1 -kind: Service -metadata: - name: {{ include "common.names.fullname" . }}-npm - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: npm - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -spec: - type: ClusterIP - ports: - - name: http - port: 80 - targetPort: http - protocol: TCP - selector: {{- include "common.labels.matchLabels" . | nindent 4 }} - app.kubernetes.io/component: npm -{{- end }} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/opdata/configmap.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/opdata/configmap.yaml deleted file mode 100644 index c8f2b5d087b..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/opdata/configmap.yaml +++ /dev/null @@ -1,23 +0,0 @@ -{{- if .Values.opdata.enabled -}} -kind: ConfigMap -apiVersion: v1 -metadata: - name: {{ include "common.names.fullname" . }}-opdata - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: opdata - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -data: - application.yml: |- - # 应用版本 - spring: - application: - version: 1.0.0 - {{- if keys $.Values.opdata.config }} - {{- toYaml .Values.opdata.config | nindent 6 }} - {{- end}} - {{- end }} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/opdata/deployment.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/opdata/deployment.yaml deleted file mode 100644 index 0d2a40fe0da..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/opdata/deployment.yaml +++ /dev/null @@ -1,112 +0,0 @@ -{{- if .Values.opdata.enabled -}} -apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }} -kind: Deployment -metadata: - name: {{ include "common.names.fullname" . }}-opdata - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: opdata - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -spec: - selector: - matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} - app.kubernetes.io/component: opdata - replicas: {{ default 1 .Values.opdata.replicaCount }} - template: - metadata: - labels: {{- include "common.labels.standard" . | nindent 8 }} - app.kubernetes.io/component: opdata - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - {{- if .Values.opdata.podLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.opdata.podLabels "context" $) | nindent 8 }} - {{- end }} - spec: - serviceAccountName: {{ template "bkrepo.serviceAccountName" . }} - {{- include "bkrepo.imagePullSecrets" . | nindent 6 }} - {{- if .Values.opdata.hostAliases }} - hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.opdata.hostAliases "context" $) | nindent 8 }} - {{- end }} - {{- if .Values.opdata.affinity }} - affinity: {{- include "common.tplvalues.render" ( dict "value" .Values.opdata.affinity "context" $) | nindent 8 }} - {{- else }} - affinity: - {{- if eq .Values.persistence.accessMode "ReadWriteOnce" }} - podAffinity: {{- include "common.affinities.pods" (dict "type" "hard" "component" "repository" "context" $) | nindent 10 }} - {{- else }} - podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.repository.podAffinityPreset "component" "opdata" "context" $) | nindent 10 }} - {{- end }} - podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.opdata.podAntiAffinityPreset "component" "opdata" "context" $) | nindent 10 }} - nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.opdata.nodeAffinityPreset.type "key" .Values.opdata.nodeAffinityPreset.key "values" .Values.opdata.nodeAffinityPreset.values) | nindent 10 }} - {{- end }} - {{- if .Values.opdata.nodeSelector }} - nodeSelector: {{- include "common.tplvalues.render" ( dict "value" .Values.opdata.nodeSelector "context" $) | nindent 8 }} - {{- end }} - {{- if .Values.opdata.tolerations }} - tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.opdata.tolerations "context" .) | nindent 8 }} - {{- end }} - {{- if .Values.opdata.priorityClassName }} - priorityClassName: {{ .Values.opdata.priorityClassName | quote }} - {{- end }} - {{- if .Values.opdata.podSecurityContext.enabled }} - securityContext: {{- omit .Values.opdata.podSecurityContext "enabled" | toYaml | nindent 8 }} - {{- end }} - containers: - - name: opdata - image: {{ include "bkrepo.images.image" ( dict "imageRoot" .Values.opdata.image "global" .Values.global "bkrepo" .Values.common) }} - imagePullPolicy: {{ .Values.opdata.image.pullPolicy }} - {{- if .Values.opdata.containerSecurityContext.enabled }} - securityContext: {{- omit .Values.opdata.containerSecurityContext "enabled" | toYaml | nindent 12 }} - {{- end }} - {{- if .Values.opdata.resources }} - resources: {{- toYaml .Values.opdata.resources | nindent 12 }} - {{- end }} - env: - - name: BK_REPO_JVM_OPTION - value: {{ .Values.common.jvmOption }} - - name: BK_REPO_PROFILE - value: {{ .Values.common.springProfile }} - - name: BK_REPO_SERVICE_PREFIX - value: {{ include "common.names.fullname" . }}- - ports: - - name: http - containerPort: 25904 - protocol: TCP - livenessProbe: - httpGet: - path: /actuator/health/livenessState - port: http - initialDelaySeconds: 120 - periodSeconds: 15 - timeoutSeconds: 10 - failureThreshold: 5 - successThreshold: 1 - readinessProbe: - httpGet: - path: /actuator/health/readinessState - port: http - initialDelaySeconds: 60 - periodSeconds: 15 - timeoutSeconds: 10 - failureThreshold: 5 - successThreshold: 1 - volumeMounts: - - name: storage - mountPath: {{ .Values.common.mountPath }} - volumes: - - name: storage - {{- if .Values.common.config.storage.nfs.enabled }} - nfs: - path: {{ .Values.common.config.storage.nfs.path }} - server: {{ .Values.common.config.storage.nfs.server }} - {{- else if .Values.persistence.enabled }} - persistentVolumeClaim: - claimName: {{ if .Values.persistence.existingClaim }}{{ .Values.persistence.existingClaim }}{{- else }}{{ template "common.names.fullname" . }}-storage{{- end }} - {{- else }} - emptyDir: {} - {{- end }} -{{- end }} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/opdata/service.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/opdata/service.yaml deleted file mode 100644 index bc631da890f..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/opdata/service.yaml +++ /dev/null @@ -1,24 +0,0 @@ -{{- if .Values.opdata.enabled -}} -apiVersion: v1 -kind: Service -metadata: - name: {{ include "common.names.fullname" . }}-opdata - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: opdata - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -spec: - type: ClusterIP - ports: - - name: http - port: 80 - targetPort: http - protocol: TCP - selector: {{- include "common.labels.matchLabels" . | nindent 4 }} - app.kubernetes.io/component: opdata -{{- end }} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/pvc-storage.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/pvc-storage.yaml deleted file mode 100644 index 0b5a79677cd..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/pvc-storage.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) -}} -kind: PersistentVolumeClaim -apiVersion: v1 -metadata: - name: {{ include "common.names.fullname" . }}-storage - labels: {{- include "common.labels.standard" . | nindent 4 }} - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} - {{- end }} -spec: - accessModes: - - {{ .Values.persistence.accessMode | quote }} - resources: - requests: - storage: {{ .Values.persistence.size | quote }} - {{- include "common.storage.class" (dict "persistence" .Values.persistence "global" .Values.global) | nindent 2 }} -{{- end -}} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/pypi/configmap.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/pypi/configmap.yaml deleted file mode 100644 index d36df7a0136..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/pypi/configmap.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{- if .Values.pypi.enabled -}} -kind: ConfigMap -apiVersion: v1 -metadata: - name: {{ include "common.names.fullname" . }}-pypi - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: pypi - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -data: - application.yml: |- - pypi: - domain: {{ .Values.gateway.host }}/pypi - {{- if keys $.Values.pypi.config }} - {{- toYaml .Values.pypi.config | nindent 6 }} - {{- end}} -{{- end }} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/pypi/deployment.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/pypi/deployment.yaml deleted file mode 100644 index fd7b834c993..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/pypi/deployment.yaml +++ /dev/null @@ -1,112 +0,0 @@ -{{- if .Values.pypi.enabled -}} -apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }} -kind: Deployment -metadata: - name: {{ include "common.names.fullname" . }}-pypi - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: pypi - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -spec: - selector: - matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} - app.kubernetes.io/component: pypi - replicas: {{ default 1 .Values.pypi.replicaCount }} - template: - metadata: - labels: {{- include "common.labels.standard" . | nindent 8 }} - app.kubernetes.io/component: pypi - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - {{- if .Values.pypi.podLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.pypi.podLabels "context" $) | nindent 8 }} - {{- end }} - spec: - serviceAccountName: {{ template "bkrepo.serviceAccountName" . }} - {{- include "bkrepo.imagePullSecrets" . | nindent 6 }} - {{- if .Values.pypi.hostAliases }} - hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.pypi.hostAliases "context" $) | nindent 8 }} - {{- end }} - {{- if .Values.pypi.affinity }} - affinity: {{- include "common.tplvalues.render" ( dict "value" .Values.pypi.affinity "context" $) | nindent 8 }} - {{- else }} - affinity: - {{- if eq .Values.persistence.accessMode "ReadWriteOnce" }} - podAffinity: {{- include "common.affinities.pods" (dict "type" "hard" "component" "repository" "context" $) | nindent 10 }} - {{- else }} - podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.repository.podAffinityPreset "component" "pypi" "context" $) | nindent 10 }} - {{- end }} - podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.pypi.podAntiAffinityPreset "component" "pypi" "context" $) | nindent 10 }} - nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.pypi.nodeAffinityPreset.type "key" .Values.pypi.nodeAffinityPreset.key "values" .Values.pypi.nodeAffinityPreset.values) | nindent 10 }} - {{- end }} - {{- if .Values.pypi.nodeSelector }} - nodeSelector: {{- include "common.tplvalues.render" ( dict "value" .Values.pypi.nodeSelector "context" $) | nindent 8 }} - {{- end }} - {{- if .Values.pypi.tolerations }} - tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.pypi.tolerations "context" .) | nindent 8 }} - {{- end }} - {{- if .Values.pypi.priorityClassName }} - priorityClassName: {{ .Values.pypi.priorityClassName | quote }} - {{- end }} - {{- if .Values.pypi.podSecurityContext.enabled }} - securityContext: {{- omit .Values.pypi.podSecurityContext "enabled" | toYaml | nindent 8 }} - {{- end }} - containers: - - name: pypi - image: {{ include "bkrepo.images.image" ( dict "imageRoot" .Values.pypi.image "global" .Values.global "bkrepo" .Values.common) }} - imagePullPolicy: {{ .Values.pypi.image.pullPolicy }} - {{- if .Values.pypi.containerSecurityContext.enabled }} - securityContext: {{- omit .Values.pypi.containerSecurityContext "enabled" | toYaml | nindent 12 }} - {{- end }} - {{- if .Values.pypi.resources }} - resources: {{- toYaml .Values.pypi.resources | nindent 12 }} - {{- end }} - env: - - name: BK_REPO_JVM_OPTION - value: {{ .Values.common.jvmOption }} - - name: BK_REPO_PROFILE - value: {{ .Values.common.springProfile }} - - name: BK_REPO_SERVICE_PREFIX - value: {{ include "common.names.fullname" . }}- - ports: - - name: http - containerPort: 25805 - protocol: TCP - livenessProbe: - httpGet: - path: /actuator/health/livenessState - port: http - initialDelaySeconds: 120 - periodSeconds: 15 - timeoutSeconds: 10 - failureThreshold: 5 - successThreshold: 1 - readinessProbe: - httpGet: - path: /actuator/health/readinessState - port: http - initialDelaySeconds: 60 - periodSeconds: 15 - timeoutSeconds: 10 - failureThreshold: 5 - successThreshold: 1 - volumeMounts: - - name: storage - mountPath: {{ .Values.common.mountPath }} - volumes: - - name: storage - {{- if .Values.common.config.storage.nfs.enabled }} - nfs: - path: {{ .Values.common.config.storage.nfs.path }} - server: {{ .Values.common.config.storage.nfs.server }} - {{- else if .Values.persistence.enabled }} - persistentVolumeClaim: - claimName: {{ if .Values.persistence.existingClaim }}{{ .Values.persistence.existingClaim }}{{- else }}{{ template "common.names.fullname" . }}-storage{{- end }} - {{- else }} - emptyDir: {} - {{- end }} -{{- end }} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/pypi/service.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/pypi/service.yaml deleted file mode 100644 index acd38a34291..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/pypi/service.yaml +++ /dev/null @@ -1,24 +0,0 @@ -{{- if .Values.pypi.enabled -}} -apiVersion: v1 -kind: Service -metadata: - name: {{ include "common.names.fullname" . }}-pypi - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: pypi - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -spec: - type: ClusterIP - ports: - - name: http - port: 80 - targetPort: http - protocol: TCP - selector: {{- include "common.labels.matchLabels" . | nindent 4 }} - app.kubernetes.io/component: pypi -{{- end }} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/rbac/role.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/rbac/role.yaml deleted file mode 100644 index 9679a258d9b..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/rbac/role.yaml +++ /dev/null @@ -1,26 +0,0 @@ -{{- if .Values.rbac.create -}} -apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} -kind: Role -metadata: - name: {{ include "common.names.fullname" . }} - labels: {{- include "common.labels.standard" . | nindent 4 }} - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -rules: - - apiGroups: - - "" - resources: - - configmaps - - services - - secrets - - endpoints - - persistentvolumeclaims - verbs: - - get - - watch - - list -{{- end -}} \ No newline at end of file diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/rbac/rolebinding.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/rbac/rolebinding.yaml deleted file mode 100644 index f5e66ef2ab3..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/rbac/rolebinding.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- if .Values.rbac.create -}} -apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} -kind: RoleBinding -metadata: - name: {{ include "common.names.fullname" . }} - labels: {{- include "common.labels.standard" . | nindent 4 }} - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: {{ include "common.names.fullname" . }} -subjects: - - kind: ServiceAccount - name: {{ include "bkrepo.serviceAccountName" . }} -{{- end -}} \ No newline at end of file diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/rbac/serviceaccount.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/rbac/serviceaccount.yaml deleted file mode 100644 index 88456f3affa..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/rbac/serviceaccount.yaml +++ /dev/null @@ -1,15 +0,0 @@ -{{- if .Values.serviceAccount.create -}} -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: serviceaccount - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} - {{- end }} - name: {{ include "bkrepo.serviceAccountName" . }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} - {{- end }} - namespace: {{ .Release.Namespace }} -{{- end -}} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/replication/configmap.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/replication/configmap.yaml deleted file mode 100644 index 2e99a8205f1..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/replication/configmap.yaml +++ /dev/null @@ -1,23 +0,0 @@ -{{- if .Values.replication.enabled -}} -kind: ConfigMap -apiVersion: v1 -metadata: - name: {{ include "common.names.fullname" . }}-replication - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: replication - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -data: - application.yml: |- - # 应用版本 - spring: - application: - version: 1.0.0 - {{- if keys $.Values.replication.config }} - {{- toYaml .Values.replication.config | nindent 6 }} - {{- end}} - {{- end }} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/replication/deployment.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/replication/deployment.yaml deleted file mode 100644 index 50003a8fdbd..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/replication/deployment.yaml +++ /dev/null @@ -1,112 +0,0 @@ -{{- if .Values.replication.enabled -}} -apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }} -kind: Deployment -metadata: - name: {{ include "common.names.fullname" . }}-replication - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: replication - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -spec: - selector: - matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} - app.kubernetes.io/component: replication - replicas: {{ default 1 .Values.replication.replicaCount }} - template: - metadata: - labels: {{- include "common.labels.standard" . | nindent 8 }} - app.kubernetes.io/component: replication - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - {{- if .Values.replication.podLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.replication.podLabels "context" $) | nindent 8 }} - {{- end }} - spec: - serviceAccountName: {{ template "bkrepo.serviceAccountName" . }} - {{- include "bkrepo.imagePullSecrets" . | nindent 6 }} - {{- if .Values.replication.hostAliases }} - hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.replication.hostAliases "context" $) | nindent 8 }} - {{- end }} - {{- if .Values.replication.affinity }} - affinity: {{- include "common.tplvalues.render" ( dict "value" .Values.replication.affinity "context" $) | nindent 8 }} - {{- else }} - affinity: - {{- if eq .Values.persistence.accessMode "ReadWriteOnce" }} - podAffinity: {{- include "common.affinities.pods" (dict "type" "hard" "component" "repository" "context" $) | nindent 10 }} - {{- else }} - podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.repository.podAffinityPreset "component" "replication" "context" $) | nindent 10 }} - {{- end }} - podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.replication.podAntiAffinityPreset "component" "replication" "context" $) | nindent 10 }} - nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.replication.nodeAffinityPreset.type "key" .Values.replication.nodeAffinityPreset.key "values" .Values.replication.nodeAffinityPreset.values) | nindent 10 }} - {{- end }} - {{- if .Values.replication.nodeSelector }} - nodeSelector: {{- include "common.tplvalues.render" ( dict "value" .Values.replication.nodeSelector "context" $) | nindent 8 }} - {{- end }} - {{- if .Values.replication.tolerations }} - tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.replication.tolerations "context" .) | nindent 8 }} - {{- end }} - {{- if .Values.replication.priorityClassName }} - priorityClassName: {{ .Values.replication.priorityClassName | quote }} - {{- end }} - {{- if .Values.replication.podSecurityContext.enabled }} - securityContext: {{- omit .Values.replication.podSecurityContext "enabled" | toYaml | nindent 8 }} - {{- end }} - containers: - - name: replication - image: {{ include "bkrepo.images.image" ( dict "imageRoot" .Values.replication.image "global" .Values.global "bkrepo" .Values.common) }} - imagePullPolicy: {{ .Values.replication.image.pullPolicy }} - {{- if .Values.replication.containerSecurityContext.enabled }} - securityContext: {{- omit .Values.replication.containerSecurityContext "enabled" | toYaml | nindent 12 }} - {{- end }} - {{- if .Values.replication.resources }} - resources: {{- toYaml .Values.replication.resources | nindent 12 }} - {{- end }} - env: - - name: BK_REPO_JVM_OPTION - value: {{ .Values.common.jvmOption }} - - name: BK_REPO_PROFILE - value: {{ .Values.common.springProfile }} - - name: BK_REPO_SERVICE_PREFIX - value: {{ include "common.names.fullname" . }}- - ports: - - name: http - containerPort: 25903 - protocol: TCP - livenessProbe: - httpGet: - path: /actuator/health/livenessState - port: http - initialDelaySeconds: 120 - periodSeconds: 15 - timeoutSeconds: 10 - failureThreshold: 5 - successThreshold: 1 - readinessProbe: - httpGet: - path: /actuator/health/readinessState - port: http - initialDelaySeconds: 60 - periodSeconds: 15 - timeoutSeconds: 10 - failureThreshold: 5 - successThreshold: 1 - volumeMounts: - - name: storage - mountPath: {{ .Values.common.mountPath }} - volumes: - - name: storage - {{- if .Values.common.config.storage.nfs.enabled }} - nfs: - path: {{ .Values.common.config.storage.nfs.path }} - server: {{ .Values.common.config.storage.nfs.server }} - {{- else if .Values.persistence.enabled }} - persistentVolumeClaim: - claimName: {{ if .Values.persistence.existingClaim }}{{ .Values.persistence.existingClaim }}{{- else }}{{ template "common.names.fullname" . }}-storage{{- end }} - {{- else }} - emptyDir: {} - {{- end }} -{{- end }} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/replication/service.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/replication/service.yaml deleted file mode 100644 index 897b279c0a3..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/replication/service.yaml +++ /dev/null @@ -1,24 +0,0 @@ -{{- if .Values.replication.enabled -}} -apiVersion: v1 -kind: Service -metadata: - name: {{ include "common.names.fullname" . }}-replication - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: replication - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -spec: - type: ClusterIP - ports: - - name: http - port: 80 - targetPort: http - protocol: TCP - selector: {{- include "common.labels.matchLabels" . | nindent 4 }} - app.kubernetes.io/component: replication -{{- end }} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/repository/configmap.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/repository/configmap.yaml deleted file mode 100644 index 45bd348b7be..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/repository/configmap.yaml +++ /dev/null @@ -1,18 +0,0 @@ -kind: ConfigMap -apiVersion: v1 -metadata: - name: {{ include "common.names.fullname" . }}-repository - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: repository - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -data: - application.yml: |- - repository: - {{- if keys $.Values.repository.config }} - {{- toYaml .Values.repository.config | nindent 6 }} - {{- end}} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/repository/deployment.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/repository/deployment.yaml deleted file mode 100644 index a8fceff9657..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/repository/deployment.yaml +++ /dev/null @@ -1,126 +0,0 @@ -apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }} -kind: Deployment -metadata: - name: {{ include "common.names.fullname" . }}-repository - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: repository - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -spec: - selector: - matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} - app.kubernetes.io/component: repository - replicas: {{ default 1 .Values.repository.replicaCount }} - template: - metadata: - labels: {{- include "common.labels.standard" . | nindent 8 }} - app.kubernetes.io/component: repository - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - {{- if .Values.repository.podLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.repository.podLabels "context" $) | nindent 8 }} - {{- end }} - spec: - serviceAccountName: {{ template "bkrepo.serviceAccountName" . }} - {{- include "bkrepo.imagePullSecrets" . | nindent 6 }} - {{- if .Values.repository.hostAliases }} - hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.repository.hostAliases "context" $) | nindent 8 }} - {{- end }} - {{- if .Values.repository.affinity }} - affinity: {{- include "common.tplvalues.render" ( dict "value" .Values.repository.affinity "context" $) | nindent 8 }} - {{- else }} - affinity: - {{- if eq .Values.persistence.accessMode "ReadWriteOnce" }} - podAffinity: {{- include "common.affinities.pods" (dict "type" "hard" "component" "repository" "context" $) | nindent 10 }} - {{- else }} - podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.repository.podAffinityPreset "component" "repository" "context" $) | nindent 10 }} - {{- end }} - podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.repository.podAntiAffinityPreset "component" "repository" "context" $) | nindent 10 }} - nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.repository.nodeAffinityPreset.type "key" .Values.repository.nodeAffinityPreset.key "values" .Values.repository.nodeAffinityPreset.values) | nindent 10 }} - {{- end }} - {{- if .Values.repository.nodeSelector }} - nodeSelector: {{- include "common.tplvalues.render" ( dict "value" .Values.repository.nodeSelector "context" $) | nindent 8 }} - {{- end }} - {{- if .Values.repository.tolerations }} - tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.repository.tolerations "context" .) | nindent 8 }} - {{- end }} - {{- if .Values.repository.priorityClassName }} - priorityClassName: {{ .Values.repository.priorityClassName | quote }} - {{- end }} - {{- if .Values.repository.podSecurityContext.enabled }} - securityContext: {{- omit .Values.repository.podSecurityContext "enabled" | toYaml | nindent 8 }} - {{- end }} - {{- if .Values.mongodb.enabled }} - initContainers: - - name: wait-for-mongodb - image: {{ include "bkrepo.images.image" ( dict "imageRoot" .Values.init.mongodb.image "global" .Values.global "bkrepo" .Values.common) }} - imagePullPolicy: {{ .Values.init.mongodb.image.pullPolicy }} - command: - - "/bin/sh" - - "-c" - - | - until getent hosts {{ include "bkrepo.mongodb.fullname" . }} - do - echo waiting for {{ include "bkrepo.mongodb.fullname" . }}; - sleep 2; - done - echo "Mongodb is available"; - {{- end }} - containers: - - name: repository - image: {{ include "bkrepo.images.image" ( dict "imageRoot" .Values.repository.image "global" .Values.global "bkrepo" .Values.common) }} - imagePullPolicy: {{ .Values.repository.image.pullPolicy }} - {{- if .Values.repository.containerSecurityContext.enabled }} - securityContext: {{- omit .Values.repository.containerSecurityContext "enabled" | toYaml | nindent 12 }} - {{- end }} - {{- if .Values.repository.resources }} - resources: {{- toYaml .Values.repository.resources | nindent 12 }} - {{- end }} - env: - - name: BK_REPO_JVM_OPTION - value: {{ .Values.common.jvmOption }} - - name: BK_REPO_PROFILE - value: {{ .Values.common.springProfile }} - - name: BK_REPO_SERVICE_PREFIX - value: {{ include "common.names.fullname" . }}- - ports: - - name: http - containerPort: 25901 - protocol: TCP - livenessProbe: - httpGet: - path: /actuator/health/livenessState - port: http - initialDelaySeconds: 120 - periodSeconds: 15 - timeoutSeconds: 10 - failureThreshold: 5 - successThreshold: 1 - readinessProbe: - httpGet: - path: /actuator/health/readinessState - port: http - initialDelaySeconds: 60 - periodSeconds: 15 - timeoutSeconds: 10 - failureThreshold: 5 - successThreshold: 1 - volumeMounts: - - name: storage - mountPath: {{ .Values.common.mountPath }} - volumes: - - name: storage - {{- if .Values.common.config.storage.nfs.enabled }} - nfs: - path: {{ .Values.common.config.storage.nfs.path }} - server: {{ .Values.common.config.storage.nfs.server }} - {{- else if .Values.persistence.enabled }} - persistentVolumeClaim: - claimName: {{ if .Values.persistence.existingClaim }}{{ .Values.persistence.existingClaim }}{{- else }}{{ template "common.names.fullname" . }}-storage{{- end }} - {{- else }} - emptyDir: {} - {{- end }} diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/repository/service.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/repository/service.yaml deleted file mode 100644 index ae36a3ff781..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/repository/service.yaml +++ /dev/null @@ -1,22 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ include "common.names.fullname" . }}-repository - labels: {{- include "common.labels.standard" . | nindent 4 }} - app.kubernetes.io/component: repository - {{ include "bkrepo.labelValues.scope" . }}: {{ include "bkrepo.labelValues.scope.backend" . }} - {{- if .Values.commonLabels }} - {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} - {{- end }} - {{- if .Values.commonAnnotations }} - annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} - {{- end }} -spec: - type: ClusterIP - ports: - - name: http - port: 80 - targetPort: http - protocol: TCP - selector: {{- include "common.labels.matchLabels" . | nindent 4 }} - app.kubernetes.io/component: repository diff --git a/support-files/storage/kubernetes/charts/bkrepo/templates/tls-secret.yaml b/support-files/storage/kubernetes/charts/bkrepo/templates/tls-secret.yaml deleted file mode 100644 index adc12416d2f..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/templates/tls-secret.yaml +++ /dev/null @@ -1,10 +0,0 @@ -{{- if and (eq .Values.ingress.tls true) (ne .Values.ingress.crt "") }} -apiVersion: v1 -kind: Secret -type: kubernetes.io/tls -metadata: - name: bkrepo-tls -data: - tls.crt: {{ .Values.ingress.crt | b64enc }} - tls.key: {{ .Values.ingress.key | b64enc }} -{{- end }} diff --git a/support-files/storage/kubernetes/charts/bkrepo/values.schema.json b/support-files/storage/kubernetes/charts/bkrepo/values.schema.json deleted file mode 100644 index 73cabebe4ed..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/values.schema.json +++ /dev/null @@ -1,194 +0,0 @@ -{ - "$schema": "http://json-schema.org/schema#", - "type": "object", - "properties": { - "common": { - "type": "object", - "title": "初始用户信息", - "description": "配置bkrepo初始用户名/密码", - "form": true, - "properties": { - "username": { - "type": "string", - "title": "bkrepo初始用户名", - "form": true - }, - "password": { - "type": "string", - "title": "bkrepo初始密码", - "form": true - } - } - }, - "mongodb": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "title": "是否部署mongodb", - "form": true - } - } - }, - "externalMongodb": { - "type": "object", - "title": "外部mongodb服务配置", - "form": true, - "hidden": "mongodb/enabled", - "properties": { - "uri": { - "type": "string", - "title": "连接字符串", - "form": true - } - } - }, - "init": { - "type": "object", - "properties": { - "mongodb": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "title": "是否初始化数据库,支持幂等执行", - "form": true - } - } - } - } - }, - "ingress": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "title": "是否创建ingress", - "form": true - } - } - }, - "nginx-ingress-controller": { - "type": "object", - "title": "nginx-ingress-controller配置", - "form": true, - "hidden": { - "value": false, - "path": "ingress/enabled" - }, - "properties": { - "enabled": { - "type": "boolean", - "title": "是否部署nginx-ingress-controller", - "form": true - } - } - }, - "persistence": { - "type": "object", - "title": "数据持久化设置", - "form": true, - "properties": { - "enabled": { - "type": "boolean", - "form": true, - "title": "开启数据持久化", - "description": "请提前创建可用的pv,否则默认创建的pv在应用删除后会被清理" - }, - "size": { - "type": "string", - "title": "Volume大小", - "form": true, - "render": "slider", - "sliderMin": 10, - "sliderUnit": "Gi", - "hidden": { - "value": false, - "path": "persistence/enabled" - } - } - } - }, - "gateway": { - "type": "object", - "title": "gateway配置", - "description": "gateway是bkrepo的服务入口", - "form": true, - "properties": { - "host": { - "type": "string", - "title": "域名", - "description": "gateway必须通过域名访问", - "form": true - }, - "service": { - "type": "object", - "title": "Service配置", - "form": true, - "properties": { - "type": { - "type": "string", - "title": "Service类型", - "enum": [ - "ClusterIP", - "NodePort", - "LoadBalancer" - ], - "form": true - } - } - } - } - }, - "generic": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "title": "是否部署generic registry", - "form": true - } - } - }, - "docker": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "title": "是否部署docker registry", - "form": true - } - } - }, - "npm": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "title": "是否部署npm registry", - "form": true - } - } - }, - "pypi": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "title": "是否部署pypi registry", - "form": true - } - } - }, - "helm": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "title": "是否部署helm registry", - "form": true - } - } - } - } -} \ No newline at end of file diff --git a/support-files/storage/kubernetes/charts/bkrepo/values.yaml b/support-files/storage/kubernetes/charts/bkrepo/values.yaml deleted file mode 100644 index 9f366b19bc7..00000000000 --- a/support-files/storage/kubernetes/charts/bkrepo/values.yaml +++ /dev/null @@ -1,595 +0,0 @@ -## Global Docker image parameters -## Please, note that this will override the image parameters, including dependencies, configured to use the global value -## Current available global Docker image parameters: imageRegistry and imagePullSecrets -## -# global: -# imageRegistry: myRegistryName -# imagePullSecrets: -# - myRegistryKeySecretName -# storageClass: myStorageClass - -## Add labels to all the deployed resources -## -commonLabels: {} - -## Add annotations to all the deployed resources -## -commonAnnotations: {} - -## Specifies whether RBAC resources should be created -## -rbac: - create: true - -## Specifies whether a ServiceAccount should be created -## -serviceAccount: - create: true - ## The name of the ServiceAccount to use. - ## If not set and create is true, a name is generated using the fullname template - ## - name: - -# metrics采集配置 -serviceMonitor: - enabled: false - - -## 日志采集配置 -bkLogConfig: - enabled: false - service: - dataId: 1 - gatewayAccess: - dataId: 1 - gatewayError: - dataId: 1 - -## ingress配置 -ingress: - enabled: true - tls: false - crt: "" - key: "" - annotations: - kubernetes.io/ingress.class: nginx - nginx.ingress.kubernetes.io/proxy-body-size: "10240m" - -## nginx-ingress-controller 配置 -## ref: https://github.com/bitnami/charts/tree/master/bitnami/nginx-ingress-controller -nginx-ingress-controller: - ## 是否部署nginx-ingress-controller - hostNetwork: false - replicaCount: 1 - enabled: true - defaultBackend: - enabled: false - -## mongodb charts配置 -## ref: https://github.com/bitnami/charts/tree/master/bitnami/mongodb -mongodb: - # 是否部署mongodb - # 如果需要使用外部数据库,设置为false并配置externalMongodb - enabled: true - auth: - enabled: true - database: bkrepo - username: bkrepo - password: bkrepo - persistence: - subPath: mongodb - size: 20Gi - -## 如果mongodb.enabled为false,bkrepo将使用下面的参数连接外部mongodb -externalMongodb: - ## mongodb 标准连接字符串 - uri: mongodb://bkrepo:bkrepo@localhost:27017/bkrepo - -## 数据持久化配置, 当使用filesystem方式存储时需要配置 -## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ -persistence: - ## 是否开启数据持久化,false则使用emptyDir类型volume, pod结束后数据将被清空,无法持久化 - enabled: true - accessMode: ReadWriteOnce - size: 100Gi - - ## 如果不定义或设置为null, 将使用默认的storageClass(minikube上是hostPath, AWS上的gp2, GKE上是standard) - ## 如果设置为"-", 则禁用动态卷供应 - ## 如果设置为其它值,则storageClassName: - # storageClass: "-" - - ## 绑定k8s集群中已存在的pvc - ## Requires persistence.enabled: true - # existingClaim: my-persistent-volume-claim - - ## 如果开启持久化,并且没有任何上述配置,将使用动态卷供应方式提供存储,使用storageClass定义的存储类。 - ## 在删除该声明后,这个卷也会被销毁(用于单节点环境,生产环境不推荐)。 - # ref: https://kubernetes.io/docs/concepts/storage/dynamic-provisioning/ - -init: - mongodb: - enabled: true - image: - registry: mirrors.tencent.com - repository: blueking/bkrepo-init - tag: 1.1.0 - pullPolicy: IfNotPresent - pullSecrets: [] -## bkrepo公共配置 -common: - # bkrepo镜像仓库全局配置, 具有最高优先级 - imageRegistry: "" - # bkrepo镜像tag全局配置, 具有最高优先级 - imageTag: "" - ## 部署区域,可不填 - region: - ## jvm启动选项, 如-Xms1024M -Xmx1024M - jvmOption: "" - ## SpringBoot active profile - springProfile: dev - ## 初始用户名 - username: admin - ## 初始用户密码 - password: blueking - ## pod volume 挂载路径 - mountPath: /data/storage - config: - ## bkrepo存储配置 - storage: - ## 指定存储类型,支持filesystem/cos/s3/hdfs/innercos - type: filesystem - ## filesystem配置,使用文件系统 - filesystem: - path: /data/storage/store - ## innercos,使用对象存储终端存储文件 - innercos: - ## cos secretId - secretId: xxx - ## cos secretKey - secretKey: xxx - ## cos region - region: gzc - ## cos bucket ,比如test-00001 - bucket: test-00001 - ## lb modeId - modId: 000001 - ## lb cmdId - cmdId: 0001 - cache: - enabled: true - path: /data/storage/cached - expireDays: 14 - loadCacheFirst: true - upload: - location: /data/storage/temp - # 是否启用nfs挂载 - nfs: - enabled: false - path: / - server: - - ## 腾讯云cos存储配置 - #cos: - ## 标准s3对象存储 - #s3: - ## hdfs存储配置 - #hdfs: - -## 网关配置 -gateway: - ## bkrepo 地址 - host: bkrepo.example.com - ## bkrepo docker仓库地址 - dockerHost: docker.bkrepo.example.com - ## bkrepo helm仓库地址 - helmHost: helm.bkrepo.example.com - ## dns服务器地址,用于配置nginx resolver。local=on为openrestry语法,取本机/etc/resolv.conf配置 - dnsServer: local=on - ## 网关访问微服务认证信息 - authorization: "Platform MThiNjFjOWMtOTAxYi00ZWEzLTg5YzMtMWY3NGJlOTQ0YjY2OlVzOFpHRFhQcWs4NmN3TXVrWUFCUXFDWkxBa00zSw==" - ## 部署模式,standalone: 独立模式,ci: 与ci搭配模式 - deployMode: standalone - ## bkrepo gateway service配置 - service: - type: ClusterIP - ## 服务类型为`ClusterIP`时端口设置 - port: 80 - ## 服务类型为`NodePort`时端口设置 - nodePort: 30025 - ## Kubernetes 通用配置 - image: - registry: mirrors.tencent.com - repository: blueking/bkrepo-gateway - tag: 1.1.0 - pullPolicy: IfNotPresent - pullSecrets: [] - replicaCount: 1 - hostAliases: [] - resources: - requests: - cpu: 100m - memory: 1000Mi - limits: - cpu: 500m - memory: 1500Mi - containerSecurityContext: - enabled: false - runAsUser: 1001 - runAsNonRoot: true - podSecurityContext: - enabled: false - fsGroup: 1001 - podAffinityPreset: "" - podAntiAffinityPreset: "" - nodeAffinityPreset: - type: "" - key: "" - values: [] - affinity: {} - nodeSelector: {} - tolerations: [] - podLabels: {} - podAnnotations: {} - priorityClassName: "" - -## 仓库服务配置 -repository: - config: - # 节点被删除后多久清理数据 - deletedNodeReserveDays: 15 - ## Kubernetes 通用配置 - image: - registry: mirrors.tencent.com - repository: blueking/bkrepo-repository - tag: 1.1.0 - pullPolicy: IfNotPresent - pullSecrets: [] - replicaCount: 1 - hostAliases: [] - resources: - requests: - cpu: 100m - memory: 1000Mi - limits: - cpu: 500m - memory: 1500Mi - containerSecurityContext: - enabled: false - runAsUser: 1001 - runAsNonRoot: true - podSecurityContext: - enabled: false - fsGroup: 1001 - podAffinityPreset: "" - podAntiAffinityPreset: "" - nodeAffinityPreset: - type: "" - key: "" - values: [] - affinity: {} - nodeSelector: {} - tolerations: [] - podLabels: {} - podAnnotations: {} - priorityClassName: "" - -## 认证服务配置 -auth: - config: - ## 指定realm类型,支持local/devops - realm: local - ## Kubernetes 通用配置 - image: - registry: mirrors.tencent.com - repository: blueking/bkrepo-auth - tag: 1.1.0 - pullPolicy: IfNotPresent - pullSecrets: [] - replicaCount: 1 - hostAliases: [] - resources: - requests: - cpu: 100m - memory: 1000Mi - limits: - cpu: 500m - memory: 1500Mi - containerSecurityContext: - enabled: false - runAsUser: 1001 - runAsNonRoot: true - podSecurityContext: - enabled: false - fsGroup: 1001 - podAffinityPreset: "" - podAntiAffinityPreset: "" - nodeAffinityPreset: - type: "" - key: "" - values: [] - affinity: {} - nodeSelector: {} - tolerations: [] - podLabels: {} - podAnnotations: {} - priorityClassName: "" - -## generic服务配置 -generic: - enabled: true - config: {} - ## Kubernetes 通用配置 - image: - registry: mirrors.tencent.com - repository: blueking/bkrepo-generic - tag: 1.1.0 - pullPolicy: IfNotPresent - pullSecrets: [] - replicaCount: 1 - hostAliases: [] - resources: - requests: - cpu: 100m - memory: 1000Mi - limits: - cpu: 500m - memory: 1500Mi - containerSecurityContext: - enabled: false - runAsUser: 1001 - runAsNonRoot: true - podSecurityContext: - enabled: false - fsGroup: 1001 - podAffinityPreset: "" - podAntiAffinityPreset: "" - nodeAffinityPreset: - type: "" - key: "" - values: [] - affinity: {} - nodeSelector: {} - tolerations: [] - podLabels: {} - podAnnotations: {} - priorityClassName: "" - -## replication服务配置 -replication: - enabled: true - config: {} - ## Kubernetes 通用配置 - image: - registry: mirrors.tencent.com - repository: blueking/bkrepo-replication - tag: 1.1.0 - pullPolicy: IfNotPresent - pullSecrets: [] - replicaCount: 1 - hostAliases: [] - resources: - requests: - cpu: 100m - memory: 1000Mi - limits: - cpu: 500m - memory: 1500Mi - containerSecurityContext: - enabled: false - runAsUser: 1001 - runAsNonRoot: true - podSecurityContext: - enabled: false - fsGroup: 1001 - podAffinityPreset: "" - podAntiAffinityPreset: "" - nodeAffinityPreset: - type: "" - key: "" - values: [] - affinity: {} - nodeSelector: {} - tolerations: [] - podLabels: {} - podAnnotations: {} - priorityClassName: "" - -## opdata服务配置 -opdata: - enabled: true - config: {} - ## Kubernetes 通用配置 - image: - registry: mirrors.tencent.com - repository: blueking/bkrepo-opdata - tag: 1.1.3 - pullPolicy: IfNotPresent - pullSecrets: [] - replicaCount: 1 - hostAliases: [] - resources: - requests: - cpu: 100m - memory: 1000Mi - limits: - cpu: 500m - memory: 1500Mi - containerSecurityContext: - enabled: false - runAsUser: 1001 - runAsNonRoot: true - podSecurityContext: - enabled: false - fsGroup: 1001 - podAffinityPreset: "" - podAntiAffinityPreset: "" - nodeAffinityPreset: - type: "" - key: "" - values: [] - affinity: {} - nodeSelector: {} - tolerations: [] - podLabels: {} - podAnnotations: {} - priorityClassName: "" - -## docker registry服务配置 -docker: - enabled: false - config: {} - ## Kubernetes 通用配置 - image: - registry: mirrors.tencent.com - repository: blueking/bkrepo-docker - tag: 1.1.0 - pullPolicy: IfNotPresent - pullSecrets: [] - replicaCount: 1 - hostAliases: [] - resources: - requests: - cpu: 100m - memory: 1000Mi - limits: - cpu: 500m - memory: 1500Mi - containerSecurityContext: - enabled: false - runAsUser: 1001 - runAsNonRoot: true - podSecurityContext: - enabled: false - fsGroup: 1001 - podAffinityPreset: "" - podAntiAffinityPreset: "" - nodeAffinityPreset: - type: "" - key: "" - values: [] - affinity: {} - nodeSelector: {} - tolerations: [] - podLabels: {} - podAnnotations: {} - priorityClassName: "" - -## npm registry服务配置 -npm: - enabled: false - config: {} - ## Kubernetes 通用配置 - image: - registry: mirrors.tencent.com - repository: blueking/bkrepo-npm - tag: 1.1.0 - pullPolicy: IfNotPresent - pullSecrets: [] - replicaCount: 1 - hostAliases: [] - resources: - requests: - cpu: 100m - memory: 1000Mi - limits: - cpu: 500m - memory: 1500Mi - containerSecurityContext: - enabled: false - runAsUser: 1001 - runAsNonRoot: true - podSecurityContext: - enabled: false - fsGroup: 1001 - podAffinityPreset: "" - podAntiAffinityPreset: "" - nodeAffinityPreset: - type: "" - key: "" - values: [] - affinity: {} - nodeSelector: {} - tolerations: [] - podLabels: {} - podAnnotations: {} - priorityClassName: "" - -## pypi registry服务配置 -pypi: - enabled: false - config: {} - ## Kubernetes 通用配置 - image: - registry: mirrors.tencent.com - repository: blueking/bkrepo-pypi - tag: 1.1.0 - pullPolicy: IfNotPresent - pullSecrets: [] - replicaCount: 1 - hostAliases: [] - resources: - requests: - cpu: 100m - memory: 1000Mi - limits: - cpu: 500m - memory: 1500Mi - containerSecurityContext: - enabled: false - runAsUser: 1001 - runAsNonRoot: true - podSecurityContext: - enabled: false - fsGroup: 1001 - podAffinityPreset: "" - podAntiAffinityPreset: "" - nodeAffinityPreset: - type: "" - key: "" - values: [] - affinity: {} - nodeSelector: {} - tolerations: [] - podLabels: {} - podAnnotations: {} - priorityClassName: "" - -## helm registry服务配置 -helm: - enabled: false - config: {} - ## Kubernetes 通用配置 - image: - registry: mirrors.tencent.com - repository: blueking/bkrepo-helm - tag: 1.1.0 - pullPolicy: IfNotPresent - pullSecrets: [] - replicaCount: 1 - hostAliases: [] - resources: - requests: - cpu: 100m - memory: 1000Mi - limits: - cpu: 500m - memory: 1500Mi - containerSecurityContext: - enabled: false - runAsUser: 1001 - runAsNonRoot: true - podSecurityContext: - enabled: false - fsGroup: 1001 - podAffinityPreset: "" - podAntiAffinityPreset: "" - nodeAffinityPreset: - type: "" - key: "" - values: [] - affinity: {} - nodeSelector: {} - tolerations: [] - podLabels: {} - podAnnotations: {} - priorityClassName: "" diff --git a/support-files/storage/kubernetes/charts/build.sh b/support-files/storage/kubernetes/charts/build.sh deleted file mode 100755 index 8d00eb7cdf5..00000000000 --- a/support-files/storage/kubernetes/charts/build.sh +++ /dev/null @@ -1,99 +0,0 @@ -#!/usr/bin/env bash -# 用途:构建并推送charts包 - -# 安全模式 -set -euo pipefail - -# 通用脚本框架变量 -PROGRAM=$(basename "$0") -EXITCODE=0 - -VERSION=1.0.0 -APP_VERSION=latest -PUSH=0 -REGISTRY=http://localhost/helm -USERNAME= -PASSWORD= - -cd $(dirname $0) -WORKING_DIR=$(pwd) - -usage () { - cat <&2 - usage_and_exit 1 -} - -warning () { - echo "$@" 1>&2 - EXITCODE=$((EXITCODE + 1)) -} - -# 解析命令行参数,长短混合模式 -(( $# == 0 )) && usage_and_exit 1 -while (( $# > 0 )); do - case "$1" in - -v | --version ) - shift - VERSION=$1 - ;; - -a | --app-version ) - shift - APP_VERSION=$1 - ;; - -p | --push ) - PUSH=1 - ;; - -r | --registry ) - shift - REGISTRY=$1 - ;; - --username ) - shift - USERNAME=$1 - ;; - --password ) - shift - PASSWORD=$1 - ;; - --help | -h | '-?' ) - usage_and_exit 0 - ;; - -*) - error "不可识别的参数: $1" - ;; - *) - break - ;; - esac - shift -done - -helm package bkrepo --version $VERSION --app-version $APP_VERSION -if [[ $PUSH -eq 1 ]] ; then - helm push bkrepo-$VERSION.tgz $REGISTRY -f --username $USERNAME --password $PASSWORD -fi -log "BUILD SUCCESSFUL!" diff --git a/support-files/storage/kubernetes/images/backend/backend.Dockerfile b/support-files/storage/kubernetes/images/backend/backend.Dockerfile deleted file mode 100644 index 985ebef26df..00000000000 --- a/support-files/storage/kubernetes/images/backend/backend.Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM blueking/jdk:0.0.1 - -LABEL maintainer="Tencent BlueKing Devops" - -ENV BK_REPO_HOME=/data/workspace \ - BK_REPO_LOGS_DIR=/data/workspace/logs \ - BK_REPO_SERVICE_PREFIX=repo- \ - BK_REPO_PROFILE=dev - -COPY ./ /data/workspace/ -RUN ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \ - echo 'Asia/Shanghai' > /etc/timezone && \ - chmod +x /data/workspace/startup.sh -WORKDIR /data/workspace -CMD /data/workspace/startup.sh diff --git a/support-files/storage/kubernetes/images/backend/startup.sh b/support-files/storage/kubernetes/images/backend/startup.sh deleted file mode 100755 index f013a77e0b3..00000000000 --- a/support-files/storage/kubernetes/images/backend/startup.sh +++ /dev/null @@ -1,19 +0,0 @@ -#! /bin/sh - -mkdir -p $BK_REPO_LOGS_DIR -chmod 777 $BK_REPO_LOGS_DIR - -java -server \ - -Dsun.jnu.encoding=UTF-8 \ - -Dfile.encoding=UTF-8 \ - -Xloggc:$BK_REPO_LOGS_DIR/gc.log \ - -XX:+PrintTenuringDistribution \ - -XX:+PrintGCDetails \ - -XX:+PrintGCDateStamps \ - -XX:+HeapDumpOnOutOfMemoryError \ - -XX:HeapDumpPath=oom.hprof \ - -XX:ErrorFile=$BK_REPO_LOGS_DIR/error_sys.log \ - -Dspring.profiles.active=$BK_REPO_PROFILE \ - -Dservice.prefix=$BK_REPO_SERVICE_PREFIX \ - $BK_REPO_JVM_OPTION \ - -jar /data/workspace/app.jar diff --git a/support-files/storage/kubernetes/images/build.sh b/support-files/storage/kubernetes/images/build.sh deleted file mode 100755 index 154743e004c..00000000000 --- a/support-files/storage/kubernetes/images/build.sh +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/env bash -# 用途:构建并推送docker镜像 - -# 安全模式 -set -euo pipefail - -# 通用脚本框架变量 -PROGRAM=$(basename "$0") -EXITCODE=0 - -ALL=1 -GATEWAY=0 -BACKEND=0 -INIT=0 -VERSION=latest -PUSH=0 -REGISTRY=docker.io/bkrepo -USERNAME= -PASSWORD= -BACKENDS=(repository auth generic docker helm npm pypi replication opdata) - -cd $(dirname $0) -WORKING_DIR=$(pwd) -ROOT_DIR=${WORKING_DIR%/*/*/*/*} -BACKEND_DIR=$ROOT_DIR/src/backend/storage/core -FRONTEND_DIR=$ROOT_DIR/src/frontend -GATEWAY_DIR=$ROOT_DIR/src/gateway - -usage () { - cat <&2 - usage_and_exit 1 -} - -warning () { - echo "$@" 1>&2 - EXITCODE=$((EXITCODE + 1)) -} - -# 解析命令行参数,长短混合模式 -(( $# == 0 )) && usage_and_exit 1 -while (( $# > 0 )); do - case "$1" in - --gateway ) - ALL=0 - GATEWAY=1 - ;; - --backend ) - ALL=0 - BACKEND=1 - ;; - --init ) - ALL=0 - INIT=1 - ;; - -v | --version ) - shift - VERSION=$1 - ;; - -p | --push ) - PUSH=1 - ;; - -r | --registry ) - shift - REGISTRY=$1 - ;; - --username ) - shift - USERNAME=$1 - ;; - --password ) - shift - PASSWORD=$1 - ;; - --help | -h | '-?' ) - usage_and_exit 0 - ;; - -*) - error "不可识别的参数: $1" - ;; - *) - break - ;; - esac - shift -done - -if [[ $PUSH -eq 1 && -n "$USERNAME" ]] ; then - docker login --username $USERNAME --password $PASSWORD $REGISTRY - log "docker login成功" -fi - -# 创建临时目录 -random=$RANDOM -mkdir -p $WORKING_DIR/tmp_$random -tmp_dir=$WORKING_DIR/tmp_$random -# 执行退出时自动清理tmp目录 -trap 'rm -rf $tmp_dir' EXIT TERM - -# 编译frontend -if [[ $ALL -eq 1 || $GATEWAY -eq 1 ]] ; then - log "编译frontend..." - yarn --cwd $FRONTEND_DIR install - yarn --cwd $FRONTEND_DIR run public - - # 打包gateway镜像 - log "构建gateway镜像..." - rm -rf $tmp_dir/* - cp -rf $FRONTEND_DIR/frontend $tmp_dir/ - cp -rf $GATEWAY_DIR $tmp_dir/gateway - cp -rf gateway/startup.sh $tmp_dir/ - cp -rf $ROOT_DIR/scripts/render_tpl $tmp_dir/ - cp -rf $ROOT_DIR/support-files/templates $tmp_dir/ - docker build -f gateway/gateway.Dockerfile -t $REGISTRY/bkrepo-gateway:$VERSION $tmp_dir --network=host - if [[ $PUSH -eq 1 ]] ; then - docker push $REGISTRY/bkrepo-gateway:$VERSION - fi -fi - -# 构建backend镜像 -if [[ $ALL -eq 1 || $BACKEND -eq 1 ]] ; then - for SERVICE in ${BACKENDS[@]}; - do - log "构建${SERVICE}镜像..." - $BACKEND_DIR/gradlew -p $BACKEND_DIR :$SERVICE:boot-$SERVICE:build -PassemblyMode=k8s -x test - rm -rf $tmp_dir/* - cp backend/startup.sh $tmp_dir/ - cp $BACKEND_DIR/release/boot-$SERVICE-*.jar $tmp_dir/app.jar - docker build -f backend/backend.Dockerfile -t $REGISTRY/bkrepo-$SERVICE:$VERSION $tmp_dir --network=host - if [[ $PUSH -eq 1 ]] ; then - docker push $REGISTRY/bkrepo-$SERVICE:$VERSION - fi - done -fi - -# 构建init镜像 -if [[ $ALL -eq 1 || $INIT -eq 1 ]] ; then - log "构建init镜像..." - rm -rf $tmp_dir/* - cp -rf init/init-mongodb.sh $tmp_dir/ - cp -rf $ROOT_DIR/support-files/sql/init-data.js $tmp_dir/ - docker build -f init/init.Dockerfile -t $REGISTRY/bkrepo-init:$VERSION $tmp_dir --no-cache --network=host - if [[ $PUSH -eq 1 ]] ; then - docker push $REGISTRY/bkrepo-init:$VERSION - fi -fi -echo "BUILD SUCCESSFUL!" diff --git a/support-files/storage/kubernetes/images/gateway/gateway.Dockerfile b/support-files/storage/kubernetes/images/gateway/gateway.Dockerfile deleted file mode 100644 index 7318cbbff19..00000000000 --- a/support-files/storage/kubernetes/images/gateway/gateway.Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -FROM bkrepo/openrestry:0.0.1 - -LABEL maintainer="Tencent BlueKing Devops" - -ENV BK_REPO_HOME=/data/workspace \ - BK_REPO_LOGS_DIR=/data/workspace/logs - -COPY ./ /data/workspace/ - -RUN ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \ - echo 'Asia/Shanghai' > /etc/timezone && \ - rm -rf /usr/local/openresty/nginx/conf &&\ - ln -s /data/workspace/gateway /usr/local/openresty/nginx/conf &&\ - mkdir -p /usr/local/openresty/nginx/run/ && \ - chmod +x /data/workspace/startup.sh &&\ - chmod +x /data/workspace/render_tpl - -WORKDIR /usr/local/openresty/nginx/ -CMD /data/workspace/startup.sh \ No newline at end of file diff --git a/support-files/storage/kubernetes/images/gateway/startup.sh b/support-files/storage/kubernetes/images/gateway/startup.sh deleted file mode 100644 index 454d3697da9..00000000000 --- a/support-files/storage/kubernetes/images/gateway/startup.sh +++ /dev/null @@ -1,12 +0,0 @@ -#! /bin/sh - -mkdir -p $BK_REPO_LOGS_DIR/nginx -chmod 777 $BK_REPO_LOGS_DIR/nginx - -##初始化配置 -touch repo.env -/data/workspace/render_tpl -u -p /data/workspace -m . -e repo.env /data/workspace/templates/gateway* -/data/workspace/render_tpl -u -p /data/workspace -m . -e repo.env /data/workspace/frontend/ui/frontend#ui#index.html - -##启动程序 -/usr/local/openresty/nginx/sbin/nginx -g 'daemon off;' diff --git a/support-files/storage/kubernetes/images/init/init-mongodb.sh b/support-files/storage/kubernetes/images/init/init-mongodb.sh deleted file mode 100644 index eebe9e3894b..00000000000 --- a/support-files/storage/kubernetes/images/init/init-mongodb.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -username=$BK_REPO_USERNAME -password_md5=$(echo -n $BK_REPO_PASSWORD | md5sum | cut -d ' ' -f1) -sed -i "s/\"admin\"/\"$username\"/g" init-data.js -sed -i "s/5f4dcc3b5aa765d61d8327deb882cf99/$password_md5/g" init-data.js - -mongo $BK_REPO_MONGODB_URI init-data.js diff --git a/support-files/storage/kubernetes/images/init/init.Dockerfile b/support-files/storage/kubernetes/images/init/init.Dockerfile deleted file mode 100644 index a18e0abdf0b..00000000000 --- a/support-files/storage/kubernetes/images/init/init.Dockerfile +++ /dev/null @@ -1,8 +0,0 @@ -FROM bkrepo/mongo-shell:0.0.1 - -LABEL maintainer="blueking" - -COPY ./ /data/workspace/ - -RUN chmod +x /data/workspace/init-mongodb.sh -WORKDIR /data/workspace \ No newline at end of file diff --git a/support-files/storage/sql/init-data.js b/support-files/storage/sql/init-data.js deleted file mode 100644 index 324c7809172..00000000000 --- a/support-files/storage/sql/init-data.js +++ /dev/null @@ -1,194 +0,0 @@ -db.user.updateOne( - { userId: "admin" }, - { - $setOnInsert: { - userId: "admin", - name: "admin", - pwd: "5f4dcc3b5aa765d61d8327deb882cf99", - admin: true, - locked: false, - tokens: [], - roles: [], - asstUsers: [], - group: false - } - }, - { upsert: true } -); - -db.account.updateOne( - { appId: "bkdevops" }, - { - $setOnInsert: { - appId: "bkdevops", - locked: "false", - credentials: [{ - accessKey: "18b61c9c-901b-4ea3-89c3-1f74be944b66", - secretKey: "Us8ZGDXPqk86cwMukYABQqCZLAkM3K", - createdAt: new Date(), - status: "ENABLE" - }] - } - }, - { upsert: true } -); - -db.project.updateOne( - { name: "blueking" }, - { - $setOnInsert: { - name: "blueking", - displayName: "blueking", - description: "", - createdBy: "admin", - createdDate: new Date(), - lastModifiedBy: "admin", - lastModifiedDate: new Date() - } - }, - { upsert: true } -); - -db.repository.updateOne( - { - projectId: "blueking", - name: "generic-local" - }, - { - $setOnInsert: { - projectId: "blueking", - name: "generic-local", - type: "GENERIC", - category: "LOCAL", - public: false, - description: "generic local repository", - configuration: "{}", - display: true, - createdBy: "admin", - createdDate: new Date(), - lastModifiedBy: "admin", - lastModifiedDate: new Date() - } - }, - { upsert: true } -); - -db.repository.updateOne( - { - projectId: "blueking", - name: "maven-local" - }, - { - $setOnInsert: { - projectId: "blueking", - name: "maven-local", - type: "MAVEN", - category: "LOCAL", - public: false, - description: "maven local repository", - configuration: "{}", - display: true, - createdBy: "admin", - createdDate: new Date(), - lastModifiedBy: "admin", - lastModifiedDate: new Date() - } - }, - { upsert: true } -); - -db.repository.updateOne( - { - projectId: "blueking", - name: "docker-local" - }, - { - $setOnInsert: { - projectId: "blueking", - name: "docker-local", - type: "DOCKER", - category: "LOCAL", - public: false, - description: "docker local repository", - configuration: "{}", - display: true, - createdBy: "admin", - createdDate: new Date(), - lastModifiedBy: "admin", - lastModifiedDate: new Date() - } - }, - { upsert: true } -); - -db.repository.updateOne( - { - projectId: "blueking", - name: "npm-local" - }, - { - $setOnInsert: { - projectId: "blueking", - name: "npm-local", - type: "NPM", - category: "LOCAL", - public: false, - description: "npm local repository", - configuration: "{}", - display: true, - createdBy: "admin", - createdDate: new Date(), - lastModifiedBy: "admin", - lastModifiedDate: new Date() - } - }, - { upsert: true } -); - -db.repository.updateOne( - { - projectId: "blueking", - name: "pypi-local" - }, - { - $setOnInsert: { - projectId: "blueking", - name: "pypi-local", - type: "PYPI", - category: "LOCAL", - public: false, - description: "pypi local repository", - configuration: "{}", - display: true, - createdBy: "admin", - createdDate: new Date(), - lastModifiedBy: "admin", - lastModifiedDate: new Date() - } - }, - { upsert: true } -); - -db.repository.updateOne( - { - projectId: "blueking", - name: "helm-local" - }, - { - $setOnInsert: { - projectId: "blueking", - name: "helm-local", - type: "HELM", - category: "LOCAL", - public: false, - description: "helm local repository", - configuration: "{}", - display: true, - createdBy: "admin", - createdDate: new Date(), - lastModifiedBy: "admin", - lastModifiedDate: new Date() - } - }, - { upsert: true } -); diff --git a/support-files/storage/templates/#etc#bkrepo#application.yaml b/support-files/storage/templates/#etc#bkrepo#application.yaml deleted file mode 100644 index d0e425dd8d0..00000000000 --- a/support-files/storage/templates/#etc#bkrepo#application.yaml +++ /dev/null @@ -1,39 +0,0 @@ -spring: - cloud: - consul: - discovery: - tags: __BK_REPO_CONSUL_TAG__ - data: - mongodb: - uri: __BK_REPO_MONGODB_URI__ - transaction: - enabled: false - redis: - host: __BK_REPO_REDIS_HOST__ - password: __BK_REPO_REDIS_ADMIN_PASSWORD__ - port: __BK_REPO_REDIS_PORT__ - -logging: - config: classpath:logback-config.xml - path: __BK_REPO_LOGS_DIR__ - -storage: - type: __BK_REPO_STORAGE_TYPE__ - filesystem: - path: __BK_REPO_FILE_PATH__ - innercos: - secretId: __BK_REPO_COS_SECRET_ID__ - secretKey: __BK_REPO_COS_SECRET_KEY__ - region: __BK_REPO_COS_REGION__ - bucket: __BK_REPO_COS_BUCKET__ - cache: - enabled: __BK_REPO_CACHE_ENABLE__ - path: __BK_REPO_CACHE_MOUNT_PATH__/cached - expireDays: __BK_REPO_CACHE_EXPIRE_DAY__ - loadCacheFirst: true - upload: - location: __BK_REPO_CACHE_MOUNT_PATH__/temp - -security: - auth: - enabled: true diff --git a/support-files/storage/templates/#etc#bkrepo#auth.yaml b/support-files/storage/templates/#etc#bkrepo#auth.yaml deleted file mode 100644 index 8ee0fc5e762..00000000000 --- a/support-files/storage/templates/#etc#bkrepo#auth.yaml +++ /dev/null @@ -1,27 +0,0 @@ -server: - port: __BK_REPO_AUTH_PORT__ - -auth: - realm: __BK_REPO_AUTH_REALM__ - iam: - callbackUser: __BK_REPO_IAM_CALLBACK_USER__ - systemId: __BK_REPO_APP_CODE__ - baseUrl: __BK_IAM_PRIVATE_URL__ - appCode: __BK_REPO_APP_CODE__ - appSecret: __BK_REPO_APP_TOKEN__ - devops: - envName: __BK_CI_AUTH_ENV__ - appId: bkdevops - appIdSet: bkdevops,bkrepo,codecc - authEnabled: true - allowAnonymous: true - ciAuthServer: __BK_CI_PUBLIC_URL__ - ciAuthToken: __BK_CI_AUTH_TOKEN__ - enableSuperAdmin: false - -esb: - code: __BK_REPO_APP_CODE__ - secret: __BK_REPO_APP_TOKEN__ - iam: - url: __BK_PAAS_PRIVATE_URL__ - diff --git a/support-files/storage/templates/#etc#bkrepo#docker.yaml b/support-files/storage/templates/#etc#bkrepo#docker.yaml deleted file mode 100644 index 6e578cadc31..00000000000 --- a/support-files/storage/templates/#etc#bkrepo#docker.yaml +++ /dev/null @@ -1,8 +0,0 @@ -server: - port: __BK_REPO_DOCKER_PORT__ - -auth: - url: http://__BK_REPO_HOST__/docker/v2/auth - -docker: - domain: __BK_REPO_DOCKER_HOST__ \ No newline at end of file diff --git a/support-files/storage/templates/#etc#bkrepo#generic.yaml b/support-files/storage/templates/#etc#bkrepo#generic.yaml deleted file mode 100644 index 501a1a81cc9..00000000000 --- a/support-files/storage/templates/#etc#bkrepo#generic.yaml +++ /dev/null @@ -1,4 +0,0 @@ -server: - port: __BK_REPO_GENERIC_PORT__ -generic: - host: http://__BK_REPO_HOST__/generic/ diff --git a/support-files/storage/templates/#etc#bkrepo#git.yaml b/support-files/storage/templates/#etc#bkrepo#git.yaml deleted file mode 100644 index 54355137ea0..00000000000 --- a/support-files/storage/templates/#etc#bkrepo#git.yaml +++ /dev/null @@ -1,2 +0,0 @@ -server: - port: __BK_REPO_GIT_PORT__ \ No newline at end of file diff --git a/support-files/storage/templates/#etc#bkrepo#helm.yaml b/support-files/storage/templates/#etc#bkrepo#helm.yaml deleted file mode 100644 index 12091eeb563..00000000000 --- a/support-files/storage/templates/#etc#bkrepo#helm.yaml +++ /dev/null @@ -1,5 +0,0 @@ -server: - port: __BK_REPO_HELM_PORT__ -helm: - registry: - domain: http://__BK_REPO_HOST__/helm/ \ No newline at end of file diff --git a/support-files/storage/templates/#etc#bkrepo#maven.yaml b/support-files/storage/templates/#etc#bkrepo#maven.yaml deleted file mode 100644 index 3e1439237f5..00000000000 --- a/support-files/storage/templates/#etc#bkrepo#maven.yaml +++ /dev/null @@ -1,2 +0,0 @@ -server: - port: __BK_REPO_MAVEN_PORT__ \ No newline at end of file diff --git a/support-files/storage/templates/#etc#bkrepo#npm.yaml b/support-files/storage/templates/#etc#bkrepo#npm.yaml deleted file mode 100644 index d713dca6236..00000000000 --- a/support-files/storage/templates/#etc#bkrepo#npm.yaml +++ /dev/null @@ -1,6 +0,0 @@ -server: - port: __BK_REPO_NPM_PORT__ - -npm: - tarball: - prefix: http://__BK_REPO_HOST__/npm/ \ No newline at end of file diff --git a/support-files/storage/templates/#etc#bkrepo#oci.yaml b/support-files/storage/templates/#etc#bkrepo#oci.yaml deleted file mode 100644 index 8d62d939574..00000000000 --- a/support-files/storage/templates/#etc#bkrepo#oci.yaml +++ /dev/null @@ -1,5 +0,0 @@ -server: - port: __BK_REPO_OCI_PORT__ - -oci: - domain: __BK_REPO_OCI_HOST__ diff --git a/support-files/storage/templates/#etc#bkrepo#opdata.yaml b/support-files/storage/templates/#etc#bkrepo#opdata.yaml deleted file mode 100644 index 9b7301dcad0..00000000000 --- a/support-files/storage/templates/#etc#bkrepo#opdata.yaml +++ /dev/null @@ -1,4 +0,0 @@ -op: - security: - admin-username: __BK_REPO_OP_ADMIN_USERNAME__ - admin-password: __BK_REPO_OP_ADMIN_PASSWORD__ \ No newline at end of file diff --git a/support-files/storage/templates/#etc#bkrepo#repository.yaml b/support-files/storage/templates/#etc#bkrepo#repository.yaml deleted file mode 100644 index d74fabe2aa0..00000000000 --- a/support-files/storage/templates/#etc#bkrepo#repository.yaml +++ /dev/null @@ -1,2 +0,0 @@ -server: - port: __BK_REPO_REPOSITORY_PORT__ diff --git a/support-files/storage/templates/#etc#bkrepo#scanner-executor.yaml b/support-files/storage/templates/#etc#bkrepo#scanner-executor.yaml deleted file mode 100644 index c96f866b8af..00000000000 --- a/support-files/storage/templates/#etc#bkrepo#scanner-executor.yaml +++ /dev/null @@ -1,9 +0,0 @@ -scanner: - executor: - work-dir: __BK_REPO_SCANNER_EXECUTOR_WORK_DIR__ - docker: - enabled: __BK_REPO_SCANNER_EXECUTOR_DOCKER_ENABLED__ - host: __BK_REPO_SCANNER_EXECUTOR_DOCKER_HOST__ - version: __BK_REPO_SCANNER_EXECUTOR_DOCKER_VERSION__ - connect-timeout: __BK_REPO_SCANNER_EXECUTOR_DOCKER_CONNECT_TIMEOUT__ - read-timeout: __BK_REPO_SCANNER_EXECUTOR_DOCKER_READ_TIMEOUT__ diff --git a/support-files/storage/templates/#etc#bkrepo#scanner.yaml b/support-files/storage/templates/#etc#bkrepo#scanner.yaml deleted file mode 100644 index c980eac5693..00000000000 --- a/support-files/storage/templates/#etc#bkrepo#scanner.yaml +++ /dev/null @@ -1,7 +0,0 @@ -scanner: - spring: - data: - mongodb: - uri: __BK_REPO_SCANNER_MONGODB_URI__ - transaction: - enabled: false diff --git a/support-files/storage/templates/gateway#lua#init.lua b/support-files/storage/templates/gateway#lua#init.lua deleted file mode 100644 index 4b493516682..00000000000 --- a/support-files/storage/templates/gateway#lua#init.lua +++ /dev/null @@ -1,64 +0,0 @@ ---[[ -Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. - -Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - -BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. - -A copy of the MIT License is included in this file. - - -Terms of the MIT License: ---------------------------------------------------- -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -]] - -config = { - static_dir = "__BK_REPO_HOME__/frontend", - home_dir = "__BK_REPO_HOME__", - service_name = "__BK_REPO_SERVICE_NAME__", -- 指定后台微服务名称,如果对接后端是boot-assembly的单体微服务,则该配置项为bk-ci, 否则请置空会自动路由相应微服务 - service_prefix = "__BK_REPO_SERVICE_PREFIX__", -- 微服务前缀 - allow_hosts = { - "__BK_REPO_GATEWAY_CORS_ALLOW_LIST__" - }, - allow_headers = "Authorization,Content-Type,withcredentials,credentials,Accept,Origin,User-Agent,Cache-Control,Keep-Alive,X-Requested-With,If-Modified-Since,X-CSRFToken,X-DEVOPS-PROJECT-ID,X-DEVOPS-TASK-ID,X-BKREPO-UID,X-BKREPO-API-TYPE", - ns = { - ip = { - "__BK_REPO_CONSUL_DNS_HOST__" - }, - port = "__BK_REPO_CONSUL_DNS_PORT__", - http_port = "__BK_REPO_CONSUL_SERVER_PORT__", - domain = "__BK_REPO_CONSUL_DOMAIN__", - tag = "__BK_REPO_CONSUL_TAG__", - nodes_url = "/v1/catalog/nodes" - }, - oauth = { -- 对接蓝鲸权限中心才需要的配置 - ip = "__BK_REPO_SSM_IP0__", - env = "__BK_REPO_SSM_ENV__", - port = "__BK_REPO_SSM_HTTP_PORT__", - host = "__BK_REPO_SSM_HOST__", - url = "__BK_REPO_SSM_TOKEN_URL__", -- 接口路径 - app_code = "__BK_REPO_APP_CODE__", - app_secret = "__BK_REPO_APP_TOKEN__", - }, - bkrepo = { - authorization = "__BK_REPO_AUTHORIZATION__", - domain = "__BK_REPO_DOMAIN__" - }, - mode = "__BK_REPO_DEPLOY_MODE__", - router = { - project = { - { - name = "devops", - tag = "devops" - } - } - } -} - -require("init_common") -require("ip_whitelist") diff --git a/support-files/storage/templates/gateway#server.common.conf b/support-files/storage/templates/gateway#server.common.conf deleted file mode 100644 index 7052cf04e04..00000000000 --- a/support-files/storage/templates/gateway#server.common.conf +++ /dev/null @@ -1,26 +0,0 @@ - # 前端静态资源 - root $static_dir; - index index.html index.htm; - - client_max_body_size 0; - - if ($time_iso8601 ~ '(\d{4}-\d{2}-\d{2})') { - set $log_date $1; - } - - #dns指向本地的consul dns服务 - resolver __BK_REPO_GATEWAY_DNS_ADDR__ valid=30s; - - #设置通用变量 - include set.conf; - - #将错误统一处理成json格式返回 - include error/error.html.handler.conf; - include error/error.json.handler.conf; - include error/error.json.conf; - - #状态监测 - include nginx.status.conf; - - #网关auth验证 - include auth.conf; \ No newline at end of file diff --git a/support-files/storage/templates/gateway#vhosts#bkrepo.docker.server.conf b/support-files/storage/templates/gateway#vhosts#bkrepo.docker.server.conf deleted file mode 100644 index 5ad49efc053..00000000000 --- a/support-files/storage/templates/gateway#vhosts#bkrepo.docker.server.conf +++ /dev/null @@ -1,43 +0,0 @@ -server { - listen __BK_REPO_DOCKER_HTTP_PORT__; - listen [::]:__BK_REPO_DOCKER_HTTP_PORT__; - #listen __BK_REPO_DOCKER_HTTPS_PORT__ ssl; - server_name "__BK_REPO_DOCKER_HOST__"; - - #ssl_certificate __BK_REPO_DOCKER_CERT_PEM__; - #ssl_certificate_key __BK_REPO_DOCKER_CERT_KEY__; - - if ($http_x_forwarded_proto = '') { - set $http_x_forwarded_proto $scheme; - } - chunked_transfer_encoding on; - - access_log __BK_REPO_LOGS_DIR__/nginx/bkrepo.docker.access.$log_date.log devops_format; - error_log __BK_REPO_LOGS_DIR__/nginx/bkrepo.docker.error.log; - - set_by_lua $name_space 'return os.getenv("NAMESPACE")'; - - # server的通用配置 - include server.common.conf; - - # 构建机层服务分发 - location / { - set $service "docker"; - set $target ''; - proxy_read_timeout 900; - access_by_lua_file 'conf/lua/router_srv.lua'; - - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Port $server_port; - proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; - proxy_set_header Host $http_host; - proxy_http_version 1.1; - # 反向代理到目标ip,端口,路径和参数 - if ( $assembly ){ - proxy_pass http://$target$request_uri; - break; - } - proxy_pass http://$target; - } -} diff --git a/support-files/storage/templates/gateway#vhosts#bkrepo.helm.server.conf b/support-files/storage/templates/gateway#vhosts#bkrepo.helm.server.conf deleted file mode 100644 index dda9d41d762..00000000000 --- a/support-files/storage/templates/gateway#vhosts#bkrepo.helm.server.conf +++ /dev/null @@ -1,35 +0,0 @@ -server { - listen __BK_REPO_HELM_HTTP_PORT__; - listen [::]:__BK_REPO_HELM_HTTP_PORT__; - server_name "__BK_REPO_HELM_HOST__"; - - if ($http_x_forwarded_proto = '') { - set $http_x_forwarded_proto $scheme; - } - chunked_transfer_encoding on; - - access_log __BK_REPO_LOGS_DIR__/nginx/bkrepo.helm.access.$log_date.log devops_format; - error_log __BK_REPO_LOGS_DIR__/nginx/bkrepo.helm.error.log; - - set_by_lua $name_space 'return os.getenv("NAMESPACE")'; - - # server的通用配置 - include server.common.conf; - - # 构建机层服务分发 - location / { - set $service "helm"; - set $target ''; - proxy_read_timeout 900; - access_by_lua_file 'conf/lua/router_srv.lua'; - - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Port $server_port; - proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; - proxy_set_header Host $http_host; - proxy_http_version 1.1; - # 反向代理到目标ip,端口,路径和参数 - proxy_pass http://$target; - } -} diff --git a/support-files/storage/templates/gateway#vhosts#bkrepo.server.conf b/support-files/storage/templates/gateway#vhosts#bkrepo.server.conf deleted file mode 100644 index b21ab30f377..00000000000 --- a/support-files/storage/templates/gateway#vhosts#bkrepo.server.conf +++ /dev/null @@ -1,46 +0,0 @@ -server { - listen __BK_REPO_HTTP_PORT__ ; - listen [::]:__BK_REPO_HTTP_PORT__; - server_name "__BK_REPO_HOST__"; - - listen 8081; - listen [::]:8081; -# ### ssl config begin ### -# listen __BK_REPO_HTTPS_PORT__ ssl; -# ssl_certificate __BK_REPO_CERT_PEM__; -# ssl_certificate_key __BK_REPO_CERT_KEY__; -# ssl_protocols TLSv1 TLSv1.1 TLSv1.2; -# ssl_prefer_server_ciphers on; -# ssl_session_cache shared:SSL:10m; -# ssl_session_timeout 10m; -# ssl_ciphers HIGH:!aNULL:!MD5; -# include devops.ssl; -# # force https-redirects -# # if ($scheme = http) { -# # return 301 https://$server_name$request_uri; -# # } -# ### ssl config end ### - - access_log __BK_REPO_LOGS_DIR__/nginx/bkrepo.access.$log_date.log devops_format; - error_log __BK_REPO_LOGS_DIR__/nginx/bkrepo.error.log; - - set_by_lua $name_space 'return os.getenv("NAMESPACE")'; - - # server的通用配置 - include server.common.conf; - - # 网络测速路径 - include vhosts/bkrepo.speedtest.conf; - - # 静态资源网关路径 - include vhosts/bkrepo.ui.conf; - - # 运营管理后台静态资源网关路径 - include vhosts/bkrepo.op.conf; - - # web接口网关路径 - include vhosts/bkrepo.web.conf; - - # 后台的网关路径 - include vhosts/bkrepo.backend.conf; -}