Reputation: 90
After reading through the Open Policy Agent introduction documentation a few times, I'm having trouble writing a rule which asserts that for every element in a set, the specified object has an associated key.
Here's a simplified example what I'm currently trying to get working
https://play.openpolicyagent.org/p/oWBumjRkWX
package example
my_object = {
"lemon": ""
}
fruits = {
"orange",
"lemon",
"banana"
}
has_key(x, k) { _ = x[k] }
default has_lemon = false
has_lemon = has_key(my_object, "lemon") # this works as you'd expect
default all_fruits_have_entries_in_my_object = false
all_fruits_have_entries_in_my_object { # this is never false for some reason
some fruit
fruits[fruit]
has_key(my_object, fruit) # each fruit have a key in the my_object object
}
From what I understand, has_lemon
should be false when the fruits
does not contain the "lemon"
element and I've tested that this is working. However, I also thought that the all_fruits_have_entries_in_my_object
rule should evaluate to false
here since my_object
is missing keys for "orange"
and "banana"
. Am I doing something stupid here?
Upvotes: 1
Views: 491
Reputation: 5003
Rego is existentially quantified. That means rules are declared to check if there exists some fruit that is a key of the object.
One way to solve the problem: you can first gather all unexpected keys using a comprehension and then count the result:
package example
my_object = {
"lemon": ""
}
fruits = {
"orange",
"lemon",
"banana"
}
has_key(x, k) { _ = x[k] }
default has_lemon = false
has_lemon = has_key(my_object, "lemon") # this works as you'd expect
default all_fruits_have_entries_in_my_object = false
all_fruits_have_entries_in_my_object { # this is never false for some reason
non_fruit_keys := { key | my_object[key]; !fruits[key] }
count(non_fruit_keys) > 0
}
You can evaluate this example in the Rego Playground.
See also the documentation on Universal Quantification in Rego
Upvotes: 3