ИЛИ в Open Policy Agent (профсоюзное поведение)

В OPA ясно, как запрашивать condition AND condition:

values := {
  "value1": {
    "a": "one"
  },
  "value2": {
    "a": "one",
    "b": "two"
  },
  "value3": {
    "a": "one",
    "b": "one"
  }
}

goodValues = [name |
  value = values[name]
  value.a == "one"
  value.b == "one"
]

Так что goodValues здесь будет содержать value3 только.

Но как запросить condition OR condition, так что goodValues будет содержать все 3 значения, потому что они либо value.a == "one" ИЛИ value.b == "one"?

2 ответа

Решение

Объединение нескольких выражений вместе выражает логическое И. Чтобы выразить логическое ИЛИ, вы определяете несколько правил или функций с одним и тем же именем. Это может сработать несколькими способами. Это описано во введении в OPA: https://www.openpolicyagent.org/docs/latest/.

Вариант 1: понимание и функции

Условия, которые вы хотите выразить по отношению к значению, можно разложить на вспомогательные функции, а затем запрос на понимание может ссылаться на функцию.

goodValues = [name |
  value := values[name]
  value_match(value)
]

value_match(v) {
  v.a == "one"
}

value_match(v) {
  v.b = "two"
}

Вариант 2: Дополнительные правила

В OPA/Rego правила приращения присваивают переменной набор значений. Определение правила предоставляет логику для генерации установленных значений. В отличие от понимания, вы можете перегрузить определение правила (предоставив несколько правил с одним и тем же именем) и выразить логическое ИЛИ, как объясняется в другом ответе.

# goodValues is a set that contains 'name' if...
goodValues[name] {
 value := values[name]  # name is in values
 value.a == "one"       # value.a is "one"
}

# goodvalues is a set that contains 'name' if...
goodValues[name] {
  value := values[name]  # name is in values
  value.b == "two"       # value.b is "two"
}

Нашел уродливый ответ с помощью инкрементального набора:

goodValues[name] {
  value = values[name]
  value.a == "one"
}

goodValues[name] {
  value = values[name]
  value.b == "one"
}

Но что, если это обычное состояние value = values[name]становится сложнее? Нужно будет извлечь его в отдельную переменную (и перебирать ее в каждом операторе условия)? Есть лучшее решение?

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