Golang Go语言中的OPA 进阶-简洁的推导式
Golang Go语言中的OPA 进阶-简洁的推导式
本文来讲讲OPA
推导式( comprehensions ),主要涉及三类数据的推导式:object,array,set
我们将以实现判断配置文件数据的不同聚合方式为例展开。
用到的输入(配置文件列表)为:
// input.json
// posix 为常见路径格式
// traditional-mac 为 mac 的一种文件路径格式
{
"files": [
{
"type": "posix",
"path": "/Users/newbmiao/Documents/1.yaml"
},
{
"type": "posix",
"path": "/Users/newbmiao/Documents/2.yaml"
},
{
"type": "traditional-mac",
"path": "Macintosh HD:Users:newbmiao:Documents:3.yml"
},
{
"type": "traditional-mac",
"path": "Macintosh HD:Users:newbmiao:Documents:3.json"
}
]
}
comprehensions
推导式(comprehensions
)提供了一种从子查询构建复合值(Composite Values
)的简洁方法。
定义很晦涩,我们从例子来看会清晰许多
object comprehensions
首先看一个按文件路径类型聚合文件的例子:
import input.files
group_files_by_type := {type: paths |
file := files[]
type := file.type
paths := [path |
tmp := files[]
tmp.type == type
path := tmp.path
]
}
即两层遍历,外层遍历获取type
内层遍历按type
匹配推导出paths
数组
对应结果为
opa eval -f values -d . -i input.json "data.example_comprehensions.group_files_by_type"
[
{
"posix": [
"/Users/newbmiao/Documents/1.yaml",
"/Users/newbmiao/Documents/2.yaml"
],
"traditional-mac": [
"Macintosh HD:Users:newbmiao:Documents:3.yml",
"Macintosh HD:Users:newbmiao:Documents:3.json"
]
}
]
忽略实现细节,对象的推导式语法为:
{ <key>: <term> | <body> }
定义的key
和term
需要在body
内赋值,最后会复合出一个对象,包含有所有满足的<key>: <term>
这里要注意的事body
内条件要都满足才会返回
array comprehensions
上边例子中paths
是一个数组推导式
其语法为: [ <term> | <body> ]
注意这里的[]
, 只有数组推导式用方括号
而且其内容是可重复的
对应再举一个将所有文件路径转为posix
的例子:
convert_all_to_posix_path_array := [path |
path1 := [p |
file := files[_]
file.type == "posix"
p := file.path
]
path2 := [p |
file := files[_]
file.type == “traditional-mac”
p := replace(replace(file.path, “Macintosh HD”, “”), “:”, “/”)
]
paths := array.concat(path1, path2)
path = paths[_]
]
这里按文件路径类型推导出path1
和path2
两个数组
其内部对于file.type
的判断达到了过滤匹配的作用
set comprehensions
上边功能也可以用集合推导式实现如下:
convert_all_to_posix_path_sets := {path |
path1 := {p |
file := files[_]
file.type == "posix"
p := file.path
}
path2 := {p |
file := files[_]
file.type == “traditional-mac”
p := replace(replace(file.path, “Macintosh HD”, “”), “:”, “/”)
}
paths := path1 | path2
path = paths[_]
}
集合推导式语法为:
{ <term> | <body> }
其特点是不会重复
可以看出同样功能,集合做组合操作比较表意
类似的,交集可以用&
,差集可以用-
以上就是OPA
三类推导式的使用方式。推导式最大的特点就是简洁。
一旦你熟悉了,就可以写出很多优雅的聚合方式。
最后出一个题目,大家可以自己练习下(答案可以去opa-koans
中查看)
实现基于文件后缀聚合文件路径, 即输出为:
{
"json": [
"Macintosh HD:Users:newbmiao:Documents:3.json"
],
"yaml": [
"/Users/newbmiao/Documents/1.yaml",
"/Users/newbmiao/Documents/2.yaml"
],
"yml": [
"Macintosh HD:Users:newbmiao:Documents:3.yml"
]
}
提示, 对于文件后缀可以用如下两种方式获取
方式一: hardcode
extSets := ["yaml", "yml", "json"]
方式二:regex
extSets := {e |
e = regex.find_all_string_submatch_n(".*\\.(.*)$", files[_].path, -1)[0][1]
}
本文代码详见:NewbMiao/opa-koans
下一篇,我们讲讲如何用OPA
的测试和压测保证规则的正确性与效率。
文章首发公众号:newbmiao
推荐阅读:OPA 系列
更多关于Golang Go语言中的OPA 进阶-简洁的推导式的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于Golang Go语言中的OPA 进阶-简洁的推导式的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Golang(Go语言)生态系统中,OPA(Open Policy Agent)作为一个强大的策略执行引擎,为开发者提供了灵活且高效的方式来管理和实施策略。虽然Go语言本身以简洁和直接著称,但在结合OPA进行进阶应用时,我们依然可以探索一些简洁的推导式来优化代码和策略定义。
OPA使用Rego语言来编写策略,Rego语言支持类似函数式编程的推导式,这使得策略表达更加紧凑和可读。在Go语言中调用OPA进行策略评估时,可以通过接口定义清晰的数据传输对象(DTOs),将复杂的数据结构简化为OPA易于理解的格式。
利用OPA的推导式,你可以将策略逻辑从Go代码中抽象出来,放在Rego策略文件中。这样做不仅提高了代码的可维护性,还使得策略变更更加灵活,无需修改Go代码即可调整策略。
例如,通过定义一系列规则(rules)和规则集(rule sets),你可以简洁地表达复杂的业务逻辑,如访问控制、数据验证等。在Go代码中,只需调用OPA的评估接口,传入相关数据,即可获得策略执行的结果。
此外,OPA还提供了丰富的内置函数和操作符,支持数组、对象等复杂数据结构的操作,进一步简化了策略表达式的编写。
总之,在Go语言中使用OPA时,通过合理利用Rego语言的推导式和OPA的内置功能,你可以实现更加简洁、高效且可维护的策略管理。