开放策略代理满足所有数组项的条件

Fit*_*lry 3 open-policy-agent rego

试图解决这个问题一段时间 - 我有一个包含数组的 JSON 输入,请说如下:

{
    "array" : [
        {"foo": "bar"},
        {"foo": "buzz"},
        {"misbehaving": "object"}
    ]
}
Run Code Online (Sandbox Code Playgroud)

我的目标是验证数组中的所有对象是否满足具有名为 foo 的字段的条件(实际用例是确保云部署中的所有资源都有标签)。我的问题是标准 rego 表达式被评估为“至少”而不是“全部”,这意味着表达式如下:

all_have_foo_field {
    input.array.foo
}
Run Code Online (Sandbox Code Playgroud)

总是返回 true,即使某些对象不满足这一点。我已经看过这个,但是评估一个正则表达式返回true或者false当我的策略检查字段是否存在时,这意味着如果它不存在,我会收到一个“var_is_unsafe”错误。

有任何想法吗?

tsa*_*all 7

有两种说法“X 中元素的所有字段都必须符合这些条件”(FOR ALL)。

域名注册地址:

all_have_foo_field {
  # use negation and a helper rule
  not any_missing_foo_field
}

any_missing_foo_field {
  some i
  input.array[i]
  not input.array[i].foo
}
Run Code Online (Sandbox Code Playgroud)

或者

all_have_foo_field {
  # use a comprehension
  having_foo := {i | input.array[i].foo}
  count(having_foo) == count(input.array)
}
Run Code Online (Sandbox Code Playgroud)

该方法取决于美国的情况。如果您想知道哪些元素不满足条件,那么理解很不错,因为您可以使用集合算术,例如,{i | input.array[i]} - {i | input.array[i].foo}生成不包含字段“foo”的数组索引集合。您可能希望将这些表达式分配给局部变量以提高可读性。有关更多详细信息,请参阅文档中的此部分:https : //www.openpolicyagent.org/docs/latest/policy-language/#universal-quantification-for-all

在这种情况下(与您链接的答案相反)我们不必使用正则表达式或类似的东西,因为对缺失/未定义字段的引用会导致未定义和未定义向外传播到表达式、查询、规则等。这介绍中在一定程度上进行了介绍

我们所要做的就是参考相关领域。请注意,not input.array[i].foo如果“foo”字段值false在许多情况下未定义并且false可以被视为可互换(它们并不完全相同 -false是有效的 JSON 值,而 undefined 表示缺少值。)如果您只需要匹配 undefined 然后您必须将引用的结果分配给局部变量。在理解的情况下,我们可以这样写:

# the set will contain all values i where field "foo" exists regardless
{i | _ = input.array[i].foo}
Run Code Online (Sandbox Code Playgroud)

在否定的情况下,我们需要一个额外的辅助规则,因为它not _ = input.array[i].foo是“不安全的”。我们可以写:

exists(value, key) { value[key] = _ }`
Run Code Online (Sandbox Code Playgroud)

现在not exists(input[i], "foo")只有当字段“foo”丢失时才为 TRUE。

请注意,区分 undefined 和false通常不值得 - 我建议仅在必要时这样做。