Packages inside the dynamic extent of a rule's ref are rejected at compile-time
johanfylling opened this issue · 0 comments
The general case
The following modules
Module A:
package overlap
p[x] := 1 {
x := "foo"
}
Module B:
package overlap.p
bar := 2
will generate the compile-time error:
1 error occurred: a.rego:1: rego_type_error: package overlap.p conflicts with rule p[__local0__] defined at a.rego:3
However, module A
and B
can be expressed as a single module:
package overlap
p[x] := 1 {
x := "foo"
}
p.bar := 2
which is valid rego, and will not be rejected by the compiler.
Side note: the error reports the bad package to be at a.rego:1
, but it's actually at b.rego:1
The optimized build case
The above scenario can unintentionally be triggered through optimized compilation, e.g. when building an optimized bundle.
If building the policy:
package overlap
p[x] := 1 {
x := input.x
}
p.bar := input.y
main {
p[input.x]
}
with opa build --optimize 1 .
a bundle with the following content will be produced:
optimized/overlap.rego
:
package overlap
main {
__local2__1 = input.x
data.overlap.p[__local2__1] = _term_1_11
_term_1_11
}
p[__local0__3] = 1 {
__local0__3 = input.x
}
optimized/overlap/p.rego
:
package overlap.p
bar = __local1__2 {
__local1__2 = input.y
}
which will produce the following error when evaluated with opa eval -d bundle.tar.gz -fpretty 'data'
:
1 error occurred: /optimized/overlap.rego:1: rego_type_error: package overlap.p conflicts with rule p[__local0__3] defined at /optimized/overlap.rego:9
Suggested fix
Allow packages to be declared within the dynamic extent of a rule's ref. The document defined at the package path by the module might pose a conflict at eval-time, but cannot be determined to do so at compile-time.
Example 1: package extends partial object rule (valid)
a.rego
:
package overlap
p[x] := 1 { x := input.list[_] }
b.rego
:
package overlap.p
q := 2
Example 2: package redeclares value of single-value rule (invalid)
a.rego
:
package overlap
p := 1
b.rego
:
package overlap.p
q := 2
Example 3: package redeclares value of multi-value rule (invalid)
a.rego
:
package overlap
p[x] { x := input.list[_] }
b.rego
:
package overlap.p
q := 2