7

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

 1 year ago
source link: https://studygolang.com/articles/35645
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

SQLE · 大约1小时之前 · 64 次点击 · 预计阅读时间 7 分钟 · 大约8小时之前 开始浏览    

作者:孙健

孙健,爱可生研发工程师,负责 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项目,然后

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/[email protected] # 此版本为该文章编辑时的最新版本。

2.编写最小化插件代码

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

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服务里。可以正常添加数据源,如下图所示:

sunjian0513-1.png

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

sunjian0513-2.png

3.给插件添加一条规则

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

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内,可以看到新增了一条规则,如下图所示:

sunjian0513-3.png

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

sunjian0513-4.png

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

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

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

代码如下:

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了,如图:

sunjian0513-5.png

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

sunjian0513-6.png

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

sunjian0513-7.png

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

sunjian0513-8.png

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


有疑问加站长微信联系(非本文作者))

280

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:701969077


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK