python 规则引擎

编程入门 行业动态 更新时间:2024-10-03 17:15:12

python <a href=https://www.elefans.com/category/jswz/34/1771204.html style=规则引擎"/>

python 规则引擎

OPA,全称OpenPolicyAgent, 底层用Go实现,它灵活而强大的声明式语言全面支持通用策略定义。

目前国内资料还比较少。

个人因为工作接触比较多,打算陆续分享些教程介绍下。

私以为规则引擎的技术选型完全可以多这个选择~~

文章目录什么是 OPA

优点

一个 RBAC 例子基本语法

rule

unification

什么是OPA

主要关键词是:轻量级的通用策略引擎

可与服务共存

集成方式可以是sidecar、主机级守护进程或库引入

文字图片还是不够生动,看看OPA作者怎么说:OpenPolicyAgent

优点强大的声明式策略

上下文感知

表达性强

快速

可移植

输入和输出支持任意格式

配合强大的声明式策略语言Rego,描述任意规则都不是问题全面支持规则和系统解耦

除了集成做Auth外,还可以应用到k8s,terraform,docker,kafka,sql,linux等上做规则决策工具齐全

有命令行,有交互式运行环境

支持测试,性能分析(底层Go实现)

有强大的交互式编辑器扩展vscode-opa

下面从一个RBAC鉴权例子来了解下OPA

一个RBAC例子

以下json配置了role能操作的资源和user的绑定关系

// data.json

{

"roles": [

{

"operation": "read",

"resource": "widgets",

"name": "widget-reader"

},

{

"operation": "write",

"resource": "widgets",

"name": "widget-writer"

}

],

"bindings": [

{

"user": "inspector-alice",

"role": "widget-reader"

},

{

"user": "maker-bob",

"role": "widget-writer"

}

]

}

当一个请求读取widgets的user(如下json)过来操作资源,怎么判定他是否可以呢?

// input.json

{

"action":{

"operation":"read",

"resource":"widgets"

},

"subject":{

"user":"inspector-alice"

}

}

可能你习惯性在想用自己趁手的语言和框架,一顿遍历循环搞定。

且慢,OPA告诉我们:

几行代码就可以!(当然代码少不是重点。。。)

这里是可以在线运行的代码示例

我们先抛开语法,代码其实就是描述了一条规则:

用户是否有角色,角色是否有权限操作的资源

下面我们开始学习OPA如何定义这条规则

基本语法

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

OPA的Rego基本语法如下表:

一点也不多。函数和虚拟文档我们后边再开文章展开,今天主要看明白他的规则定义。

首先输入会挂在input对象下,用到的上下文(就是规则决策基于的源数据)会挂在data对象下

rule

当定义规则时:每条规则都会有返回值

格式1:< Name > { ... }

不声明返回值,则只返回true或false格式2 < Name > = < Value > { ... }

声明返回值 < Value > 则返回其值规则体内每条描述会逐条And运算,全部成立才会返回值

多条同名规则相互之间是Or运算,满足其一即可

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

要求user_has_role和role_has_permission同时满足

两者的role_name也是一样。

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

Rego里可以省略声明局部变量, 直接使用。Tips: 但要这样的变量可以被同名的全局变量修改。 局部变量必要时还是应该使用some声明 如 some role_name

default allow = false

# allow will be true when user has role and role has permission

allow {

user_has_role[role_name]

role_has_permission[role_name]

}

然后其中user_has_role[role_name]这种带参数的结构不是规则,叫虚拟文档(文档:可被查询的集合)

# check user role binding exist

user_has_role[role_name] {

role_binding = data.bindings[_]

role_binding.role = role_name

role_binding.user = input.subject.user

}Tips: 仔细同学会发现,线上运行版有with : role_binding = data.bindings[_] with data.bindings as data_context.bindings

with 是用来替换输入input或者上下文data里的数据。

因为线上版没法指定上边的 data.json, 所以通过变量data_context替换传入的。

集合里边role_binding = data.bindings[_]是遍历data.bindings

Rego的遍历语法类似python,这里遍历流程是

将data.bindings一个值赋值给role_binding

进行后续处理,处理完后再赋下一个值Tips: _是特殊变量名,当需要变量占位又不需要后边引用时使用(类似Go的_)

至于role_binding.role = role_name这条你应该能猜到是判断请求过来的role名是否和配置一致

可是为什么是=操作符,不应该是==?

这里是一个有趣的点!

unification

Rego中实际只有=,而且作用是为变量赋值使等式成立,叫Unification

而:=局部变量赋值,==比较,是=的语法糖,为了实现局部变量赋值和比较,和编译错误更容易区分

所以=更像是数据查询。(毕竟Rego是一个数据查询语言嘛)

这里举个例子就好理解了:

[x, "world"] = ["hello", y]

# 之后,x值为hello,y为world

总结一下,本文介绍什么是OPA,并借一个简单的RBAC例子初探了Rego强大的声明规则语法。

下一篇,将会介绍如何本地优雅的开发OPA,感兴趣同学可以先在OPA的playground玩玩。

文章首发公众号:newbmiao

推荐阅读:OPA系列

更多推荐

python 规则引擎

本文发布于:2024-02-28 06:04:06,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1768648.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:规则   引擎   python

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!