A sharing about Open Policy Agent
package play
default hello = false
default v = false
default t2 = false
hello {
pi := 3.14159
#pi = 2.71828
rect := {"width": 2, "height": 4}
#rect.width=21
rect == {"height": 4, "width": 2}
cui := {"hometown":"zp", "age":26}
# =和==效果等效,都是判等而不是赋值
# cui = {"age":27, "hometown":"zp"}
# cui == {"age":27,"hometown":"zp"}
m := input.message
m == "world"
}
#右边的input,可以传参进来,根据参数来进行判断,也可以不传
v { “hello” == “hello” }
可以用;来分割多个”表达式”,或者新起一行,以省略;
几个表达式之间是and的关系
t { x := 42; y := 41; x > y }
也可以直接返回true/false,但是不能返回空body,否则会报错: found empty body
tt {true}
t2 {
x := 42
y := 41
x > y
#3 > 5
}
———-
这里面表达式的顺序不影响结果
s {
x > y
y = 41
x = 42
}
s2 {
#43 > y # 在一个值出现后又被:=赋值,则会报错
y := 42
y := 42 #这样会报错:rego_compile_error: var y assigned above
}
在一个值出现后又被:=赋值,则会报错;即在这个值出现过后,不能再出现:=的操作
s3 {
y := 42
43 > y
}
———-
sli {
#sites = [{"name": "prod"}, {"name": "smoke1"}, {"name": "dev"}]
# there exists (at least) one document within sites where the name attribute equals "smoke1".,
# 即[_]的作用就是遍历这个东西,然后如果有其中一个元素,和已知的元素相等,则返回true,类似Inslice方法或者in_array方法
input.site[_].name = "smoke1"
}
We can generalize the example above with a rule that defines a set document instead of a boolean document,
可以用这种方式,来返回一个”set”,而不是bool值
sli6[enviroment]{
#enviroment := input.site[_].name
enviroment = input.site[_].name
#:=和=两种写法都可以.
}
is_sli6_contain_sth {
sli6[“prod”]
sli6[“23sd”]
}
———————————————————
greeting := “Hello”
max_height := 42
location := null
scalar{
[greeting, max_height] = ["Hello",42]
location = null
}
#default composite1 = true
composite1[cube] {
cube := {"width": 3, "height": 4, "depth": 5}
}
composite1[cube2] {
cube2 := {"width": 13, "height": 4111, "depth": 2225}
}
composite6 {
cube := {"width": 13, "height": 4111, "depth": 2225}
cube.height #返回13
}
composite8 {
a := 42
b := false
c := null
d := {“a”: a, “x”: [b, c]}
d.a = 44
}
—–
set类型是unordered的,unique的;
{}即是集合
set5[cube] {
cube := {“width”: 666, “height”: 777,”time”: 666, “depth”: 888,”depth”: 999}
}
set6[s] {
cube := {“width”: 666, “height”: 777,”time”: 6667, “depth”: 888,”depth”: 999}
s := {cube.width, cube.height, cube.depth,cube.time}
}
set8 {
{1,2,3} == {3,1,2}
x = 1
{1,2,3} == {3,x,2}
}
因为集合与对象都是用{}大括号语法来定义; 用{}定义一个空对象,所以必须使用不同的语法来创建一个空集合:count(set())
#———Variables—————–
#———References—————–
r[ u[0].servers[1].hostname] {
u := input.university
}
#用dot-access或者类似python的方式都可以
r2[ u[0][“servers”][2][“name”]] {
u := input.university
}
两种形式均有效,但是,点访问样式通常更具可读性。但在四种情况下必须使用方括号:
—————Variable Keys—————–
i和j,类似冒泡排序,把每个都过一遍,但凡有一个值等于给定的值,则返回true
下划线可以被视为特殊的迭代器。就是一种语法糖: 在幕后,OPA将_字符转换为唯一的变量名称,该名称与范围内的变量和规则不冲突。
vk {
input.university[].servers[].hostname = “sdu.edu.cn”
}
——————Composite Keys—————————
s := {[1, 2], [1, 4], [2, 6]}
s[[1, 2]]
——————Comprehensions————————
这部分的input
{
“message”: “world”,
“site”:[{“name”: “prod”}, {“name”: “smoke1”}, {“name”: “dev”}],
"university":[
{
"region": "north",
"name": "Beijing",
"servers": [
{
"name": "tsinghua",
"hostname": "tsinghua.edu.cn"
},
{
"name": "pku",
"hostname": "pku.edu.cn"
},
{
"name": "ruc",
"hostname": "ruc.edu.cn"
}
]
},
{
"region": "east",
"name": "Shanghai",
"servers": [
{
"name": "sjtu",
"hostname": "sjtu.edu.cn"
},
{
"name": "fudan",
"hostname": "fudan.edu.cn"
},
{
"name": "tongji",
"hostname": "tongji.edu.cn"
}
]
},
{
"region": "south",
"name": "Guangzhou",
"servers": [
{
"name": "sysu",
"hostname": "sysu.edu.cn"
},
{
"name": "scut",
"hostname": "scut.edu.cn"
}
]
}
]
}
2
package play
sites := [
{“name”: “prod”},
{“name”: “smoke1”},
{“name”: “dev”}
]
q[name1] {
name1 := input.sites[_].name
}
v {
1 = 1
input.site[_].name = “dev”
}{
2=22
}
2的input
{
“message”: “world”,
“site”:[{“name”: “prod”}, {“name”: “smoke1”}, {“name”: “dev”}]
}
3
package play
Composite Keys
s = {[1, 2], [1, 4], [2, 6]}
rs[s[[1, x]]]{
s[[1,x]] == [1,2]
#true
}
4
package play
Comprehensions ,类似python中的语法
Python equivalent of Rego comprehension shown above.
names = [site.name for site in sites if site.region == “west”]
region := “west”
#names := [name | sites[i].region == region; name := sites[i].name]
names := [name | input.site[i].region == region; name := input.site[i].name]
input是:
{
“message”: “world”,
“site”:[
{
“region”: “east”,
“name”: “prod”,
“servers”: [
{
“name”: “web-0”,
“hostname”: “hydrogen”
},
{
“name”: “web-1”,
“hostname”: “helium”
},
{
“name”: “db-0”,
“hostname”: “lithium”
}
]
},
{
“region”: “west”,
“name”: “smoke”,
“servers”: [
{
“name”: “web-1000”,
“hostname”: “beryllium”
},
{
“name”: “web-1001”,
“hostname”: “boron”
},
{
“name”: “db-1000”,
“hostname”: “carbon”
}
]
},
{
“region”: “west”,
“name”: “dev”,
“servers”: [
{
“name”: “web-dev”,
“hostname”: “nitrogen”
},
{
“name”: “db-dev”,
“hostname”: “oxygen”
}
]
}
]
}
5
package play
default hello = false
Array Comprehensions
app_to_hostnames[app_name] = hostnames {
app := input.apps[_]
app_name := app.name
hostnames := [hostname | name := app.servers[]
s := input.sites[].servers[_]
s.name == name
hostname := s.hostname]
}
input是:
{
“message”: “world”,
“apps”: [
{
“name”: “web”,
“servers”: [“web-0”, “web-1”, “web-1000”, “web-1001”, “web-dev”]
},
{
“name”: “mysql”,
“servers”: [“db-0”, “db-1000”]
},
{
“name”: “mongodb”,
“servers”: [“db-dev”]
}
],
"sites" : [
{
"region": "east",
"name": "prod",
"servers": [
{
"name": "web-0",
"hostname": "hydrogen"
},
{
"name": "web-1",
"hostname": "helium"
},
{
"name": "db-0",
"hostname": "lithium"
}
]
},
{
"region": "west",
"name": "smoke",
"servers": [
{
"name": "web-1000",
"hostname": "beryllium"
},
{
"name": "web-1001",
"hostname": "boron"
},
{
"name": "db-1000",
"hostname": "carbon"
}
]
},
{
"region": "west",
"name": "dev",
"servers": [
{
"name": "web-dev",
"hostname": "nitrogen"
},
{
"name": "db-dev",
"hostname": "oxygen"
}
]
}
]
}
6
package play
default hello = false
Object Comprehensions
app_to_hostnames := {app.name: hostnames |
app := input.apps[]
hostnames := [hostname |
name := app.servers[]
s := input.sites[].servers[]
s.name == name
hostname := s.hostname]
}
input:
{
“message”: “world”,
“apps”: [
{
“name”: “web”,
“servers”: [“web-0”, “web-1”, “web-1000”, “web-1001”, “web-dev”]
},
{
“name”: “mysql”,
“servers”: [“db-0”, “db-1000”]
},
{
“name”: “mongodb”,
“servers”: [“db-dev”]
}
],
"sites":[
{
"region": "east",
"name": "prod",
"servers": [
{
"name": "web-0",
"hostname": "hydrogen"
},
{
"name": "web-1",
"hostname": "helium"
},
{
"name": "db-0",
"hostname": "lithium"
}
]
},
{
"region": "west",
"name": "smoke",
"servers": [
{
"name": "web-1000",
"hostname": "beryllium"
},
{
"name": "web-1001",
"hostname": "boron"
},
{
"name": "db-1000",
"hostname": "carbon"
}
]
},
{
"region": "west",
"name": "dev",
"servers": [
{
"name": "web-dev",
"hostname": "nitrogen"
},
{
"name": "db-dev",
"hostname": "oxygen"
}
]
}
]
}
####
原文作者: fliter
原文链接:
http://www.dashen.tech/2019/12/05/A-sharing-about-Open-Policy-Agent_bak/版权声明: 转载请注明出处