Могу я зациклить ключи и значения объекта в OPA, чтобы проверить, придерживаются ли они определенного формата (CamelCase)
Мы используем conftest для проверки, применяется ли наш набор изменений terraform к определенным правилам и соответствию. Одна вещь, которую мы хотим проверить, заключается в том, помечены ли наши ресурсы AWS в соответствии с соглашением об использовании тегов AWS, которое определяет определенные теги для использования (например, Owner, ApplicationRole, Project) и указывает, что все теги и значения находятся в CamelCase.
В terraform набор изменений изображается в следующем (упрощенном) выводе json:
{
"resource_changes":{
"provider_name":"aws",
"change":{
"before":{
},
"after":{
"tags":{
"ApplicationRole":"SomeValue",
"Owner":"SomeValue",
"Project":"SomeValue"
}
}
}
}
}
То, что я сейчас пытаюсь сделать, это проверить следующее:
- Проверьте, установлены ли метки.
- Проверьте, все ли ключи и значения верблюда.
- Убедитесь, что ключи включают набор (ApplicationRole, Owner, Project) в минимум.
Однако у меня возникают проблемы с определением этого в 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, хотя я проверяю и ключ, и значение в сравнении с регулярным выражением
1 ответ
tags_camel_case(tags)
Функция возвращает true для ввода с двумя ключами, потому что (по умолчанию) переменные в Rego количественно определены количественно. Это означает, что тела правила выполняются, если для некоторого набора привязок переменных операторы в теле правила истинны. В приведенном выше примере тело правила будет удовлетворено {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/.