Hello! I have an issue with constructing JSON object in .rego files. I need to create JSON mongodb-selector in rule by provided variables and some variables may be are not provided (optional arguments). But when at least one field value in JSON is not provided - whole rule fails and returned null.
Example:
test policy:
package test
hello[selector] {
selector = {
"a": input.a,
"b": input.b #For example: b is optional and b is not provided now
}
}
input:
{
"a": "hello"
}
result:
{
"result": {
"hello": []
}
}
But i need another result, like this:
{
"result": {
"hello": {
"a": "hello"
}
}
}
Have .rego any suggestion for this case? Thanks!
# if b was not provided, this matches
hello[selector] {
not input.b
selector = {
"a": input.a
}
}
# matches if both a and b are provided
hello[selector] {
selector = {
"a": input.a,
"b": input.b
}
}
Try playing with the input to see either one of the rules match -- This might not be the most elegant approach, but I hope it serves as an inspiration :wink:
(It might not clarify things, but if it could be written more succinctly, see here.)
Rego doesn't (currently) have a great way to construct JSON values that may be partially undefined. In the long run, I think we need to add a new construct to the language that lets you mark parts of a JSON value as optional (or supply a default) so that construction doesn't fail when a single reference is undefined. This requires a bit of thought though.
In the meantime, there are a few ways you can do this. @srenatus provided one method. Here are two other examples: https://play.openpolicyagent.org/p/Znvn2hm7nR.
@tsandall Thanks a lot!
Just ran into this the other day. I ended up using an object comprehension.
hello[selector] {
possible_keys := {"a", "b"}
selector := {x:y |
possible_keys[x]
y := input[x] # if a possible key doesn't exist in input, this will be undefined
}
}
Just ran into this the other day. I ended up using an object comprehension.
hello[selector] { possible_keys := {"a", "b"} selector := {x:y | possible_keys[x] y := input[x] # if a possible key doesn't exist in input, this will be undefined } }
Thanks for a solution, but i need more flexible syntax, like in javascript. For example, i have this structure
hello[selector] {
selector = {
"a": input.a,
"b": {
"c": input.b #For example: b.c is optional and input.b is not provided now and b in nested object, also b may be in the another field of input, e.x: input.anotherField.b .
}
}
}
+1 it would be really appreciated to have such feature asap 🙄
Introducing a new constructor for dictionaries/objects that ignores an
undefined key or value would require a change to evaluation where the
constructor/builtin would be called despite one of its arguments being
undefined.
For example, suppose there were an operator {? for constructing
dictionaries where undefined key/values were ignored. (I don't like this
operator syntactically, but it serves the purpose of the example.)
d := {? "a": "b",
"c": input.foo}
So if input = {"foo": true} then d == {"a": "b", "c": true}, just like
with the normal operator. But with input = {} then d == {"a": "b"}.
Implementing that would require the evaluator to hand the undefined value
of input.foo over to the constructor, instead of propagating it up to the
dictionary and d like it does today.
On Tue, May 21, 2019 at 6:34 AM Nikolay Aleshkovskiy <
[email protected]> wrote:
+1 it would be really appreciated to have such feature asap 🙄
—
You are receiving this because you were assigned.
Reply to this email directly, view it on GitHub
https://github.com/open-policy-agent/opa/issues/1411?email_source=notifications&email_token=ACMVQK27YZZHEZMGNYR6423PWPF4ZA5CNFSM4HK7X4CKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODV3PVHA#issuecomment-494336668,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ACMVQK7H4XNF7G2SJTUM5Q3PWPF4ZANCNFSM4HK7X4CA
.
Most helpful comment
+1 it would be really appreciated to have such feature asap 🙄