Могу я зациклить ключи и значения объекта в 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"
            }
         }
      }
   }
}

То, что я сейчас пытаюсь сделать, это проверить следующее:

  1. Проверьте, установлены ли метки.
  2. Проверьте, все ли ключи и значения верблюда.
  3. Убедитесь, что ключи включают набор (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/.

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