直入正题:我们在落地 Zadig 的过程中,发现项目初始化时有很多重复性配置工作,比如说同一类 java 服务构建部署中构建过程 90%都是重复的,要一个个手动创建过去;通过 Zadig 里的“项目”区分一个业务线的多个环境的话,每个环境中的服务也要一个个创建,哪怕是通过模板导入,也是一个不小的工作量。这里我们分享一下我们通过自动化脚本来降低这部分工作量的做法,抛砖引玉,仅用于为大家提供一个参考思路~
一、思路
Zadig 自身有丰富的 API 接口用于外部调用,通过 API Token 实现认证; 在此基础上,我们可以通过浏览器调试模式获取相关功能接口地址和请求参数,要实现批量操作,只需要自己拼装 HTTP 请求,循环调用相关接口即可。我们以通过脚本批量为用户授权这个场景为例说明整个过程。
以下实现过程还存在较大优化空间,比如说手动创建用户列表配置文件仍较难维护且容易出错,使用 shell 开发不利于后期功能扩展等。
二、场景说明
- 集成了 ldap 用于用户管理,初始化完一个项目后需要给所有的研发和测试人员分配相应权限;
- 完成 Zadig 部署(v1.10.0+)并集成 ldap、创建好项目、在项目中提前创建好角色(此处以 developer 和 tester 两个角色组分别代表研发和测试人员为例)
- 假设操作的项目名为 demo-qa
三、前期准备
- 获取 API Token:参考官方文档:API 调用说明
- 获取接口地址和参数:
- 浏览器登录 Zadig,导航到:demo-qa 项目 » 配置 » 权限 页面,打开浏览器调试模式(Chrome 快捷键为 F12),点击“添加成员”按钮;
- 点击调试调试工具中的 Clear 按钮清空控制台,点击 Fetch/XHR 过滤指定类型请求(去除干扰项),如图 1:
- 在弹出的选择框中下拉选择用户名称和角色名称,点击“确定”按钮,观察调试工具窗口里的输出,如图 2:可以看到,我们页面执行为一个用户分配权限的动作,Zadig 控制台和服务端两个接口发生了交互,简单分辨一下可以看出来,第一个是我们需要的功能接口,第二个其实是操作完成后页面刷新加载新的页面内容用的(有个简单的判断办法,根据调试工具右侧的
Response
来判断,这是接口响应的具体内容,一般来讲内容为:{"message":"success"}
的就是我们需要用的接口),鼠标右键点击这个接口,如图以此展开 Copy » Copy as cURL(bash),将复制到的内容粘贴到文本编辑器里,得到如下内容:
# 将ldap账户绑定角色
curl 'http://<Your Zadig Address>/api/v1/rolebindings?projectName=<Your Project Name>&bulk=true' \
-H 'Connection: keep-alive' \
-H 'Accept: application/json, text/plain, */*' \
-H 'DNT: 1' \
-H 'Authorization: Bearer <Your Bearer>' \
-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36' \
-H 'Content-Type: application/json;charset=UTF-8' \
-H 'Origin: http://<Your Zadig Address>' \
-H 'Referer: http://<Your Zadig Address>/v1/projects/detail/<Your Project Name>/rbac' \
-H 'Accept-Language: zh-CN,zh;q=0.9,en;q=0.8' \
--data-raw '[{"uid":"e3521a93-a123-11ec-123a-86c0dc7647f5","role":"developer","preset":false,"type":"custom"}]' \
--compressed \
--insecure
其中的 http://<Your Zadig Address>/api/v1/rolebindings?projectName=<Your Project Name>&bulk=true
就是为用户绑定角色的接口地址, --data-raw
就是调用这个接口需要传递的表单参数,我们简单分析一下参数内容就能发现,其中有两个关键的属性:uid
和 role
,一个是用户 id,一个是角色名,那接下来我们就需要获取需要授权的用户的 id,因为当前页面就会加载用户列表,所以我们直接刷新当前页面,在调试工具中找一找,可以发现,search 接口就返回了所有的用户信息,如图 3:,我们拷贝 Response
里的响应内容到文件编辑器中备用,样例:
{
"users": [
{
"lastLoginTime": 1646994537,
"uid": "786f514f-8b0a-11ec-ba40-bea187f93886",
"name": "",
"identity_type": "ldap",
"email": "",
"phone": "",
"account": "",
"token": ""
},
{
"lastLoginTime": 1646993873,
"uid": "e3949fd2-a123-22ec-837a-86c0dc7647f5",
"name": "小明",
"identity_type": "ldap",
"email": "xiaoming@demo.com",
"phone": "",
"account": "xiaoming",
"token": ""
},
{
"lastLoginTime": 1646993873,
"uid": "dafea9fd2-a123-11ec-837a-86c0dc7647f5",
"name": "小亮",
"identity_type": "ldap",
"email": "xiaolaing@demo.com",
"phone": "",
"account": "xiaoming",
"token": ""
}
],
"totalCount": 2
}
结合场景简单分析一下,对我们有用的属性有俩:一个是 uid
,就是上文中提到的用户 id;另外一个是 name
,这个和 uid 是一一对应的,我么那后续接口调用的时候用不到,仅用做我们手写配置文件的时候肉眼区分用户;
四、脚本开发
需求很小,shell 最方便,如果考虑维护性和规范性,建议使用 Python 或者 Golang。
这里我们使用 shell 开发,原理就是通过:配置 + 模板组装 HTTP 请求,通过 curl 执行;根据上面已经掌握的信息,先写一个 http 请求模板,命名为 curl_rbac_bind.tpl
,内容(注意替换
curl 'http://<Your Zadig Address>/api/v1/rolebindings?projectName=${project_name}&bulk=true' \
-H 'Connection: keep-alive' \
-H 'Accept: application/json, text/plain, */*' \
-H 'DNT: 1' \
-H 'Authorization: Bearer ${auth_bearer}' \
-H 'Content-Type: application/json;charset=UTF-8' \
-H 'Origin: http://zadig.demo.com' \
-H 'Referer: http://<Your Zadig Address>/v1/projects/detail/${project_name}/rbac' \
-H 'Accept-Language: zh-CN,zh;q=0.9,en;q=0.8' \
--data '[{"uid":"${user_uuid}","role":"${user_role}","preset":false,"type":"custom"}]' \
--compressed \
--insecure
然后写一个配置文件,分三列,依次为 uid、用户名、角色名,命名为:ldap-user-list.txt
,内容为:
9414a55a-a22d-11ec-837a-86c0dc7647f5 小明 developer
9414a55a-a22d-11ec-837a-86c0dc7647f5 小亮 developer
e32dd191-a321-11ec-837a-86c0dc7647f5 小红 tester
e3d6c003-a321-11ec-837a-86c0dc7647f5 小黄 tester
最后写一个主程序,名为 do_bind.bash
,这里项目名和 Token 是写死的,没有参数化,注意替换,内容为:
#!/bin/bash
export project_name="demo-qa"
export auth_bearer="aaabbbcccddd"
mkdir -p create_bind
cat ldap-user-list.txt | while read line
do
export user_uuid=`echo $line | awk -F ' ' '{print $1}'`
user_name=`echo $line | awk -F ' ' '{print $2}'`
export user_role=`echo $line | awk -F ' ' '{print $3}'`
echo "do with ${user_name}..."
envsubst < curl_rbac_bind.tpl > create_bind/${user_uuid}.bash
cat create_bind/${user_uuid}.bash | bash
sleep 1
done
整体文件结构(假设执行目录为 script):
---script
|---ldap-user-list.txt
|---curl_rbac_bind.tpl
|---do_bind.bash
五、使用
确认配置和脚本语法无误后在 bash 会话中执行命令:sh do_bind.bash
,顺利执行完后刷新项目权力管理页面查看效果。
其他批量操作的需求也可以通过类似思路实现,实现服务、构建等的批量创建删除等,我们也有类似的脚本,但是目前处在能用的阶段,并没有很完善,后续改进下再跟大家分享。