OPA策略引擎用法实战

 

简介

官网介绍

OPA简单的说就是一个功能强大的策略规则引擎,开发的时候多少会遇到一些多样的规则配置,这些配置不足以写到数据库,所以都写到了代码中、配置文件中。项目做大的时候,如果需要修改规则,那么只能重新修改代码,打包发布,相对比较麻烦,还增加了业务的复杂度,这个时候OPA的作用就出来了,它可以把这些配置的的东西独立出来,让规则脱离主业务逻辑。

 

安装

OPA是一个很简单的东西,直接下载放到Linux的sbin下就能直接使用了

macOS (64-bit):  https://openpolicyagent.org/downloads/latest/opa_darwin_amd64

Linux下载:https://openpolicyagent.org/downloads/latest/opa_linux_amd64

 

以Linux为例,把名称修改下 opa_linux_amd64 改为 opa,然后设置文件可执行,再然后丢到/usr/bin目录下就能用了。

# Ubuntu 默认下载到 Downloads 目录下面
# 剪切刚才下载的opa可执行文件到 /usr/bin/目录下,并且重命名为 opa
sudo mv opa_linux_amd64 /usr/bin/opa

# 赋予它可执行权限
sudo chmod +x opa

# 测试
opa 回车

tommy@tommy-Vostro-3900:~/Downloads$ opa
An open source project to policy-enable your service.

Usage:
  opa [command]

Available Commands:
  bench       Benchmark a Rego query
  build       Build an OPA bundle
  check       Check Rego source files
  deps        Analyze Rego query dependencies
  eval        Evaluate a Rego query
  fmt         Format Rego source files
  help        Help about any command
  parse       Parse Rego source file
  run         Start OPA in interactive or server mode
  sign        Generate an OPA bundle signature
  test        Execute Rego test cases
  version     Print the version of OPA

Flags:
  -h, --help   help for opa

Use "opa [command] --help" for more information about a command.

实测

OPA官方给出了一个在线测试的地址

测试地址

image.png

 

 

实战

语法规则

基本语法

OPA基于一种数据查询语言实现了描述语言Rego

OPA的Rego基本语法如下表:

语法例子
上下文data
输入input
索引取值data.bindings[0]
比较“alice” == input.subject.user
赋值user := input.subject.user
规则< Header > { < Body > }
规则头< Name > = < Value > { … } 或者 < Name > { … }
规则体And运算的一个个描述
多条同名规则Or运算的一个规则
规则默认值default allow = false
函数fun(x) { … }
虚拟文档doc[x] { … }

rule

当定义规则时:

  • 每条规则都会有返回值
    • 格式1:< Name > { ... }
  • 不声明返回值,则只返回true或false
    • 格式2 < Name > = < Value > { ... }
  • 声明返回值 < Value > 则返回其值
  • 规则体内每条描述会逐条And运算,全部成立才会返回值
  • 多条同名规则相互之间是Or运算,满足其一即可

具体到代码中规则allow, 默认值是false

要求user_has_rolerole_has_permission同时满足

两者的role_name也是一样。

你可能发现,局部变量role_name 没声明啊!

Rego里可以省略声明局部变量, 直接使用。

事例

规则描述

高考中规定的分数线,不同城市的本科分数线是不一样的,小明考试查询下分数,需要往系统录入考试城市,以及考试分数,用来查询,即:

{
  "alias": "shenzhen",
  "score": 600
}

规则数据Data

{
  "achievement": {
    "shenzhen": {
      "yiben": {
        "score": 600
      },
      "erben": {
        "score": 500
      }
    },
    "guangzhou":{
      "yiben": {
        "score": 620
      },
      "erben": {
        "score": 520
      }
    }
  }

规则逻辑代码

package app.rbac

# 查询分数线是否满足条件
result = {"score_line": 1, "msg": "恭喜你考上一本"} {
    data.achievement[input.alias].yiben.score <= input.score
} else = {"score_line": 2, "msg": "恭喜你考上二本"}{
    data.achievement[input.alias].erben.score <= input.score
} else = {"score_line": -1, "msg": "没考上"}

 

运行测试结果

image.png

本地opa跑代码

创建一个文件夹 tommy 然后在tommy文件夹下再创建 tommytest 把三个文件丢到tommytest目录下

文件名称随意,标准的是:input.json data.json policy.rego

文件内容分别为:

input.json文件

{
  "alias": "shenzhen",
  "score": 600
}

data.json文件

{
  "achievement": {
    "shenzhen": {
      "yiben": {
        "score": 600
      },
      "erben": {
        "score": 500
      }
    },
    "guangzhou": {
      "yiben": {
        "score": 620
      },
      "erben": {
        "score": 520
      }
    }
  }
}
package tommytest

# 查询分数线是否满足条件
result = {"score_line": 1, "msg": "恭喜你考上一本"} {
    data.tommytest.achievement[input.alias].yiben.score <= input.score
} else = {"score_line": 2, "msg": "恭喜你考上二本"}{
    data.tommytest.achievement[input.alias].erben.score <= input.score
} else = {"score_line": -1, "msg": "没考上"}

然后,回到tommy文件夹目录,执行命令

opa eval --bundle . -i tommytest/input.json 'data.tommytest.result'

# 返回的结果
{
  "result": [
    {
      "expressions": [
        {
          "value": {
            "msg": "恭喜你考上一本",
            "score_line": 1
          },
          "text": "data.tommytest.result",
          "location": {
            "row": 1,
            "col": 1
          }
        }
      ]
    }
  ]
}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

s清风s

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值