Как передать ввод в правило запроса, определяющее заданный документ

В документации OPA есть много примеров генерации наборов / массивов / объектов для запросов, например:

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.

Для повторного использования я хотел бы определить функцию, которая возвращает набор / массив / объект, но позволяет динамически передавать ввод. По сути, я хочу попытаться сделать следующее:

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 не будет работать для меня.

0 ответов

В 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

Вот ссылка на политику внутри игровой площадки: https://play.openpolicyagent.org/p/pEp6BLCtgn

Другие вопросы по тегам