前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SQL审核 | 如何快速使用 SQLE 审核各种类型的数据库

SQL审核 | 如何快速使用 SQLE 审核各种类型的数据库

作者头像
爱可生开源社区
发布2022-05-23 09:30:20
5970
发布2022-05-23 09:30:20
举报
文章被收录于专栏:爱可生开源社区

作者:孙健

孙健,爱可生研发工程师,负责 SQLE 相关开发;

本文来源:原创投稿

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

前言

近些年来,数据库产业发展迅猛,各种新兴数据库如雨后春笋般出现,各个公司的技术栈也不再局限于某一种数据库。对于SQL质量管理平台来说仅支持某一个类型的数据库(例如MySQL),那么是会有一定的局限性,SQLE在设计之初考虑支持多种数据库,因此产品设计时,将审核流程(业务)的代码和具体SQL审核上线的代码进行分离,SQL审核上线通过插件的形式实现。SQLE对外提供插件开发所需的接口和库,可以快速创建开启一个审核插件,无需升级软件,导入审核插件即可获对应数据库类型的审核上线能力,使用平台所有功能。

插件的开发参考文档:https://actiontech.github.io/sqle-docs-cn/3.modules/3.7_auditplugin/auditplugin_development.html ,

插件的使用参考文档:https://actiontech.github.io/sqle-docs-cn/3.modules/3.7_auditplugin/auditplugin_management.html。

本文将演示如何从零开始创建一个简单可用的审核插件,作为案例。

目标

首先将创建一个 Postgres 数据库审核插件,并添加两条规则,“禁止使用 SELECT *”和“创建的表字段过多”,并在开发过程中结合SQLE对Postgres数据库进行SQL审核上线工单的测试演示。以下过程中的演示代码可从此处https://github.com/actiontech/sqle/tree/main/example/db_plugin下载。

实操

提示:SQLE和插件为GO语言开发,如果要进行插件开发,需要对GO有一丢丢了解即可。

1. 创建插件项目

首先使用go mod初始化一个go项目,然后

代码语言:javascript
复制
mkdir sqle-pg-plugin
cd sqle-pg-plugin
touch main.go
go mod init sqle-pg-plugin # 初始化go mod 
export GOPROXY=goproxy.cn,goproxy.io,direct # 设置 GoProxy,解决SQLE库下载问题,通过IDEA开发的可以在IDEA软件上设置;
go get github.com/actiontech/sqle@v1.2204.0 # 此版本为该文章编辑时的最新版本。
2.编写最小化插件代码

在项目main.go文件内编写如下代码,即可最快的添加一个Postgres数据库审核插件,此时插件没有审核规则。

代码语言:javascript
复制
package main
 
import (
   adaptor "github.com/actiontech/sqle/sqle/pkg/driver"
)
 
func main() {
   plugin := adaptor.NewAdaptor(&adaptor.PostgresDialector{})
   plugin.Serve()
}

使用`go build编译后得到二进制文件 sqle-pg-plugin,按前言中的插件的使用参考文档,我们部署到SQLE服务里。可以正常添加数据源,如下图所示:

此时正常进行SQL审核上线工单创建并上线,如下图所示:

3.给插件添加一条规则

在刚刚代码的基础上,我们在main函数内添加如下代码来新增一条规则“禁止使用 SELECT *”,完整代码如下所示。

代码语言:javascript
复制
package main
 
import (
   "context"
   "strings"
 
   "github.com/actiontech/sqle/sqle/driver"
   adaptor "github.com/actiontech/sqle/sqle/pkg/driver"
 
)
 
func main() {
   plugin := adaptor.NewAdaptor(&adaptor.PostgresDialector{})
   rule1 := &driver.Rule{
      Name:     "pg_rule_1", // 规则ID,该值会与插件类型一起作为这条规则在 SQLE 的唯一标识
      Desc:     "禁止使用 SELECT *",      // 规则描述
      Category: "DQL规范",           // 规则分类,用于分组,相同类型的规则会在 SQLE 的页面上展示在一起
      Level:    driver.RuleLevelError,    // 规则等级,表示该规则的严重程度
   }
    //
   rule1Handler := func(ctx context.Context, rule *driver.Rule, sql string) (string, error) {
      if strings.Contains(sql, "select *") {
         return rule.Desc, nil
      }
      return "", nil
   }
   plugin.AddRule(rule1, rule1Handler)
   plugin.Serve()
}

我们按之前的方式编译插件二进制文件,并部署到SQLE server内,可以看到新增了一条规则,如下图所示:

此时我们提交一个工单验证一下,可以看到触发了我们刚添加的规则

4.给插件添加一条可配置的复杂规则

基于上面的代码,我们再添加一条规则“创建的表字段过多”,具备如下特性:

  • 上面添加的规则基于字符串匹配进行的,准确性不高,无法匹配到不同的书写格式,比如大小写,换行等。因此我们在这里会基于SQL解析器开发一条规则,测试使用的解析库 https://github.com/pganalyze/pg_query_go;
  • 为了增加规则的适用性,我们准备给规则加一个动态配置给用户提供可选项。

代码如下:

代码语言:javascript
复制
package main
 
import (
   "context"
   "fmt"
   "strings"
 
   "github.com/actiontech/sqle/sqle/driver"
   adaptor "github.com/actiontech/sqle/sqle/pkg/driver"
   "github.com/actiontech/sqle/sqle/pkg/params"
   parser "github.com/pganalyze/pg_query_go/v2"
)
 
func main() {
   plugin := adaptor.NewAdaptor(&adaptor.PostgresDialector{})
 
   rule1 := &driver.Rule{
      Name:     "pg_rule_1",           // 规则ID,该值会与插件类型一起作为这条规则在 SQLE 的唯一标识
      Desc:     "避免查询所有的列",            // 规则描述
      Category: "DQL规范",               // 规则分类,用于分组,相同类型的规则会在 SQLE 的页面上展示在一起
      Level:    driver.RuleLevelError, // 规则等级,表示该规则的严重程度
   }
   rule1Handler := func(ctx context.Context, rule *driver.Rule, sql string) (string, error) {
      if strings.Contains(sql, "select *") {
         return rule.Desc, nil
      }
      return "", nil
   }
 
   // 定义第二条规则
   rule2 := &driver.Rule{
      Name:     "pg_rule_2",
      Desc:     "表字段不建议过多",
      Level:    driver.RuleLevelWarn,
      Category: "DDL规范",
      Params: []*params.Param{ // 自定义参数列表
         &params.Param{
            Key:   "max_column_count",  // 自定义参数的ID
            Value: "50",                // 自定义参数的默认值
            Desc:  "最大字段个数",            // 自定义参数在页面上的描述
            Type:  params.ParamTypeInt, // 自定义参数的值类型
         },
      },
   }
 
   // 这时处理函数的参数是 interface{} 类型,需要将其断言成 AST 语法树。
   rule2Handler := func(ctx context.Context, rule *driver.Rule, ast interface{}) (string, error) {
      node, ok := ast.(*parser.RawStmt)
      if !ok {
         return "", nil
      }
      switch stmt := node.GetStmt().GetNode().(type) {
      case *parser.Node_CreateStmt:
         columnCounter := 0
         for _, elt := range stmt.CreateStmt.TableElts {
            switch elt.GetNode().(type) {
            case *parser.Node_ColumnDef:
               columnCounter++
            }
         }
         // 读取 SQLE 传递过来的该参数配置的值
         count := rule.Params.GetParam("max_column_count").Int()
         if count > 0 && columnCounter > count {
            return fmt.Sprintf("表字段不建议超过%d个,目前有%d个", count, columnCounter), nil
         }
      }
      return "", nil
   }
 
   plugin.AddRule(rule1, rule1Handler)
   plugin.AddRuleWithSQLParser(rule2, rule2Handler)
 
   // 需要将 SQL 解析的方法注册到插件中。
   plugin.Serve(adaptor.WithSQLParser(func(sql string) (ast interface{}, err error) {
      // parser.Parse 使用 PostgreSQL 的解析器,将 sql 解析成 AST 语法树。
      result, err := parser.Parse(sql)
      if err != nil {
         return nil, fmt.Errorf("parse sql error")
      }
      if len(result.Stmts) != 1 {
         return nil, fmt.Errorf("unexpected statement count: %d", len(result.Stmts))
      }
      // 将 SQL 的语法树返回。
      return result.Stmts[0], nil
   }))
 
   plugin.Serve()
}

打开SQLE规则界面,可以看到该规则已经添加到SQLE了,如图:

我们将规则模板内该规则的值调小点然后进行测试一下:

首先我们提交一条超过5个字段的建表语句,此时SQLE会触发该规则并给出预期的提示信息,如下图所示:

然后我们提交一条不超过5个字段的建表语句,此时SQLE不会触发该规则,如下图所示:

总结

通过上面的演示,大概介绍了SQLE数据库审核插件的简单开发测试过程。大家可根据类似步骤开发出一套符合自己公司需求的规则集,结合SQLE平台来满足日常使用。我们也提供了一些常见数据库的审核插件,大家也可以在此基础上进行开发,参考文档:https://actiontech.github.io/sqle-docs-cn/3.modules/3.7_auditplugin/overview.html

本文关键字:#SQLE# #SQL审核#

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-05-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 爱可生开源社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 目标
  • 实操
    • 1. 创建插件项目
      • 2.编写最小化插件代码
        • 3.给插件添加一条规则
          • 4.给插件添加一条可配置的复杂规则
          • 总结
          相关产品与服务
          数据库
          云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档