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"
        }
    ]
}

]

}

####