341 Commits

Author SHA1 Message Date
Ashutosh Narkar cb104e318b config: Add API to expose OPA's active config
This commit adds a new API endpoint to fetch OPA's
active configuration. When the discovery feature is enabled,
this API can be used to fetch the discovered configuration
in the last evaluated discovery bundle.

Fixes: #2020

Signed-off-by: Ashutosh Narkar <anarkar4387@gmail.com>
2021-03-19 11:23:59 -07:00
Torin Sandall 65afa55c91 server: Remove cached revisions (#3277)
This commit refactors how the server manages the bundle revisions that
are included in decision logs and provenance results for the
API. Previously the revisions were cached on the server struct,
outside of the store. The server would read the revisions from the
store on reload() to keep them consistent.

While it is more performant to keep the revisions cached outside of
the store, it requires that the server perform reads on the
transaction that has already been committed. The inmem store
implementation allows for this however it's not going to be possible
to support that with other transaction implementations in the future.

This commit updates the server to simply read the revisions out of the
store in the handlers that require them. This adds a small amount of
overhead to the handlers that wasn't present before however in
practice this is not a concern (the overhead measured on my machine
was approx. 5 microseconds compared to the entire server handler that
was taking approx. 75 microseconds.)

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2021-03-16 11:50:57 +01:00
Matthew Mahnke 930d1031b9 server: URL decode policy IDs
Policy IDs will be decoded in GET, PUT, and DELETE requests to the
/policies endpoint.  This will enable users to include non-alphanumeric
characters in policy IDs, as well as leading forward slashes, by URL
encoding the path component of their requests.

Fixes #2116
Signed-off-by: Matthew Mahnke <mmahnke18@gmail.com>
2021-02-22 09:08:21 +01:00
Stephan Renatus 58be4ee36b cleanup: remove test.Subtest (#3144)
Go 1.7 was so long ago. New code doesn't use this anymore, either,
so let's get rid of it.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2021-02-11 19:59:54 +01:00
Stephan Renatus 103ea6c9ae custom reason in authz policy (#3137)
* Authorization policy with deny reason

Currently the authorization policy only returns boolean result. There
are no way to give more context to denied requests. This adds the ability
to policies to return a reason for denying the request.

Applying backward compatible policy evaluation logic.

Fixes #3056

Signed-off-by: Ajanthan Balachandran <balaajanthan@gmail.com>

* docs/security:: make object-response the extra, not the default; update tests

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
Co-authored-by: Ajanthan Balachandran <balaajanthan@gmail.com>
2021-02-09 18:02:48 +01:00
jkbschmid 81b7428d3e server: add metrics timer for CompilePost (#3097)
This change adds a server_handler timer to the metrics for any POSTs to /v1/compile.

So `curl -X POST localhost:8181/v1/compile?metrics ...` will result in:

    "metrics": {
        "timer_rego_partial_eval_ns": 145020,
        "timer_rego_query_compile_ns": 86415,
        "timer_rego_query_parse_ns": 56104,
        "timer_server_handler_ns": 377557  #this line is new
      }

Fixes #3096.

Signed-off-by: Jakob Schmid <jakob.schmid@sap.com>
2021-01-26 14:24:28 +01:00
Grant Shively a1d8381fc8 plugins: inter-query cache config discovery
InterQueryBuiltinCacheConfig now responds to the plugin manager's reconfigure event, which allows cache config to exist in discovery config. Previously, cache config would be ignored if it was only declared in discovery config.

Related to #2978.

Signed-off-by: Grant Shively <gshively@godaddy.com>
2021-01-05 16:09:58 -08:00
Anders Eknert 05a0697542 Fix false positives in bundle root check (#3033)
Allow writing to /data/foo when /data/foobar is a bundle root.

Fixes #2868

Signed-off-by: Anders Eknert <anders@eknert.com>
2021-01-05 11:46:41 +01:00
Stephan Renatus f9e0332dcf server: pass instrumentation via rego.EvalInstrument
Fixes #3000.

The assertions on the response metrics object should be enough to
cover the bug -- depending on what is happening during eval, the
keys of that object may differ. (E.g. if there's a ref to be resolved,
that operation is timed; if there are none, there's no timer data.)

Small change to test/e2e: close some request bodies

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2020-12-14 09:17:38 -05:00
Torin Sandall d40ff6f79b server: Add message body to authorization policy input
This commit updates the server's basic authorizer to include the
deserialized message body in the input to the authorization policy so
that the latter can make decisions based on policy query input
documents. The authorizer caches the parsed message body on the
request context and the server retrieves the value to avoid parsing twice.

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2020-12-08 09:55:53 -05:00
Patrick East 948bce78f9 server: Only set resolvers on base rego objects
We can set the resolvers on the base rego objects (which avoids
having them reloaded from the store) and they get propagated to any
prepared evals automatically.

Signed-off-by: Patrick East <east.patrick@gmail.com>
2020-11-06 15:12:38 -05:00
Patrick East 197c8387f7 wasm: Add metrics for wasm resolver evaluations
This plumbs through metrics to the wasm evaluation, adding several
new timers. They will show up when using a Wasm bundle with any of the
usual evaluation mechanisms (eg opa eval, bench, server requests etc)

Signed-off-by: Patrick East <east.patrick@gmail.com>
2020-11-06 15:12:38 -05:00
Patrick East 332c686c50 wasm: Update resolver usage for multiple entrypoints
The wasm binaries support >1 entrypoint per module, this makes changes
to reflect that in the various data structures we keep references to
the modules and resolvers, mapping them to entrypoints.

Signed-off-by: Patrick East <east.patrick@gmail.com>
2020-11-06 15:12:38 -05:00
Patrick East f84f4674a1 Add support for evaluating Wasm bundles
This is largely plumbing changes required to get Wasm modules loaded
from bundles and configured as external resolvers for evaluations.

Signed-off-by: Patrick East <east.patrick@gmail.com>
2020-11-06 15:12:38 -05:00
Torin Sandall c606719dd0 server: Add ?strict-builtin-errors query parameter to v1/data API
Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2020-10-23 12:28:23 -07:00
Torin Sandall 8b93b5a976 misc: Fix tests that relied on built-in errors
Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2020-10-23 12:28:23 -07:00
Torin Sandall 2373d89b12 runtime: Remove --insecure-addr flag
--insecure-addr was deprecated in in Oct 2018. It's time to say
  goodbye.

Fixes #763

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2020-10-23 10:01:21 -07:00
Stephan Renatus 2928df76bc server: move AuthenticationTLS test to e2e
Signed-off-by: Stephan Renatus <srenatus@chef.io>
2020-10-05 15:37:04 -07:00
Stephan Renatus d894ab456c server: enable H2C for HTTP listeners via CLI flag
This follows the docs provided by the [github issue](1),
https://www.mailgun.com/blog/http-2-cleartext-h2c-client-example-go/

For manual testing, ensure that you have a curl version with the proper
"Features", as can be read off `curl --version`:

    curl 7.72.0 (x86_64-apple-darwin19.5.0) libcurl/7.72.0 OpenSSL/1.1.1g zlib/1.2.11 brotli/1.0.9 zstd/1.4.5 c-ares/1.16.1 libssh2/1.9.0 nghttp2/1.41.0 librtmp/2.3
    Release-Date: 2020-08-19
    Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp
    Features: AsynchDNS brotli GSS-API HTTP2 HTTPS-proxy IPv6 Kerberos Largefile libz Metalink NTLM NTLM_WB SPNEGO SSL TLS-SRP UnixSockets zstd

As described in the mailgun blog post, curl-openssl on homebrew has it for osx.

With this change, and started with

    ./opa_darwin_amd64 run -s --h2c --diagnostic-addr :8182

Both the ALPN and the "prior knowledge" modes work against the insecure endpoints:

    $ curl -v --http2 http://127.0.0.1:8181/metrics >/dev/null
    *   Trying 127.0.0.1:8181...
    > GET /metrics HTTP/1.1
    > Host: 127.0.0.1:8181
    > User-Agent: curl/7.72.0
    > Accept: */*
    > Connection: Upgrade, HTTP2-Settings
    > Upgrade: h2c
    > HTTP2-Settings: AAMAAABkAAQCAAAAAAIAAAAA
    >
    * Mark bundle as not supporting multiuse
    < HTTP/1.1 101 Switching Protocols
    < Connection: Upgrade
    < Upgrade: h2c
    * Received 101
    * Using HTTP2, server supports multi-use
    * Connection state changed (HTTP/2 confirmed)
    * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
    * Connection state changed (MAX_CONCURRENT_STREAMS == 250)!
    < HTTP/2 200
    < content-type: text/plain; version=0.0.4; charset=utf-8
    < date: Wed, 30 Sep 2020 12:15:08 GMT
    <
    { [4096 bytes data]
    * Connection #0 to host 127.0.0.1 left intact
    $ curl -v --http2-prior-knowledge http://127.0.0.1:8181/metrics >/dev/null
    *   Trying 127.0.0.1:8181...
    * Using HTTP2, server supports multi-use
    * Connection state changed (HTTP/2 confirmed)
    * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
    * Using Stream ID: 1 (easy handle 0x7f85c3814c00)
    > GET /metrics HTTP/2
    > Host: 127.0.0.1:8181
    > user-agent: curl/7.72.0
    > accept: */*
    >
    * Connection state changed (MAX_CONCURRENT_STREAMS == 250)!
    < HTTP/2 200
    < content-type: text/plain; version=0.0.4; charset=utf-8
    < date: Wed, 30 Sep 2020 12:15:13 GMT
    <
    { [4096 bytes data]
    * Connection #0 to host 127.0.0.1 left intact

[1]: https://github.com/open-policy-agent/opa/issues/2399

Signed-off-by: Stephan Renatus <srenatus@chef.io>
2020-10-01 09:00:02 -07:00
Torin Sandall 186ef99ffa watch: Remove deprecated watch package and server feature
This commit removes the deprecated watch package and server
feature. This feature was never adopted and since the implementation
was not incremental, it would inevitably encounter
performance/scalability issues.

Fixes #2265

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2020-09-23 13:28:11 -07:00
Torin Sandall 7821831dfa server: Deprecate the watch and partial query parameters
Related: https://github.com/open-policy-agent/opa/issues/2265
Related: https://github.com/open-policy-agent/opa/issues/2266

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2020-08-10 10:24:50 -04:00
Ashutosh Narkar 7f65b04561 Add a new inter-query cache to cache responses across queries
This commit adds a new inter-query cache that built-in
functions can use to cache responses across queries.

The OPA config includes a new "caching" field that can be used
to set the size of the cache. By default there is no limit.

This change also updates `http.send` to optionally utilize the
inter-query cache.

Fixes #1753

Signed-off-by: Ashutosh Narkar <anarkar4387@gmail.com>
2020-08-06 14:33:18 -07:00
Torin Sandall 97cdaf9f60 storage: Remove unused indexing interface
At one point the in-memory store implemented an indexing strategy so
that variable bindings could be returned for non-ground references to
base documents. However, we eventually disabled in-memory indexing
and we have not re-added it since
3ebbeede6c. At this point, indexing can
be removed completely.

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2020-07-21 11:01:58 -04:00
Patrick East 2380c37fbe server: Fix race in baseHTTPListener.Addr()
There was a potential race with initializing a listener and saving the
reference to it and using the reference when checking on the address
for the listener.

This change is doing two things:

* Getting the address from the listener a single time _after_ it has
  been initialized.
* Using a mutex to protect access to the address (common use-case
  being to start the listener on a background thread and check for
  the address it is listening on from another one).

`go test -tags=slow -race -vet=off ./cmd/` is now passing with these
changes.

Signed-off-by: Patrick East <east.patrick@gmail.com>
2020-07-16 09:56:43 -04:00
Patrick East 739777cfff plugins/logs: Add custom EventV1 -> AST helper
This pretty substantially improves performance by avoiding to do a
JSON round trip and then converting into AST types.

There are a couple of fields left that require the round trip, we can
iterate on this as needed to supply better options for the results
and metrics.

This custom ASTer leaves out the rule counts, which also helps to
improve the performance.

On my local machine the numbers look like:

```
name                              old time/op    new time/op    delta
MaskingNop-8                         129µs ± 1%     110µs ± 1%  -15.19%  (p=0.000 n=7+10)
MaskingRuleCountsNop/1Rules-8        138µs ± 1%     111µs ± 1%  -19.34%  (p=0.000 n=10+10)
MaskingRuleCountsNop/10Rules-8       180µs ± 1%     116µs ± 4%  -35.70%  (p=0.000 n=10+10)
MaskingRuleCountsNop/100Rules-8      614µs ± 1%     113µs ± 1%  -81.66%  (p=0.000 n=10+8)
MaskingRuleCountsNop/1000Rules-8    5.16ms ± 2%    0.11ms ± 1%  -97.79%  (p=0.000 n=10+10)
MaskingErase-8                       148µs ± 2%     129µs ± 0%  -12.65%  (p=0.000 n=10+10)

name                              old alloc/op   new alloc/op   delta
MaskingNop-8                        56.7kB ± 0%    48.0kB ± 0%  -15.43%  (p=0.000 n=10+10)
MaskingRuleCountsNop/1Rules-8       59.5kB ± 0%    48.0kB ± 0%  -19.41%  (p=0.000 n=10+10)
MaskingRuleCountsNop/10Rules-8      84.9kB ± 0%    48.0kB ± 0%  -43.47%  (p=0.000 n=10+10)
MaskingRuleCountsNop/100Rules-8      362kB ± 0%      48kB ± 0%  -86.73%  (p=0.000 n=9+10)
MaskingRuleCountsNop/1000Rules-8    3.26MB ± 1%    0.05MB ± 0%  -98.52%  (p=0.000 n=10+10)
MaskingErase-8                      65.7kB ± 0%    57.0kB ± 0%  -13.33%  (p=0.000 n=10+10)

name                              old allocs/op  new allocs/op  delta
MaskingNop-8                         1.23k ± 0%     1.12k ± 0%   -8.46%  (p=0.000 n=10+10)
MaskingRuleCountsNop/1Rules-8        1.31k ± 0%     1.12k ± 0%  -14.32%  (p=0.000 n=10+10)
MaskingRuleCountsNop/10Rules-8       1.98k ± 0%     1.12k ± 0%  -43.30%  (p=0.000 n=10+10)
MaskingRuleCountsNop/100Rules-8      8.74k ± 0%     1.12k ± 0%  -87.13%  (p=0.000 n=10+10)
MaskingRuleCountsNop/1000Rules-8     76.3k ± 0%      1.1k ± 0%  -98.52%  (p=0.000 n=10+10)
MaskingErase-8                       1.33k ± 0%     1.22k ± 0%   -7.84%  (p=0.000 n=10+10)
```

So the performance no longer scales with the number of rules hit, and
overall the base cost is almost 20% faster. This time directly impacts
round trip latency for OPA REST clients performing evaluations.

Signed-off-by: Patrick East <east.patrick@gmail.com>
2020-07-15 12:01:12 -07:00
Patrick East b45ab28375 rego: Plumb the newer QueryTracer through Rego API's
This will deprecate the older API's that used the `topdown.Tracer` in
favor of the newer `topdown.QueryTracer` interface. Usages of the old
API have been swapped, although some of the testing is left with them
to ensure we still support them (until we remove the deprecated API).

Signed-off-by: Patrick East <east.patrick@gmail.com>
2020-07-15 12:01:12 -07:00
Patrick East 3f6934ea9a server: Fix typo
Signed-off-by: Patrick East <east.patrick@gmail.com>
2020-07-15 12:01:12 -07:00
Torin Sandall 57e7e89dff rego, server: Fix panic caused by compiler misuse
Previously the rego package would construct rules for each of the
PE query results when PartialResult() was invoked--however, it would not
check if those rules would be recursive. If the user queried for
`data` (or `data.<partialnamespace>`) then PE would return an
(essentially) unmodified copy of the query and the rego package would
happily construct a rule from it--since the rule is namespaced under
data this leads to a recursion error.

The problem is that the recursion error was caught by running the
compiler--however, since the compiler is shared by the server and
other components and since compile operations do not rollback changes
on error, this approach left OPA in an inconsistent state. Some of the
compiler data structures like the rule tree would include the PE
result but any structures built by stages after the recursion check
would be incomplete. This causes issues for the evaluator because it
(rightfully) assumes that the compiler data structures are consistent.

Since we can assume that PE results are valid and do not contain
semantic errors and we do not intend to support the lazy PE API in the
future, this commit fixes the issue/panic by modifying the rego
package to check for recursion in the rules that it constructs. This
is relatively simple since it merely has to check for prefixes in the
refs contained in the PE query result. If recursion is caught, the
rego package returns an error signalling that PE was ineffective. In
this case, the server just falls back to normal eval.

Fixes #2197

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2020-05-21 15:10:58 -07:00
Torin Sandall e5c672c29b ast: Fix locations on rules parsed from exprs
The location info on rules parsed from exprs was not ideal--it was
being set to the value of the rhs term (which is not accurate.)
This commit updates the parser helper function to reset the location
to the original expr location.

This commit also fixes an issue in the parser helper test case that
was introduced in 49a963f16a when we
used a tool to roundtrip the policy examples in the OPA codebase
to move away from the old datalog if-then syntax (":-").

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2020-05-19 06:50:50 -04:00
Patrick East 6c7d9daa94 plugins: Fix panic with /health and envoy plugin
If there was a nil status value it was still being added to the
status map, but the server didn't check before dereferencing it.

We now just check if the pointer is nil before trying to use it.

Fixes: #2396
Signed-off-by: Patrick East <east.patrick@gmail.com>
2020-05-13 13:11:19 -07:00
Patrick East 8b5cbfa07c server: Add param for diagnostic address binding
This adds a new config option for the OPA server (along with plumbing
from `opa run` downward to the server) to configure separate
diagnostic addresses to listen on. These will only be configured to
serve the /metrics and /health.

This will allow for more secure OPA deployments with the normal "data"
or "policies" API's made to be only accessible on localhost.

Fixes: #2002
Signed-off-by: Patrick East <east.patrick@gmail.com>
2020-05-13 13:11:19 -07:00
Torin Sandall c79bdc4b17 server: Fix query error test case to avoid dependency on manager start
This test case does not need to have the manager started and since the
manager now performs at least one read on start, the mock used in the
test case would cause the test to fail.

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2020-04-27 15:26:43 -07:00
Torin Sandall 05761a8dec server: Fix data races around state modified on reload
This commit fixes another data race found by running go test
-race. The server was reading state modified by the trigger handler
without using a mutex or being inside of a transaction.

Note, we should think about how we can move away from relying on the
server transactions to implement critical sections in the server as
this is bound to bite us in the future.

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2020-04-24 16:22:53 -04:00
Torin Sandall d15195df10 Report location info on pretty traces
Recently we improved the trace pretty printing to include location
information on events. Unless there's a good reason we should use this
tracer printing throughout.

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2020-04-17 06:51:28 -04:00
Patrick East b39b34760e rego: Avoid re-using transactions in compiler
Any time we do a compilation in the Rego object (or helpers) we need
to be careful to setup a conflict check that is valid for the current
context (both literal golang ctx and current storage transaction).

This isn't much of a concern if the Rego instance owns the compiler,
but if an external one was provided we need to be careful to update
the conflict check before compiling.

This was already doing the "right thing" when activating bundles, but
for partial evaluation results that were being updated on the compiler
it was not.

Fixes: #2197
Signed-off-by: Patrick East <east.patrick@gmail.com>
2020-04-06 13:54:29 -07:00
Patrick East 3ee6fdcf30 server: Specify a PartialNamespace for Rego objects
Previously we let it use the default namespace, which meant that
every cached evaluation would use the same query on the compiler..
which isn't correct. They need to be unique per path.

We'll now use a hash of the path (since it needs to be a valid var).

While doing this the logic for the Rego opts was refactored in
`makeRego` to only define the list a single time.. this should help
reduce the risk of any regressions in the future.

Fixes: #2247
Signed-off-by: Patrick East <east.patrick@gmail.com>
2020-04-06 05:54:03 -07:00
Patrick East bab96efe9a server: GET /v1/policies - Don't return partial modules
Previously we would iterate over all modules on the compiler and then
look them up by id in the store. This causes problems when there are
partial compilation results on the compiler that have not been put in
the store.

To correct this we will now reverse how it iterates, instead iterating
over a list of policies from the store and looking up their AST from
the compiler as needed.

Fixes: #2036
Signed-off-by: Patrick East <east.patrick@gmail.com>
2020-04-02 10:24:25 -07:00
Torin Sandall db030e0b14 ast: New parser implementation
This commit replaces the existing PEG generated parser with a parser
implemented by hand. The new parser is more efficient (avoiding old
problems with pathological input cases like {{{{{{{{{}}}}}}}} and
deeply-nested composites in general) and offers better opportunities
for improved error reporting (which has been improved already but
there is still room to grow.)

During the test process of implementing the new parser, we identified
a few issues that were present in the old parser. Those issues are
fixed by this commit.

Fixes #1251
Fixes #501
Fixes #2198
Fixes #2199
Fixes #2200
Fixes #2201
Fixes #2202
Fixes #2203

Co-authored-by: Torin Sandall <torinsandall@gmail.com>
Co-authored-by: Patrick East <east.patrick@gmail.com>

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
Signed-off-by: Patrick East <east.patrick@gmail.com>
2020-03-26 04:57:12 -07:00
Patrick East 54fee644b0 server: Add bundles option to /health API
This deprecates `/health?bundle` in favor of (the plural)
`/health?bundles`.

Both have the same API result, taking into account *all* bundle
statuses. This just lessen any confusion with regards to whether
`bundle` means a single bundle or all. It fits better with the new
`plugins` option.

Signed-off-by: Patrick East <east.patrick@gmail.com>
2020-02-07 09:49:41 -05:00
Patrick East c26db82d33 server: Update health check to use plugin status
The health check now supports a `?plugin` option which will make the
response depend on whether or not all configured plugins are in an OK
state.

The `bundle` parameter will now use the bundle *and* discovery plugin
statuses to determine if the bundles are ready. This corrects an issue
where discovery bundles, and bundles defined by the discovery dynamic
config, were not included with `/health?bundle=true` checks.

The URL parameter parsing has also changed to allow for omitting the
value for the `bundle` option. It will default to `true` so that
`/health?bundle=true` can be shortened to `/health?bundle`.

Fixes: #2010
Fixes: #2015
Signed-off-by: Patrick East <east.patrick@gmail.com>
2020-02-07 09:49:41 -05:00
Patrick East 9d9367d0ce decision logger: Leave the path unchanged for decisions
The logger was swapping `.`'s with `/`'s but this isn't safe when a
valid path should be /foo/a.b.c/main. The server was already doing
the right thing by passing in the url path where applicable, or only
specifying a query instead of the path.

This might affect anyone using the decision logger golang API passing
in something in dot-notation and expecting it to come out with paths.
Anyone using the HTTP server should be unaffected.

Fixes: #2031
Signed-off-by: Patrick East <east.patrick@gmail.com>
2020-01-30 14:11:05 -08:00
Torin Sandall 863e46ea8a topdown: Improve partial eval coverage
Certain portions of Rego cannot be easily inlined when they depend on
unknowns (e.g., comprehensions). In the past, if PE encountered
statements that could not be inlined, PE would simply save the
original statement regardless of whether that statement (or any of
it's dependencies) depended on unknowns. This was the safest way to
introduce PE initially and worked in many cases as long as authors
were aware of the fragment of Rego that could be PE-ed. Of course,
this places a burden on authors and also fails when constructs like
comprehensions are required.

This commit enhances the evaluator so that PE will evaluate all terms
(e.g., comprehensions, references to full extent of partial sets/objects,
etc.) as long as they do not depend on unknowns. This commit also
enhances the evaluato to support PE on expressions that include with
statements.

Support for with statements is handled by disabling inlining on any
references that are contained in the expression modified by the with
statement. This approach was chosen over #1956 because while it
generates support rules it avoids the need to re-apply with statements
to inlined expressions.

This commit also addresses #1417 because negated expressions that can
be completely evaluated will be now.

As part of this change, the evaluator has been refactored to maintain
the inlining controls as a stack (this makes with statements easier to
handle.)

name                       old time/op    new time/op    delta
InliningFullScan/1000-8      5.89ms ± 0%    5.92ms ± 3%    ~     (p=0.548 n=5+5)
InliningFullScan/10000-8     65.8ms ± 2%    65.1ms ± 0%    ~     (p=0.095 n=5+5)
InliningFullScan/300000-8     2.06s ± 2%     2.07s ± 5%    ~     (p=0.841 n=5+5)

name                       old alloc/op   new alloc/op   delta
InliningFullScan/1000-8      2.68MB ± 0%    2.68MB ± 0%  +0.01%  (p=0.008 n=5+5)
InliningFullScan/10000-8     27.4MB ± 0%    27.4MB ± 0%  +0.00%  (p=0.008 n=5+5)
InliningFullScan/300000-8     825MB ± 0%     825MB ± 0%    ~     (p=0.087 n=5+5)

name                       old allocs/op  new allocs/op  delta
InliningFullScan/1000-8       81.0k ± 0%     81.0k ± 0%  +0.01%  (p=0.008 n=5+5)
InliningFullScan/10000-8       810k ± 0%      810k ± 0%  +0.00%  (p=0.008 n=5+5)
InliningFullScan/300000-8     24.3M ± 0%     24.3M ± 0%  +0.00%  (p=0.008 n=5+5)

Fixes #1069
Fixes #653
Fixes #1421
Fixes #1417

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2020-01-28 17:41:19 -08:00
Patrick East 2699974c55 rego: Stop counting metrics for "no-op" steps
We had a number of helper methods that would start a timer, defer
stopping it, and then do something to setup a Rego object for doing
its thing.

Many of these would have a check and then skip the step, but the timer
would get a little bit of time accounted for it anyway for the `if`
check and handling the deferred stop function.

This refactors as many of these as I could find to do the if check
and shortcut out before starting the timer. This will prevent any of
the "no-op" steps from showing up in metrics.

Signed-off-by: Patrick East <east.patrick@gmail.com>
2019-12-18 11:07:14 -08:00
Patrick East 051c3b8273 server: Correct server input parsing metric
The metric was using `metrics.RegoQueryParse` but it isn't actually
doing the query parse there. It is parsing the input document.

Signed-off-by: Patrick East <east.patrick@gmail.com>
2019-12-18 11:07:14 -08:00
Patrick East feaf745da9 server: Cache PreparedEvalQuery's for data requests
This adds in caching of prepared queries for versioned and unversioned
data queries (POST/GET to `/`, `/data`, and `/v1/data`).

The cache has a max size of 100 and just starts acting as a circular
buffer for queries (FIFO, no smarts for LRU caching or anything). It
seems like it would be unlikely for these API's to hit the cache max
size. Most OPA use-cases have a single query that is re-used over
and over with different inputs.

There is a new metric `counter_server_query_cache_hit` which will
show whether or not a request used the query cache or not. It is there
primarily to help explain away why sometimes a handful of the other
metrics aren't there (the query parse/compile/etc).

In the future this could be added to the query API's too. This change
does not touch anything other than the "data" API's.

Closes: #1567
Signed-off-by: Patrick East <east.patrick@gmail.com>
2019-12-18 11:07:14 -08:00
Patrick East f1b9c7586b Ensure all errors are in JSON formatted CLI output
Previously if the errors passed into the presentation Output were not
structured w/ JSON tags for marshaling the error would be an empty
string.

This changes to wrap the errors with a struct in cases where they
would otherwise not be formatted. We do this by forcing every error
into a structure and translating known error types into it.

Fixes: #1726
Fixes: #1724
Signed-off-by: Patrick East <east.patrick@gmail.com>
2019-09-27 10:55:31 -04:00
Patrick East b48c534722 Run make fmt with new goimports cmd
Signed-off-by: Patrick East <east.patrick@gmail.com>
2019-09-27 09:55:11 -04:00
Patrick East 9c9bc29f5a server: Fix panic in /health?bundle=true
The issue was that with bundles loaded from the file system we would
not initialize the mutex used for checking bundle status.

This fixes the initialization and prevents the error. Health status
works as expected now.

Fixes: #1703
Signed-off-by: Patrick East <east.patrick@gmail.com>
2019-08-29 18:37:43 -07:00
Torin Sandall df281fd020 server: Wrap decision log error messages
Previously the server didn't wrap the error messages which made it
hard to determine the source of internal errors coming back from OPA
when deployed with a custom decision logger.

Fixes #1367

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2019-08-22 14:48:56 -04:00
Torin Sandall b0523466c1 Refactor metric provider implementation
* Remove metric provider config to avoid introducing new public
  interfaces. Since there is only one provider (prometheus) and it
  doesn't have any configurable settings, remove the configuration
  changes for now. We can always add these in the future.

* Remove dummy metric provider implementation. This isn't needed now
  that we're using the metrics.Metrics interface instead of
  metrics.GlobalMetrics.

* Remove metrics.GlobalMetrics in favour of metrics.Metrics. Move the
  HTTP handler instrumentation interfaces into the server package to
  avoid coupling the metrics package to the net/http package.

* Refactor the prometheus provider to implement the metrics.Metrics
  interface. Since the prometheus registry can error on Gather()
  calls, the provider has been updated to accept a logger and use ti
  when the Gather() call fails. This doesn't affect any public
  interfaces so it can be revisited in future if needed. Alteratnively
  we could add a Gather() interface onto metrics.Metrics which could
  return the error.

* Refactor status plugin to include metrics in status update by
  default. Users implementing the status API are likely to need
  performance metrics to gauge the OPA's health. Moreover if they are
  implementing the status API it's unlikely they will want to poll the
  /metrics endpoint on the OPA HTTP API (which may not even be
  exposed.)

* Move the prometheus endpoint test case into the e2e package so the
  server package has no dependencies on prometheus anymore.

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2019-08-15 15:08:38 -04:00