v0.7 Release
We're happy to announce the v0.7 release of OPA. This release includes language improvements as well as initial support for monitoring via Prometheus. For the full list of interesting changes see GitHub Releases. The rest of this post introduces the major features introduced in v0.7.
Nested Expressions
Before v0.7, OPA only supported one level of embedding on expressions. For example:
- You could write
x = y * 2; z = x / 3 - But you could not write
z = (y * 2) / 3
For simple policies that only rely on boolean expressions and perform a few built-in calls, the limitation was not an issue. However, in more sophisticated policies that perform a series of arithmetic or string manipulation, policy authors had to introduce intermediate variables, which meant coming up with good variable names (which we all know is hard.)
With support for nested expressions, policies can be expressed more concisely and without the need for extraneous variables. For example, the policy below computes a risk score for Terraform changes. Before v0.7, the policy required extra statements to sum the products:
# compute risk score before v0.7
score = s {
all = [x | w = weights[type]
del = w.delete * num_deletes[type]
cre = w.create * num_creates[type]
upd = w.update * num_updates[type]
x1 = del + cre
x2 = x1 + upd]
sum(all, s)
}
In v0.7 with support for nested expressions we can write this simply as:
score = sum([x | w = weights[type]
x = (w.delete * num_deletes[type] +
w.create * num_creates[type] +
w.update * num_updates[type])])
Similarly, chains of string manipulation operations are much more concise now. Before v0.7:
decoded_str = base64url.decode(str)
trimmed_str = trim(decoded_str, "/")
parts = split(trimmed_str, "/")
After v0.7:
parts = split(trim(base64url.decode(str), "/"))
Assignment and Comparison Operators
In OPA, the = operator performs assignment and comparison at the same time. If you come from an imperative or functional programming background, this can be a bit confusing at first. To help improve the user experience for first time OPA users, we have introduced new operators for assignment (:=) and comparison (==) that behave the way you would expect coming from a traditional programming language.
The := operator allows users to declare local variables within the current scope by assigning a value. Unlike the = operator, variables appearing on the left hand side of the expression will shadow symbols in the global scope. Furthermore, redeclaration of a variable in the same scope is treated as an error.
The == operator allows users to compare two values. Unlike the = operator, variables appearing on either side of the operator must be set elsewhere in the query (otherwise an error is reported.)
These changes are backwards compatible. Existing policies are unaffected and you can continue to develop policies without using the new operators if you like.
Built-in Functions
OPA supports 50+ built-in functions. The documentation for built-in functions can be found in the Language Reference. Internally, OPA makes it relatively easy to add new built-in functions.
This release adds several new built-in functions:
regex.glob_intersectchecks if two regex patterns intersect.http.sendexecutes a HTTP request and returns the response.time.datereturns[YYYY, MM, DD]from the time since epoch provided as input.time.clockreturns[HH, mm, SS]for the day of the time since epoch provided as input.intersectionreturns the n-way intersection of sets provided as input.unionreturns the n-way union of sets provided as input.
Prometheus /metrics Endpoint
As we continue to harden and optimize OPA, we have begun to focus more on monitoring and diagnostic features. This release adds support for a /metrics API endpoint that exposes high level performance metrics so that users can monitor OPA using the Prometheus project. See the new Monitoring & Diagnostics documentation for more details.
