Registry server: filters on labels seem to require too much work
Filter expressions that refer to labels can fail if just one resource in a collection doesn't have the label.
$ registry label apis/- provider="google.com" --overwrite --filter 'labels.provider.contains("googleapis.com")'
FATAL[0000] Failed to handle command error=rpc error: code = InvalidArgument desc = no such key: provider uid=c46b6a16
A workaround is to add a "has" check before the label reference:
$ registry label apis/- provider="google.com" --overwrite --filter 'has(labels.provider) && labels.provider.contains("googleapis.com")'`
But this seems like unnecessary work. Are we handling the "no such key" error too severely? It seems that we are using it to abort the listing when we should instead just skip the item that lacks the key.
If this line returns false, nil instead of false with an error, the has() test is unnecessary. What could we miss by not returning the evaluation error?
With the change, we still detect invalid filters:
$ registry get apis --filter 'this is garbage'
Error: rpc error: code = InvalidArgument desc = ERROR: <input>:1:6: Syntax error: mismatched input 'is' expecting <EOF>
| this is garbage
| .....^
I agree that it seems better for most cases to just assume a false hit... but I can imagine that if the filter is testing for a negative (missing, empty, null), this change would reverse its meaning. Is that a potential issue? It seems like we could be eliminating the ability to find those? Are there any other potential solutions?
If we want to explicitly test for the presence or absence of a label, we can use has(e.f) -- for example has(labels.openapi) or !has(labels.openapi). For more possibilities, see the CEL Language Reference.
I feel like defaulting to false is probably safe if we document it well. FYI, there is also some discussion here on this CEL design decision and solutions: https://github.com/google/cel-go/issues/259