背景介绍
公司要求打通大数据各个服务的用户管理,包含有自主开发的数据治理平台、公司管理的员工用户管理系统、大数据各组件的用户。做到一站式新建、删除、更改等灵活管理。我负责改造hue的用户、角色、权限管理。Hue是一个开源的Apache Hadoop UI系统,可供用户进行数据查询等功能。
本人之前未接触过python,本次开发之前也没抱多大期望,但是通过1个月的学习摸索,终于上线,也算有了个好结果。我记录一下开发期间疑难问题,总结本次开发经验,也希望能帮到大家。
开发过程
1. hue项目编译
1.1 编译环境
意识到hue只支持在linux下编译,我准备了ubantu 22.04虚拟机,切换镜像源这里不赘述。
虚拟机自带python3.10,经实验不能编译(未找到原因),重新安装python3.8(不要卸载python3.10,不然会造成ubantu系统崩溃)。
#安装python3.8
sudo apt install python3.8 python3.8-dev python3.8-distutils python3.8-venv
#安装pip3.8
wget -O /tmp/get-pip.py https://bootstrap.pypa.io/get-pip.py
python3.8 /tmp/get-pip.py
#安装hue依赖
sudo apt-get update -y && apt-get install -y python3-pip libkrb5-dev libsasl2-modules-gssapi-mit libsasl2-dev libkrb5-dev krb5-config krb5-user libxml2-dev libxslt-dev libmysqlclient-dev libldap2-dev libsnappy-dev python3.8-venv python3.8-dev python3.8-distutils rsync curl sudo git
#安装Django
pip3.8 install django
#编译hue
export PYTHON_VER=python3.8
export ROOT=/home/wjr/workpace/hue #hue 根目录
cd /home/wjr/workpace/hue #hue 根目录
make apps #编译
以上脚本大概率会成功编译完成,失败也是小问题。
2.代码改造
2.1 新建模块
Hue使用virtualenv隔离和管理python依赖包。为了不污染hue源码,我决定新建一个app模块。
./build/env/bin/hue create_desktop_app appName
./build/env/bin/python tools/app_reg/app_reg.py --install appName
在新建的app编写自己的代码逻辑与api接口
2.2 为其他服务提供api接口
管理api的url路径是否需要Authentication检验的py文件在desktop/core/src/desktop/middleware.py,在 class LoginAndPermissionMiddleware 下process_view方法中有白名单。返回None,即可表示毋须校验。
if request.path in ['/xxx/xxx/','/xxx/xxxx/']:
return None
3. CICD
在hue源码中找到了DockerFile,文件路径:tools/docker/hue/DcokerFile。
可以直接用该DockerFile,如果出现错误,极有可能是网络问题。试试更换pip源即可解决,也包括github上的包下不了改为gitee。
4. 源码BUG
开发过程中碰到一个BUG,只在python3.8环境下出现。具体情况如下:
在调用sentryApi时出现类型转换问题,在调用api参数转换时,出现URI参数时,进行了encode操作,使原来的string变为了bytes型,才出现错误。
我是这样修改的:
在apps/security/src/security/api/hive.py中
def _to_sentry_privilege(privilege):
return {
'privilegeScope': privilege['privilegeScope'],
'serverName': privilege['serverName'],
'dbName': privilege['dbName'],
'tableName': privilege['tableName'],
'columnName': privilege['columnName'],
'URI': _massage_uri(privilege['URI'].encode('utf-8')),
'action': privilege['action'],
'createTime': privilege['timestamp'],
'grantOption': 1 if privilege['grantOption'] else 0,
}
def _hive_add_privileges(user, role, privileges):
api = get_api(user)
_privileges = []
for privilege in privileges:
if privilege['status'] not in ('deleted',):
api.alter_sentry_role_grant_privilege(role['name'], _to_sentry_privilege(privilege))
# Mocked until Sentry API returns the info. Not used currently as we refresh the whole role.
_privileges.append({
'timestamp': int(time.time()),
'database': privilege.get('dbName'),
'action': privilege.get('action'),
'scope': privilege.get('privilegeScope'),
'table': privilege.get('tableName'),
'column': privilege.get('columnName'),
# 'URI': privilege.get('URI').encode('utf-8'),
'URI': privilege.get('URI'),
'server': privilege.get('serverName'),
'grantOption': privilege.get('grantOption') == 1
})
return _privileges
去掉了其中的“.encode('utf-8')”,问题解决,不知道合不合理,暂时解决吧。