Habaform——用类似 IaC(Infrastructure as code) + GitOps 的方式管理 Harbor 的 Project 和 User
作为 Harbor 的用户,我们知道:
If you create user accounts in the Harbor database, Harbor is locked in database mode. You cannot change to a different authentication mode after you have created local users.
Harbor 的用户验证有三种方式,分别叫做:
- Database Authentication
- LDAP/Active Directory Authentication
- OIDC Provider Authentication
由于我个人需要在纯内网环境下使用 Harbor ,加上没有 LDAP 的加持,自然只有一个 「Database Authentication」可以选,由于每用户都是独立的帐号,每个帐号都有自己所属的 Project,也有一些共用的 Project 多个人共用,管理起来的成本非常大,不过好在现在已经从之前的「无文档,无记录」,升级成了用一个 Google Sheet 来记录所有的 Project,类似这样:
这样看上去直观了不少,至少有了一个统一的地方可以看到每个 Project 的所有人/用途和 GC Policy。
但是这是一个 xls,不是一个 exe,它只能用来记录,需要人工同时维护表格和 Harbor(手动点点点),容易出现表格和实际的数据不一致的情况,鉴于此,我们可以继续深入改进一下,用类似 IaC 的方式来管理 Harbor 的 Project 和 Users。
于是我造了一个方形的轮子,叫 Habaform.
Habaform
Habaform 名称来源:Haba(Harbor)-form(Terraform).
GitHub 地址:https://github.com/n0vad3v/habaform
Usage
当使用 pip3 install habaform
安装了之后,我们来看看 Habaform 怎么玩。
Init Habaform
对于一个船新的 Habaform 管理的 Harbor,我们可以通过 habaform parse
来获得一份 habaform_file
,用法如下(首先需要 export HARBOR 的登录信息),比如:
export HARBOR_USERNAME="admin"
export HARBOR_PASSWORD="Harbor12345"
export HARBOR_URL="http://hub.nova.moe"
然后就可以开始解析目前的 Harbor 结构了,先创建一个目录用来存放这些信息:
habaform parse
此时,当前目录下会出现一个目录和一个文件,类似这样:
.
├── DO_NOT_TOUCH
│ └── habaform.hf
└── habaform.hf
1 directory, 2 files
此时两个 habaform.hf
文件内容完全一致,文件内容类似如下:
habaformVersion: 1
projects:
- civic:
members:
- admin(projectAdmin)
- honda:
members:
- admin(projectAdmin)
- pingcap(developer)
- library:
members:
- admin(projectAdmin)
- novakwok:
members:
- admin(projectAdmin)
保持这个样子,可以直接丢到一个 GitHub 仓库上。
GitOps
有了一个中心化的 GitHub 仓库之后,我们可以开始配置 GitHub Action 来完成 GitOps,比如我们希望在代码合并的时候自动 habaform plan
来判断这一次合并会造成的更改,虽然是内网环境,但是由于已经有大量的 Self-hosted Runner 的部署在,我们依然可以使用 GitHub Actions 来完成这一系列内网操作(你也想要 Self-hosted Runner?来看看「在 Kubernetes 上运行 GitHub Actions Self-hosted Runner」这篇文章吧~),关键代码如下:
name: Plan Habaform
on: [pull_request]
jobs:
Plan:
runs-on: [self-hosted,X64]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Setup Habaform
run: |
pip3 install habaform
- name: Plan
id: plan
env:
HARBOR_USERNAME: ${{secrets.HARBOR_USERNAME}}
HARBOR_PASSWORD: ${{secrets.HARBOR_PASSWORD}}
HARBOR_URL: ${{secrets.HARBOR_URL}}
run: |
echo 'HABAPLAN<<EOF' >> $GITHUB_ENV
habaform plan >> $GITHUB_ENV
echo 'EOF' >> $GITHUB_ENV
- name: Preview Plan info
uses: actions/github-script@v4
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
github.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `${{ env.HABAPLAN }}`
})
对于没有问题的 PR,合并后需要自动 Apply 到实际的 Harbor 上,我们再准备一个 Action 来做这个事情,关键代码如下:
name: Apply Habaform
on:
push:
branches: [ master ]
paths:
- 'habaform.hf'
jobs:
Apply:
runs-on: [self-hosted,X64]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Setup Habaform
run: |
pip3 install habaform
- name: Apply
id: apply
env:
HARBOR_USERNAME: ${{secrets.HARBOR_USERNAME}}
HARBOR_PASSWORD: ${{secrets.HARBOR_PASSWORD}}
HARBOR_URL: ${{secrets.HARBOR_URL}}
run: |
habaform apply
- name: Sync config
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add .
git commit -m "Sync hf file"
git push
Workflow
有了上述准备后,我们来看看一个典型的 Workflow,~~由于手上没有测试环境,我们直接用生产环境的库来测试好了~~~
- 首先,我们遇到了需要针对 Project 的修改,比如要删除 pingcap 这个 Project,这个时候,我们只需要提交一个 PR,内容是在
habaform.hf
中直接删除 pingcap 的部分,像这样:
提交 PR 之后 GitHub Actions 就会自动将这次变更的效果给 Preview 出来并 Comment 到 PR 的 Issue 上,类似这样:
如果感觉没问题(Preview 符合预期),那么就可以直接合并 PR,在合并之后,由于 habaform.hf
文件有修改,会触发 Apply Habaform 这个 GitHub Action 任务,任务会自动把修改的内容 Apply 到实际的 Harbor 上,并同步两个 habaform.hf
文件。
虽然很简陋,不过,这样就完成了~
当然,Habaform 不简单局限于增/删 Project,它还可以直接管理 Project 的成员信息,只要直接修改 habaform.hf
即可,对于成员的 Role 来说,只需要在括号内申明就可以了,可用的 Role 信息如下:
- projectAdmin
- maintainer
- developer
- guest
- limitedGuest
以上,在有了 Habaform 之后,我们可以让 Habaform 来管理我们的 Harbor 的 Project/User 关系了。
Miscs
Habaform Feature
- IaC 管理 Harbor 的 Project-User,后期会考虑加入更多功能
- 对于 Delete Project 操作而言,会递归删除 Project 下所有 repo 之后删除 Project
Potential Bugs
- 由于没有类似 Terraform 的 S3 Backend,基于
DO_NOT_TOUCH/habaform.hf
作为 Trusted Source 可能会在多个 PR 同时进行的时候遇到问题 - 可能还会有些我不知道的 Bug,最坏情况是 Habaform 文件和 Harbor 实际结构不一致(比如 Habaform 上删除了 Project 但是 Harbor 上并没有成功删除之类的),此外,使用时请在 apply 前仔细阅读 plan 的内容