作者:蔡传旺

前端工程师,负责写写页面并改改bug,岂不快哉;

本文来源:原创投稿

*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。


一、SQLE 介绍

SQLE 是一款由爱可生开源社区发起,面向数据库开发与管理人员,实现了 SQL 的「开发」-「测试」-「上线」等全流程覆盖,资源与权限精细化管理,兼顾简洁与高效,易维护、易扩展的的开源项目,旨在为用户提供一套安全可靠、自主可控的 SQL 质量管控方案。

二、功能介绍

智能扫描任务是我们可以使用一系列的方式调用 sqle 的 openAPI ,将数据传输到 sqle 上进行扫描审核的功能,我们可以从数据库中传输建库建表语句审核、可以将慢日志传输到 sqle ,由 sqle 解析扫描 sql 、也可以将 Mybatis 传输到 sqle 中扫描解析其中的 sql ,所以 sqle 的智能扫描任务是非常强大的,那智能扫描能解析那些数据呢?

三、如何使用扫描任务的 OpenAPI

介绍扫描任务的 OpenAPI

智能扫描就是我们可用首先定义一个扫描任务,这个任务是针对某个特定的数据路类型,比如 MySQL ,同时我们也会设置任务的执行周期,只要时间一到,sqle 就会自动执行这个扫描任务,刚接触 sqle 的小伙伴可能比较懵,这个扫描任务创建了,但是没有内容,是我使用的方式不对吗?其实不然,sqle 开放了相应的 OpenAPI 接口,我们可以调用 OpenAPI 来将我们要审核的语句发送给 sqle 中相应的任务。那这个 OpenAPI 在哪里?怎么使用这个 OpenAPI 呢?

首先在你按照官方文档的搭建方式(https://actiontech.github.io/sqle-docs-cn/2.deploy/overview.html)搭建了一个 sqle 后,我们访问http://${your address}:10000/swagger/index.html就会得到一个 swagger 文档,我们在其中可以找到下图的两个 api ,而这两个 api 就是我们可以直接将 sql 语句传给扫描任务的 OpenAPI 。

使用方法

  1. 比如我在环境中创建了一个自定义类型的扫描任务

这样我就得到了这个扫描任务,在任务中我定义了任务类型、审核周期、数据库等,得到了一个访问凭证,这个访问凭证就是我们使用 OpenAPI 访问扫描任务中需要使用到的 token 。

  1. 使用类似postman的工具,开启一个post请求,这里的zidingyi是动态参数,你要改成你的扫描任务的名称即可

请求的 header 是

Content-Typeapplication/json
Authorization该扫描任务的访问凭证

请求的 body 是

 {"audit_plan_sql_list": [
     {
       "audit_plan_sql_counter": "1", #匹配到该指纹的语句数量
       "audit_plan_sql_fingerprint": "select * from users where id  = ?", #SQL指纹
       "audit_plan_sql_last_receive_text": "select * from users where id = 1", #最后一次匹配到该指纹的语句
       "audit_plan_sql_last_receive_timestamp": "2022-08-23T19:30:46.00Z", #最后一次匹配到该指纹的时间(RFC3339格式)
       "audit_plan_sql_schema": "db1" #还不知道
    }
  ]
}
  1. 经过发送后就可以在该扫描任务的详情页面看到你的sql

在这个任务到达审核时间,就会自动审核该任务并反馈审核结果

  1. 这两个接口分为全量同步和增量同步,全量同步会覆盖之前的记录,而增量同步会在之前的记录下新增
  2. 有这个 api 我们就可以将智能扫描任务和我们的日常开发运维连接起来,实现审核 sql 自动化,比如可以sqle结合jenkins加一个构建流程,在Jenkins任务触发时会进行sql审核,这里有分享文章(https://mp.weixin.qq.com/s/09-ZMMU3wvZdxrv6WIFFWg)

四、利用 OpenAPI 实现自己的扫描任务工具

前面我介绍了这个 OpenAPI 的高度的自定义性,下面我就给大家展示一下我写的一个小工具。就算有了 sqle ,但是我还想实现高度的自动化(其实就是比较懒,不想做重复工作),我希望有一个工具直接一键就可以将我的 sql 全部上传到扫描任务里,然后进行审核。于是我写了小工具,可以将文件或者文件夹里的 sql 扫描出来并上传到指定的扫描任务中

自定义配置文件

host: your IP and port
path: your sql file path  eg: ./test.sql
audit-name: your audit name  eg:zidingyi
type: full  #full or partial 代表全量同步或者增量同步
isIndependent: true  #是否使用独立sql语句传入(也就是一个sql语句调用一次接口传入)
token: your token

自定义配置文件支持命令和参数和配置文件绑定,命令行参数优先级高,也就是优先采用命令行的参数,没有命令行参数则使用配置文件的参数

读取 sql

这一步将分成四种方式读取 sql 文件,分别取是否读取整个文件夹和是否使用独立 sql 语句传入的笛卡尔积,共4个函数

发送请求到 api

根据不用的参数将解析的 sql 生成 OpenAPI 的 body 参数,然后可以发送给 sqle 服务器,并获取返回参数。

client := http.Client{}
req, err := http.NewRequest("POST", fmt.Sprintf("http://%s/v1/audit_plans/%s/sqls/%s", cmd.Host, cmd.AuditName, cmd.Type), body)
if err != nil {
 fmt.Println(err.Error())
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", cmd.Token)

res, err := client.Do(req)
if err != nil {
 fmt.Println(err.Error())
}
defer res.Body.Close()
b, _ := ioutil.ReadAll(res.Body)
var r = modal.Result{}
_ = json.Unmarshal(b, &r)
fmt.Println(r)
if r.Code != 0 || res.StatusCode != 200 {
 panic(r.Message)
 }
}

这里只是简单的处理一下错误,还可以加入发生错误自动发送邮件,或者对接第三方办公软件的 api 发送到指定的群等功能

综上,一个简单的小工具就完成了,这样我就可以一键解析 sql 并且将解析的 sql 传送到 sqle 的扫描任务中了,同时可以根据自己的实际情况增加不同的功能。由此可见,slqe 的扫描任务的自定义程度是非常高的。

这个小工具也是放到github上了,喜欢的可以看一看(https://github.com/caichuanwang/sqls)

功能演示
  • 将需要上传的 sql 准备成一个 sql 文件,如果需要读取同一文件夹下多个 sql 文件,只需要将配置文件路径设置成文件夹路径即可
select * from audit_plans where id = 6;
  
select * from execute_sql_detail where id = 5;
  • 配置自定义配置文件,这个根据自己的实际情况配置,如果没有配置,也可以使用命令行参数配置,命令行参数权重大于配置文件
  • 初次运行对项目进行编译后执行

后期运行只需要直接执行二进制文件并使用命令行参数修改部分参数即可

  • 再次查看扫描任务的详情即可
其他业务场景类型

为了适应不同的业务场景,同时使sqle更加强大,扫描任务支持多种类型的sql的采集任务,包括有TopSQL 慢日志 Mybatis扫描 等场景的处理,这里在我们的文档有介绍(https://actiontech.github.io/sqle-docs-cn/3.modules/3.6_auditplan/introduction.html)

五、总结

sqle 的智能扫描任务的覆盖面很广,而且可以高度自定义,在日常的开发运维中可以自动帮助我们解析 sql ,及时发现错误的 sql 。大家可以下载安装 SQLE 并结合自己公司的需求试一下智能扫描,SQLE 的安装参考主页:https://github.com/actiontech/sqle ;

更多使用场景可以参考:https://actiontech.github.io/sqle-docs-cn/3.modules/3.6_auditplan/introduction.html 。