作者:孙健 孙健,爱可生研发工程师,负责SQLE相关开发; 本文来源:原创投稿 爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。前言 近些年来,数据库产业发展迅猛,各种新兴数据库如雨后春笋般出现,各个公司的技术栈也不再局限于某一种数据库。对于SQL质量管理平台来说仅支持某一个类型的数据库(例如MySQL),那么是会有一定的局限性,SQLE在设计之初考虑支持多种数据库,因此产品设计时,将审核流程(业务)的代码和具体SQL审核上线的代码进行分离,SQL审核上线通过插件的形式实现。SQLE对外提供插件开发所需的接口和库,可以快速创建开启一个审核插件,无需升级软件,导入审核插件即可获对应数据库类型的审核上线能力,使用平台所有功能。 插件的开发参考文档:https:actiontech。github。iosqledocscn3。modules3。7auditpluginauditplugindevelopment。html, 插件的使用参考文档:https:actiontech。github。iosqledocscn3。modules3。7auditpluginauditpluginmanagement。html。 本文将演示如何从零开始创建一个简单可用的审核插件,作为案例。目标 首先将创建一个Postgres数据库审核插件,并添加两条规则,禁止使用SELECT和创建的表字段过多,并在开发过程中结合SQLE对Postgres数据库进行SQL审核上线工单的测试演示。以下过程中的演示代码可从此处https:github。comactiontechsqletreemainexampledbplugin下载。实操 提示:SQLE和插件为GO语言开发,如果要进行插件开发,需要对GO有一丢丢了解即可。1。创建插件项目 首先使用gomod初始化一个go项目,然后mkdirsqlepgplugincdsqlepgplugintouchmain。gogomodinitsqlepgplugin初始化gomodexportGOPROXYgoproxy。cn,goproxy。io,direct设置GoProxy,解决SQLE库下载问题,通过IDEA开发的可以在IDEA软件上设置;gogetgithub。comactiontechsqlev1。2204。0此版本为该文章编辑时的最新版本。2。编写最小化插件代码 在项目main。go文件内编写如下代码,即可最快的添加一个Postgres数据库审核插件,此时插件没有审核规则。packagemainimport(adaptorgithub。comactiontechsqlesqlepkgdriver)funcmain(){plugin:adaptor。NewAdaptor(adaptor。PostgresDialector{})plugin。Serve()} 使用‘gobuild‘编译后得到二进制文件sqlepgplugin,按前言中的插件的使用参考文档,我们部署到SQLE服务里。可以正常添加数据源,如下图所示: 此时正常进行SQL审核上线工单创建并上线,如下图所示: 3。给插件添加一条规则 在刚刚代码的基础上,我们在main函数内添加如下代码来新增一条规则禁止使用SELECT,完整代码如下所示。packagemainimport(contextstringsgithub。comactiontechsqlesqledriveradaptorgithub。comactiontechsqlesqlepkgdriver)funcmain(){plugin:adaptor。NewAdaptor(adaptor。PostgresDialector{})rule1:driver。Rule{Name:pgrule1,规则ID,该值会与插件类型一起作为这条规则在SQLE的唯一标识Desc:禁止使用SELECT,规则描述Category:DQL规范,规则分类,用于分组,相同类型的规则会在SQLE的页面上展示在一起Level:driver。RuleLevelError,规则等级,表示该规则的严重程度}rule1Handler:func(ctxcontext。Context,ruledriver。Rule,sqlstring)(string,error){ifstrings。Contains(sql,select){returnrule。Desc,nil}return,nil}plugin。AddRule(rule1,rule1Handler)plugin。Serve()} 我们按之前的方式编译插件二进制文件,并部署到SQLEserver内,可以看到新增了一条规则,如下图所示: 此时我们提交一个工单验证一下,可以看到触发了我们刚添加的规则 4。给插件添加一条可配置的复杂规则 基于上面的代码,我们再添加一条规则创建的表字段过多,具备如下特性:上面添加的规则基于字符串匹配进行的,准确性不高,无法匹配到不同的书写格式,比如大小写,换行等。因此我们在这里会基于SQL解析器开发一条规则,测试使用的解析库https:github。compganalyzepgquerygo;为了增加规则的适用性,我们准备给规则加一个动态配置给用户提供可选项。 代码如下:packagemainimport(contextfmtstringsgithub。comactiontechsqlesqledriveradaptorgithub。comactiontechsqlesqlepkgdrivergithub。comactiontechsqlesqlepkgparamsparsergithub。compganalyzepgquerygov2)funcmain(){plugin:adaptor。NewAdaptor(adaptor。PostgresDialector{})rule1:driver。Rule{Name:pgrule1,规则ID,该值会与插件类型一起作为这条规则在SQLE的唯一标识Desc:避免查询所有的列,规则描述Category:DQL规范,规则分类,用于分组,相同类型的规则会在SQLE的页面上展示在一起Level:driver。RuleLevelError,规则等级,表示该规则的严重程度}rule1Handler:func(ctxcontext。Context,ruledriver。Rule,sqlstring)(string,error){ifstrings。Contains(sql,select){returnrule。Desc,nil}return,nil}定义第二条规则rule2:driver。Rule{Name:pgrule2,Desc:表字段不建议过多,Level:driver。RuleLevelWarn,Category:DDL规范,Params:〔〕params。Param{自定义参数列表ms。Param{Key:maxcolumncount,自定义参数的IDValue:50,自定义参数的默认值Desc:最大字段个数,自定义参数在页面上的描述Type:params。ParamTypeInt,自定义参数的值类型},},}这时处理函数的参数是interface{}类型,需要将其断言成AST语法树。rule2Handler:func(ctxcontext。Context,ruledriver。Rule,astinterface{})(string,error){node,ok:ast。(parser。RawStmt)if!ok{return,nil}switchstmt:node。GetStmt()。GetNode()。(type){caseparser。NodeCreateStmt:columnCounter:0for,elt:rangestmt。CreateStmt。TableElts{switchelt。GetNode()。(type){caseparser。NodeColumnDef:columnCounter}}读取SQLE传递过来的该参数配置的值count:rule。Params。GetParam(maxcolumncount)。Int()ifcount0columnCountercount{returnfmt。Sprintf(表字段不建议超过d个,目前有d个,count,columnCounter),nil}}return,nil}plugin。AddRule(rule1,rule1Handler)plugin。AddRuleWithSQLParser(rule2,rule2Handler)需要将SQL解析的方法注册到插件中。plugin。Serve(adaptor。WithSQLParser(func(sqlstring)(astinterface{},errerror){parser。Parse使用PostgreSQL的解析器,将sql解析成AST语法树。result,err:parser。Parse(sql)iferr!nil{returnnil,fmt。Errorf(parsesqlerror)}iflen(result。Stmts)!1{returnnil,fmt。Errorf(unexpectedstatementcount:d,len(result。Stmts))}将SQL的语法树返回。returnresult。Stmts〔0〕,nil}))plugin。Serve()} 打开SQLE规则界面,可以看到该规则已经添加到SQLE了,如图: 我们将规则模板内该规则的值调小点然后进行测试一下 首先我们提交一条超过5个字段的建表语句,此时SQLE会触发该规则并给出预期的提示信息,如下图所示: 然后我们提交一条不超过5个字段的建表语句,此时SQLE不会触发该规则,如下图所示: 总结 通过上面的演示,大概介绍了SQLE数据库审核插件的简单开发测试过程。大家可根据类似步骤开发出一套符合自己公司需求的规则集,结合SQLE平台来满足日常使用。我们也提供了一些常见数据库的审核插件,大家也可以在此基础上进行开发,参考文档:https:actiontech。github。iosqledocscn3。modules3。7auditpluginoverview。html