我们正在使用conftest来验证我们的地形变更集是否适用于某些规则和合规性。我们要验证的一件事是,是否根据AWS标记约定对我们的AWS资源进行标记,该约定指定要使用的某些标记(例如Owner,ApplicationRole,Project),并指定所有标记和值都在CamelCase中。
在terraform中,更改集在以下(简化的)json输出中描述:
{
"resource_changes":{
"provider_name":"aws",
"change":{
"before":{
},
"after":{
"tags":{
"ApplicationRole":"SomeValue",
"Owner":"SomeValue",
"Project":"SomeValue"
}
}
}
}
}
我现在想要做的是验证以下内容:
但是,我很难在Rego中定义它(我对OPA还是很陌生的。)
有没有一种方法可以“循环”对象的键和值,并验证它们的格式是否正确?
以伪代码:
for key, value in tags {
re_match(`([A-Z][a-z0-9]+)+`, key)
re_match(`([A-Z][a-z0-9]+)+`, value)
}
我尝试了以下方法:
tags_camel_case(tags) {
some key
val := tags[key]
re_match(`^([A-Z][a-z0-9]+)+`, key) # why is key not evaluated?
re_match(`^([A-Z][a-z0-9]+)+`, val)
}
但是,当针对以下测试json进行评估时:
{
"AppRole": "SomeValue",
"appRole": "SomeValue"
}
即使我同时检查了键和值与正则表达式,规则仍返回true
答案 0 :(得分:1)
tags_camel_case(tags)
函数对具有两个键的输入返回true,因为(默认情况下)Rego中的变量已存在量化。这意味着如果对于某些变量绑定集,规则主体中的语句为true,则满足规则主体。在上面的示例中,规则主体将由{key=AppRole, val=SomeValue}
满足。
要对所有人表达 ,您可以使用一个简单的技巧。首先编写一条规则,以检查任何标签是否不是驼峰大小写。第二,编写规则以检查是否满足第一条规则。
例如:
# checks if all tags are camel case
tags_camel_case(tags) {
not any_tags_not_camel_case(tags)
}
# checks if any tags are NOT camel case
any_tags_not_camel_case(tags) {
some key
val := tags[key]
not is_camel_case(key, val)
}
# checks if a and b are both camel case
is_camel_case(a, b) {
re_match(`^([A-Z][a-z0-9]+)+`, a)
re_match(`^([A-Z][a-z0-9]+)+`, b)
}
有关Rego中“所有人”表达的更多信息,请参见https://www.openpolicyagent.org/docs/latest/how-do-i-write-policies/#universal-quantification-for-all