OPA 重新定義規則引擎-入門篇 (持續更新中)
檢視更多:歷史集錄
OPA
,全稱OpenPolicyAgent
, 底層用Go
實現,它靈活而強大的宣告式語言全面支援通用策略定義。
目前國內資料還比較少。
個人因為工作接觸比較多,打算陸續分享些教程介紹下。
私以為規則引擎的技術選型完全可以多這個選擇~~
什麼是 OPA
具體看官方文件 OPA philosophy docs
主要關鍵詞是:
- 輕量級的通用策略引擎
- 可與服務共存
- 整合方式可以是 sidecar、主機級守護程式或庫引入
文字圖片還是不夠生動,看看 OPA 作者怎麼說:
優點
-
強大的宣告式策略
- 上下文感知
- 表達性強
- 快速
- 可移植
輸入和輸出支援任意格式
配合強大的宣告式策略語言Rego
,描述任意規則都不是問題
- 全面支援規則和系統解耦
- 集承方式多
- Daemon 式服務
- Go 類庫引入
- 決策快
- 應用廣泛
除了整合做Auth
外,還可以應用到k8s,terraform,docker,kafka,sql,linux
等上做規則決策
- 工具齊全
- 有命令列,有互動式執行環境
- 支援測試,效能分析(底層
Go
實現) - 有強大的互動式編輯器擴充套件vscode-opa
- 有playground分享程式碼
下面從一個 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
基本語法如下表:
語法 | 例子 |
---|---|
上下文 | 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] { ... } |
一點也不多。函式和虛擬文件我們後邊再開文章展開,今天主要看明白他的規則定義。
首先輸入會掛在input
物件下,用到的上下文(就是規則決策基於的源資料)會掛在data
物件下
rule
當定義規則時:
-
每條規則都會有返回值
- 格式 1:
< Name > { ... }
- 格式 1:
不宣告返回值,則只返回 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 玩玩。
瞭解更多:OPA 的 Rego 文件
本文程式碼詳見:NewbMiao/opa-koans
文章首發公眾號:newbmiao
推薦閱讀:OPA 系列
- 加微信實戰群請加微信(註明:實戰群):gocnio
相關文章
- 《ElasticSearch入門》一篇管夠,持續更新Elasticsearch
- 【CTF入門】BUUCTF Misc刷題(持續更新)
- camunda快速入門(五):DMN規則引擎如何使用
- 學習 Laravel —— 前端篇(持續更新)Laravel前端
- 第八篇.HFM規則入門(二)
- git使用、持續更新中Git
- 第七篇.HFM規則入門(一)
- 關於在Flutter Web中載入html(持續更新中......)FlutterWebHTML
- Ant Design Pro 框架使用篇(持續更新)框架
- 正則 (入門篇)
- 第2-4-2章 規則引擎Drools入門案例-業務規則管理系統-元件化-中臺元件化
- PHP 的自動載入(持續學習更新中)PHP
- LeetCode刷題:數學篇(C++實現,持續更新中...)LeetCodeC++
- React SSR重構踩坑記錄(持續更新)React
- JVM(持續更新。。。)JVM
- FastApi持續更新ASTAPI
- 彙編筆記(持續更新中)筆記
- Spring面試題(持續更新中)Spring面試題
- JiaoZiVideoPlayer使用說明(持續更新中...)IDE
- clion小白使用技巧(持續更新中)
- Jenkins持續整合 入門實踐Jenkins
- URule規則引擎
- Open Policy Agent(OPA) 入門實踐
- PHP入門:常量基本規則PHP
- 常見 git 需求整理(持續更新中)Git
- springMVC簡單demo集合(持續更新中……)SpringMVC
- 【 一些網址,持續更新中….. 】
- 日常工作筆記(持續更新中。。)筆記
- Blender 雕刻 持續更新
- Xcode 技巧 持續更新XCode
- LeetCode刷題:設計問題篇(C++實現,持續更新中...)LeetCodeC++
- [IDE工具篇]提高辦公效率的幾款軟體(持續更新中)IDE
- ETL中如何自定義規則
- .NET RulesEngine(規則引擎)
- 規則引擎模式 - upperdine模式
- PC端寶藏軟體--持續更新中
- PHP面試題總結-持續更新中PHP面試題
- Angular核心概念一覽表(持續更新中)Angular