如何将输入传递给定义集合文档的查询规则
How to pass input to query rule defining a set document
在OPA的文档中有很多生成sets/arrays/objects用于查询的例子,例如:
app_to_hostnames[app_name] = hostnames {
app := apps[_]
app_name := app.name
hostnames := [hostname | name := app.servers[_]
s := sites[_].servers[_]
s.name == name
hostname := s.hostname]
}
但是,在文档中,所有数据都是静态定义的:在示例中,变量 apps
已经存在并且被定义为某个 json 对象。
为了可重用性,我想定义一个 returns 和 set/array/object 但允许动态传递输入的函数。本质上我想尝试做的是以下内容:
app_to_hostnames[app_name](apps) = hostnames {
app := apps[_]
app_name := app.name
hostnames := [hostname | name := app.servers[_]
s := sites[_].servers[_]
s.name == name
hostname := s.hostname]
}
在这种情况下,应用程序作为函数输入传递。有没有办法在 Rego 政策中实现这一目标?或者我应该以不同的方式处理这个问题?或者有没有办法将不同的输入传递给不同的策略?
我知道您可以通过 REST API 将输入发送到特定策略并以这种方式控制它,但在这种情况下,我使用 conftest 来传递输入文档(例如json 文件)到一组已编译的 rego 策略),因此使用 REST API 对我不起作用。
input
和 data
文档是全局的。您始终可以使用 with
关键字在给定表达式上替换它们的值,但有时将逻辑包装在函数中更自然。
可以使用理解重写该具体示例:
app_to_hostnames(apps, sites) = {app_name: hostnames |
app := apps[_]
app_name := app.name
hostnames := [hostname | name := app.servers[_]
s := sites[_].servers[_]
s.name == name
hostname := s.hostname]
}
或者,您可以使用 with
关键字临时替换 data
或 input
文档的部分内容。例如,如果 apps
、sites
是从包含 app_to_hostnames
的文件中的数据下导入的,您可以按如下方式查询 app_to_hostnames
:
mock_apps := [
{"name": "foo", "servers": ["s1"]},
{"name": "bar", "servers": ["s2", "s3"]},
]
mock_sites := [
{"servers": [{"name": "s1", "hostname": "x.com"}]},
{"servers": [{"name": "s2", "hostname": "y.com"}, {"name": "s3", "hostname": "z.com"}]},
]
app_to_hostnames == {"foo": ["x.com"], "bar": ["y.com", "z.com"]} with data.apps as mock_apps with data.sites as mock_sites
这里有一个 link 游乐场内的政策:https://play.openpolicyagent.org/p/pEp6BLCtgn
在OPA的文档中有很多生成sets/arrays/objects用于查询的例子,例如:
app_to_hostnames[app_name] = hostnames {
app := apps[_]
app_name := app.name
hostnames := [hostname | name := app.servers[_]
s := sites[_].servers[_]
s.name == name
hostname := s.hostname]
}
但是,在文档中,所有数据都是静态定义的:在示例中,变量 apps
已经存在并且被定义为某个 json 对象。
为了可重用性,我想定义一个 returns 和 set/array/object 但允许动态传递输入的函数。本质上我想尝试做的是以下内容:
app_to_hostnames[app_name](apps) = hostnames {
app := apps[_]
app_name := app.name
hostnames := [hostname | name := app.servers[_]
s := sites[_].servers[_]
s.name == name
hostname := s.hostname]
}
在这种情况下,应用程序作为函数输入传递。有没有办法在 Rego 政策中实现这一目标?或者我应该以不同的方式处理这个问题?或者有没有办法将不同的输入传递给不同的策略?
我知道您可以通过 REST API 将输入发送到特定策略并以这种方式控制它,但在这种情况下,我使用 conftest 来传递输入文档(例如json 文件)到一组已编译的 rego 策略),因此使用 REST API 对我不起作用。
input
和 data
文档是全局的。您始终可以使用 with
关键字在给定表达式上替换它们的值,但有时将逻辑包装在函数中更自然。
可以使用理解重写该具体示例:
app_to_hostnames(apps, sites) = {app_name: hostnames |
app := apps[_]
app_name := app.name
hostnames := [hostname | name := app.servers[_]
s := sites[_].servers[_]
s.name == name
hostname := s.hostname]
}
或者,您可以使用 with
关键字临时替换 data
或 input
文档的部分内容。例如,如果 apps
、sites
是从包含 app_to_hostnames
的文件中的数据下导入的,您可以按如下方式查询 app_to_hostnames
:
mock_apps := [
{"name": "foo", "servers": ["s1"]},
{"name": "bar", "servers": ["s2", "s3"]},
]
mock_sites := [
{"servers": [{"name": "s1", "hostname": "x.com"}]},
{"servers": [{"name": "s2", "hostname": "y.com"}, {"name": "s3", "hostname": "z.com"}]},
]
app_to_hostnames == {"foo": ["x.com"], "bar": ["y.com", "z.com"]} with data.apps as mock_apps with data.sites as mock_sites
这里有一个 link 游乐场内的政策:https://play.openpolicyagent.org/p/pEp6BLCtgn