Skip to content

Commit

Permalink
# This is a combination of 38 commits.
Browse files Browse the repository at this point in the history
# This is the 1st commit message:

finalizing changes for formatting with sprintf

Signed-off-by: Damien Burks <damien@damienjburks.com>

# This is the commit message open-policy-agent#2:

updating changes to allow for multiple format strings

Signed-off-by: Damien Burks <damien@damienjburks.com>

# This is the commit message open-policy-agent#3:

fixing golint issues

Signed-off-by: Damien Burks <damien@damienjburks.com>

# This is the commit message open-policy-agent#4:

fixing golint issues

Signed-off-by: Damien Burks <damien@damienjburks.com>

# This is the commit message open-policy-agent#5:

making recommended change: package level variable

Signed-off-by: Damien Burks <damien@damienjburks.com>

# This is the commit message open-policy-agent#6:

adding support for explicit argument indexes

Signed-off-by: Damien Burks <damien@damienjburks.com>

# This is the commit message open-policy-agent#7:

format: don't add 'in' keyword import when 'every' is there (open-policy-agent#4607)

Also ensure that added imports have a location set.

Previously, `opa fmt` on the added test file would have panicked
because the import hadn't had a location.

Fixes open-policy-agent#4606.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
# This is the commit message open-policy-agent#8:

ast+topdown+planner: allow for mocking built-in functions via "with" (open-policy-agent#4540)

With this change, we can replace calls to built-in functions via `with`. The replacement
can either be a value -- which will be used as the return value for every call to the
mocked built-in -- or a reference to a non-built-in function -- when the results need
to depend on the call's arguments.

Compiler, topdown, and planner have been adapted in this change. The included
docs changes describe the replacement options further.

Fixes first part of open-policy-agent#4449. (Missing are non-built-in functions as mock targets.)

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
# This is the commit message open-policy-agent#9:

build(deps): bump google.golang.org/grpc from 1.45.0 to 1.46.0 (open-policy-agent#4617)


# This is the commit message open-policy-agent#10:

docs/policy-testing: use assignment operator in mocks (open-policy-agent#4618)

Additionally, simplify one test example.

Signed-off-by: Anders Eknert <anders@eknert.com>
# This is the commit message open-policy-agent#11:

cmd/capabilities: expose capabilities through CLI (open-policy-agent#4588)

There is a new command argument "capabilities". With this, it is
possible to print the current capabilities version, show all
capabilities versions & print any capabilities version, without the need
of a file. Moreover, for the other commands which use the --capabilities
flag, it is possible to give only the version number, without specifying
a file. However, there are no breaking changes for those who use the
capabilities file as an input for the flag. Unit tests were also
written, in order to test the new argument and the changes made in ast.

Fixes: open-policy-agent#4236

Signed-off-by: IoannisMatzaris <matzarisioannis@gmail.com>
# This is the commit message open-policy-agent#12:

format,eval: don't use source locations when formatting PE output (open-policy-agent#4611)

* format: allow ignoreing source locations
* cmd/eval: format disregarding source locations for partial result

Before, we'd see this output:
```
$ opa eval -p -fsource 'time.clock(input.x)==time.clock(input.y)'
# Query 1
time.clock(time.clock(input.x), input.y)
```

Now, we get the proper answer: `time.clock(input.y, time.clock(input.x))`.

Note that it's a _display_ issue; the JSON output of PE has not been affected.

Fixes open-policy-agent#4609.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
# This is the commit message open-policy-agent#13:

build(deps): bump github/codeql-action from 1 to 2 (open-policy-agent#4621)

Bumps [github/codeql-action](https://github.com/github/codeql-action) from 1 to 2.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](github/codeql-action@v1...v2)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
# This is the commit message open-policy-agent#14:

status: Remove activeRevision label on all but one metric (open-policy-agent#4600)

Having one activeRevision label on each of the prometheus metrics emitted
by the status plugin has proven to be problematic with a large number of
bundles. So with this change,

1. we keep the activeRevision label (just on) the last_success_bundle_activation metric.
2. the gauge gets reset, so we only keep the last active_revision (instead of keeping
   them all and therefore avoiding the situation where the /metrics output grows indefinitely)

Fixes open-policy-agent#4584.

Signed-off-by: cmuraru <cmuraru@adobe.com>
# This is the commit message open-policy-agent#15:

website: add playground button to navbar (open-policy-agent#4622)

Addressing one tiny bit of open-policy-agent#4614.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
# This is the commit message open-policy-agent#16:

topdown/net: require prefix length for IPv6 in net.cidr_merge (open-policy-agent#4613)

There are no default prefixes in IPv6, so if an IPv6 without a prefix is fed into
net.cidr_merge, we'll return a non-halt error now.

Before, we'd fail in various ways if a prefix-less IPv6 was fed into
`net.cidr_merge`. With only one, we'd return `[ "<nil>" ]`, with two,
we'd panic.

Fixes open-policy-agent#4596.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
# This is the commit message open-policy-agent#17:

Dockerfile: add source annotation (open-policy-agent#4626)

`org.opencontainers.image.source` URL to get source code for building the image (string)

https://github.com/opencontainers/image-spec/blob/main/annotations.md

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
# This is the commit message open-policy-agent#18:

build(deps): bump github.com/fsnotify/fsnotify v1.5.2 -> v1.5.4 (open-policy-agent#4628)

https://github.com/fsnotify/fsnotify/releases/tag/v1.5.4

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
# This is the commit message open-policy-agent#19:

docs: update version in kubernetes examples (open-policy-agent#4627)

Signed-off-by: yongen.pan <yongen.pan@daocloud.io>
# This is the commit message open-policy-agent#20:

bundle/status: Include bundle type in status information

OPA has support for Delta Bundles. The status object already
contains valuable information such as last activation timestamp but
does not specify if the bundle was a canonical snapshot or delta.

This change updates the bundle.Status object to include the
bundle type string: either "snapshot" or "delta". This can be useful
for status endpoints to differentiate between the bundle types.

Issue: 4477

Signed-off-by: Bryan Fulton <bryan@styra.com>

# This is the commit message open-policy-agent#21:

ast+topdown+planner: replacement of non-built-in functions via 'with' (open-policy-agent#4616)

Follow-up to open-policy-agent#4540

We can now mock functions that are user-defined:

    package test

    f(_) = 1 {
        input.x = "x"
    }
    p = y {
        y := f(1) with f as 2
    }

...following the same scoping rules as laid out for built-in mocks.
The replacement can be a value (replacing all calls), or a built-in,
or another non-built-in function.

Also addresses bugs in the previous slice:
* topdown/evalCall: account for empty rules result from indexer
* topdown/eval: capture value replacement in PE could panic

Note: in PE, we now drop 'with' for function mocks of any kind:

These are always fully replaced in the saved support modules, so
this should be OK.

When keeping them, we'd also have to either copy the existing definitions
into the support module; or create a function stub in it.

Fixes open-policy-agent#4449.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
# This is the commit message open-policy-agent#22:

format: keep whitespaces for multiple indented same-line withs (open-policy-agent#4635)

Fixes open-policy-agent#4634.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
# This is the commit message open-policy-agent#23:

downloader: support for downloading bundles from an OCI registry (open-policy-agent#4558)

Initial support for open-policy-agent#4518.

Configuration uses the 'services' config for registries, via the "type: oci" field.
Bundles configured to pull from that service will then use OCI.

```
services:
  ghcr-registry:
    url: https://ghcr.io
    type: oci
bundles:
  authz:
    service: ghcr-registry
    resource: ghcr.io/${ORGANIZATION}/${REPOSITORY}:${TAG}
    persist: true
    polling:
      min_delay_seconds: 60
      max_delay_seconds: 120
persistence_directory: ${PERSISTENCE_PATH}
```

Service credentials are supported: if you want to pull from a private registry,
use
```
services:
  ghcr-registry:
    url: https://ghcr.io
    type: oci
    credentials:
      bearer:
        token: ${GH_PAT}
```

If no `persistence_directory` is configured, the data is stored in a directory under /tmp.

See docs/devel/OCI.md for manual steps to test this feature with some
OCI registry (like ghcr.io).

Signed-off-by: carabasdaniel <dani@aserto.com>
# This is the commit message open-policy-agent#24:

Prepare v0.40.0 Release (open-policy-agent#4631)

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
# This is the commit message open-policy-agent#25:

Prepare v0.41.0 development (open-policy-agent#4636)

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
# This is the commit message open-policy-agent#26:

docs: Adding example for `rego.metadata.role()` usage (open-policy-agent#4640)

Signed-off-by: Johan Fylling <johan.dev@fylling.se>
# This is the commit message open-policy-agent#27:

build(deps): bump oras.land/oras-go from 1.1.0 to 1.1.1 (open-policy-agent#4643)

Bumps [oras.land/oras-go](https://github.com/oras-project/oras-go) from 1.1.0 to 1.1.1.
- [Release notes](https://github.com/oras-project/oras-go/releases)
- [Commits](oras-project/oras-go@v1.1.0...v1.1.1)

---
updated-dependencies:
- dependency-name: oras.land/oras-go
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
# This is the commit message open-policy-agent#28:

build(deps): bump OpenTelemetry 1.6.3 -> 1.7.0 (open-policy-agent#4649)

https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.7.0
https://github.com/open-telemetry/opentelemetry-go-contrib/releases/tag/v1.7.0

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
# This is the commit message open-policy-agent#29:

build(deps): bump github.com/containerd/containerd from 1.6.2 to 1.6.3 (open-policy-agent#4654)

Bumps [github.com/containerd/containerd](https://github.com/containerd/containerd) from 1.6.2 to 1.6.3.
- [Release notes](https://github.com/containerd/containerd/releases)
- [Changelog](https://github.com/containerd/containerd/blob/main/RELEASES.md)
- [Commits](containerd/containerd@v1.6.2...v1.6.3)

---
updated-dependencies:
- dependency-name: github.com/containerd/containerd
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
# This is the commit message open-policy-agent#30:

Update k8s examples to the latest schema (open-policy-agent#4655)

Signed-off-by: Víctor Martínez Bevià <vicmarbev@gmail.com>
# This is the commit message open-policy-agent#31:

Fix incorrect padding claims (open-policy-agent#4657)

Signed-off-by: Anders Eknert <anders@eknert.com>
# This is the commit message open-policy-agent#32:

build(deps): bump github.com/containerd/containerd from 1.6.3 to 1.6.4 (open-policy-agent#4662)

Bumps [github.com/containerd/containerd](https://github.com/containerd/containerd) from 1.6.3 to 1.6.4.
- [Release notes](https://github.com/containerd/containerd/releases)
- [Changelog](https://github.com/containerd/containerd/blob/main/RELEASES.md)
- [Commits](containerd/containerd@v1.6.3...v1.6.4)

---
updated-dependencies:
- dependency-name: github.com/containerd/containerd
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
# This is the commit message open-policy-agent#33:

build(deps): bump docker/setup-qemu-action from 1 to 2 (open-policy-agent#4668)


# This is the commit message open-policy-agent#34:

build(deps): bump docker/setup-buildx-action from 1 to 2 (open-policy-agent#4669)

Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 1 to 2.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](docker/setup-buildx-action@v1...v2)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
# This is the commit message open-policy-agent#35:

build(deps): github.com/bytecodealliance/wasmtime-go 0.35.0 -> 0.36.0 (open-policy-agent#4652)

* build(deps): bump wasmtime-go: 0.35.0 -> 0.36.0
* internal/wasm: adapt to using epoch-based interruption

Looks like we don't get frames for this.

Also, there is currentlty no better way than comparing the message,
as the trap code isn't surfaced (yet).

Fixes open-policy-agent#4663.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
# This is the commit message open-policy-agent#36:

ecosystem: Add Sansshell (open-policy-agent#4674)


Signed-off-by: James Chacon <james.chacon@snowflake.com>
# This is the commit message open-policy-agent#37:

topdown: Add units.parse builtin (open-policy-agent#4676)

This function works on all base decimal and binary SI units of the set:

    m, K/Ki, M/Mi, G/Gi, T/Ti, P/Pi, and E/Ei

Note: Unlike `units.parse_bytes`, this function is case sensitive.

Fixes open-policy-agent#1802.

Signed-off-by: Philip Conrad <philipaconrad@gmail.com>
# This is the commit message open-policy-agent#38:

docs/contrib-code: Add capabilities step to built-in functions tutorial (open-policy-agent#4677)

Signed-off-by: Philip Conrad <philipaconrad@gmail.com>
  • Loading branch information
damienjburks committed May 18, 2022
1 parent 1ca73a0 commit d208414
Show file tree
Hide file tree
Showing 678 changed files with 65,631 additions and 3,011 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/codeql-analysis.yml
Expand Up @@ -43,7 +43,7 @@ jobs:

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
Expand All @@ -59,4 +59,4 @@ jobs:
make build
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
uses: github/codeql-action/analyze@v2
2 changes: 1 addition & 1 deletion .github/workflows/post-merge.yaml
Expand Up @@ -155,7 +155,7 @@ jobs:
path: _release

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v2

- name: Deploy OPA Edge
env:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/post-tag.yaml
Expand Up @@ -95,7 +95,7 @@ jobs:
path: _release

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v2

- name: Build and Deploy OPA Docker Images
id: build-and-deploy
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pull-request.yaml
Expand Up @@ -199,7 +199,7 @@ jobs:
uses: open-policy-agent/setup-opa@v1

- name: Set up QEMU
uses: docker/setup-qemu-action@v1
uses: docker/setup-qemu-action@v2
with:
platforms: arm64

Expand Down
159 changes: 159 additions & 0 deletions CHANGELOG.md
Expand Up @@ -5,6 +5,165 @@ project adheres to [Semantic Versioning](http://semver.org/).

## Unreleased

## 0.40.0

This release contains a number of fixes and enhancements.

### Metadata introspection

The _rich metadata_ added in the v0.38.0 release can now be introspected
from the policies themselves!

package example

# METADATA
# title: Edits by owner only
# description: |
# Only the owner is allowed to edit their data.
deny[{"allowed": false, "message": rego.metadata.rule().description}] {
input.user != input.owner
}

This snippet will evaluate to

[{
"allowed": false,
"message": "Only the owner is allowed to edit their data.\n"
}]

Both the rule's metadata can be accessed, via `rego.metadata.rule()`, and the
entire chain of metadata attached to the rule via the various scopes that different
metadata annotations can have, via `rego.metadata.chain()`.

All the details can be found in the documentation of [these new built-in functions](https://www.openpolicyagent.org/docs/v0.40.0/policy-reference/#rego).

### Function mocking

It is now possible to **mock functions** in tests! Both built-in and non-built-in
functions can be mocked:

package authz
import data.jwks.cert
import data.helpers.extract_token

allow {
[true, _, _] = io.jwt.decode_verify(extract_token(input.headers), {"cert": cert, "iss": "corp.issuer.com"})
}

test_allow {
allow
with input.headers as []
with data.jwks.cert as "mock-cert"
with io.jwt.decode_verify as [true, {}, {}] # mocked built-in
with extract_token as "my-jwt" # mocked non-built-in
}

For further information about policy testing with data and function mock, see [the Policy Testing docs](https://www.openpolicyagent.org/docs/v0.40.0/policy-testing/#data-and-function-mocking)
All details about `with` can be found in its [Policy Language section](https://www.openpolicyagent.org/docs/v0.40.0/policy-language/#with-keyword).

### Assignments with `:=`

Remaining restrictions around the use of `:=` in rules and functions have been lifted ([#4555](https://github.com/open-policy-agent/opa/issues/4555)).
These constructs are now valid:

check_images(imgs) := x { # function
# ...
}

allow := x { # rule
# ...
}

response[key] := object { # partial object rule
# ...
}

In the wake of this, rules may now be "redeclared", i.e. you can use `:=` for more than one rule body:

deny := x {
# body 1
}
deny := x {
# body 2
}

This was forbidden before, but didn't serve a real purpose: it would catch trivial-to-catch errors
like

p := 1
p := 2 # redeclared

But it would do no good in more difficult to debug "multiple assignment" problems like

p := x {
some x in [1, 2, 3]
}

### Tooling, SDK, and Runtime

- Status Plugin: Remove activeRevision label on all but one Prometheus metric ([#4584](https://github.com/open-policy-agent/opa/issues/4584)) reported and authored by @costimuraru
- Status: Include bundle type ("snapshot" or "delta") in status information
- `opa capabilities`: Expose capabilities through CLI, and allow using versions when passing `--capabilities v0.39.0` to the various commands ([#4236](https://github.com/open-policy-agent/opa/issues/4236)) authored by @IoannisMatzaris <!-- FC -->
- Logging: Log warnings at WARN level not ERROR, authored by @damienjburks
- Runtime: Persist activated bundle Etag to store ([#4544](https://github.com/open-policy-agent/opa/issues/4544))
- `opa eval`: Don't use source locations when formatting partially evaluated output ([#4609](https://github.com/open-policy-agent/opa/issues/4609))
- `opa inspect`: Fixing an issue where some errors encountered by the inspect command aren't properly reported
- `opa fmt`: Fix a bug with missing whitespace when formatting multiple `with` statements on one indented line ([#4634](https://github.com/open-policy-agent/opa/issues/4634))

#### Experimental OCI support

When configured to do so, OPA's bundle and discovery plugins will retrieve bundles from **any OCI registry**.
Please see [the Services Configuration section](https://www.openpolicyagent.org/docs/v0.40.0/configuration/#services)
for details.

Note that at this point, it's best considered a "feature preview". Be aware of this:
- Bundles are not cached, but re-retrieved and activated periodically.
- The persistence directory used for storing retrieved OCI artifacts is not yet managed by OPA,
so its content may accumulate. By default, the OCI downloader will use a temporary file location.
- The documentation on how to push bundles to an OCI repository currently only exists in the development
docs, see [OCI.md](https://github.com/open-policy-agent/opa/blob/v0.40.0/docs/devel/OCI.md).

Thanks to @carabasdaniel for starting the work on this!

### Rego and Topdown

- Builtins: Require prefix length for IPv6 in `net.cidr_merge` ([#4596](https://github.com/open-policy-agent/opa/issues/4596)), reported by @alexhu20
- Builtins: `http.send` can now parse and cache YAML responses, analogous to JSON responses
- Parser: Guard against invalid domains for "some" and "every", reported by @doyensec
- Formatting: Don't add 'in' keyword import when 'every' is there ([#4606](https://github.com/open-policy-agent/opa/issues/4606))

### Documentation

- Policy Language: Reorder Universal Quantification content, stress `every` over other constructions ([#4603](https://github.com/open-policy-agent/opa/issues/4603))
- Language pages: Use assignment operator where it's allowed.
- SSH Tutorial: Use bundle API
- Annotations: Update "Custom" annotation section
- Cloudformation: Fix markup and add warning related to booleans
- Blogs: mention OAuth2 and OIDC blog posts

### Website + Ecosystem

- Redirect previous patch releases to latest patch release ([#4225](https://github.com/open-policy-agent/opa/issues/4225))
- Add playground button to navbar
- Add SRI to static html files
- Remove right margin on sidebar (#4529) (authored by @orweis)
- Show yellow banner for old version (#4533)
- Remove unused variables to avoid error in strict mode(#4534) (authored by @panpan0000)
- Ecosystem:
- Add AWS CloudFormation Hook
- Add GKE policy automation
- Add permit.io (authored by @ozradi)
- Add Magda (authored by @t83714)

### Miscellaneous

- Workflow: no content permissions for GitHub action 'post-release', authored by @naveensrinivasan
- Various dependency bumps, notably:
- OpenTelemetry-go: 1.6.1 -> 1.6.3
- go.uber.org/automaxprocs: 1.4.0 -> 1.5.1
- Binaries and Docker images are now built using Go 1.18.1.
- Dockerfile: add source annotation (#4626)

## 0.39.0

This release contains a number of fixes and enhancements.
Expand Down
1 change: 1 addition & 0 deletions Dockerfile
Expand Up @@ -7,6 +7,7 @@ ARG BASE
FROM ${BASE}

LABEL org.opencontainers.image.authors="Torin Sandall <torinsandall@gmail.com>"
LABEL org.opencontainers.image.source="https://github.com/open-policy-agent/opa"

# Temporarily allow us to identify whether running from within an offical
# Docker image, so that we may print a warning when uid or gid == 0 (root)
Expand Down
13 changes: 13 additions & 0 deletions ast/builtins.go
Expand Up @@ -255,6 +255,7 @@ var DefaultBuiltins = [...]*Builtin{
GlobQuoteMeta,

// Units
UnitsParse,
UnitsParseBytes,

// UUIDs
Expand Down Expand Up @@ -1123,6 +1124,18 @@ var NumbersRange = &Builtin{
* Units
*/

// UnitsParse converts strings like 10G, 5K, 4M, 1500m and the like into a
// number. This number can be a non-integer, such as 1.5, 0.22, etc.
var UnitsParse = &Builtin{
Name: "units.parse",
Decl: types.NewFunction(
types.Args(
types.S,
),
types.N,
),
}

// UnitsParseBytes converts strings like 10GB, 5K, 4mb, and the like into an
// integer number of bytes.
var UnitsParseBytes = &Builtin{
Expand Down
52 changes: 51 additions & 1 deletion ast/capabilities.go
Expand Up @@ -5,14 +5,19 @@
package ast

import (
"bytes"
"fmt"
"io"
"os"
"sort"
"strings"

caps "github.com/open-policy-agent/opa/capabilities"
"github.com/open-policy-agent/opa/internal/wasm/sdk/opa/capabilities"
"github.com/open-policy-agent/opa/util"
)

// Capabilities defines a structure containing data that describes the capablilities
// Capabilities defines a structure containing data that describes the capabilities
// or features supported by a particular version of OPA.
type Capabilities struct {
Builtins []*Builtin `json:"builtins"`
Expand Down Expand Up @@ -63,3 +68,48 @@ func LoadCapabilitiesJSON(r io.Reader) (*Capabilities, error) {
var c Capabilities
return &c, d.Decode(&c)
}

// LoadCapabilitiesVersion loads a JSON serialized capabilities structure from the specific version.
func LoadCapabilitiesVersion(version string) (*Capabilities, error) {
cvs, err := LoadCapabilitiesVersions()
if err != nil {
return nil, err
}

for _, cv := range cvs {
if cv == version {
cont, err := caps.FS.ReadFile(cv + ".json")
if err != nil {
return nil, err
}

return LoadCapabilitiesJSON(bytes.NewReader(cont))
}

}
return nil, fmt.Errorf("no capabilities version found %v", version)
}

// LoadCapabilitiesFile loads a JSON serialized capabilities structure from a file.
func LoadCapabilitiesFile(file string) (*Capabilities, error) {
fd, err := os.Open(file)
if err != nil {
return nil, err
}
defer fd.Close()
return LoadCapabilitiesJSON(fd)
}

// LoadCapabilitiesVersions loads all capabilities versions
func LoadCapabilitiesVersions() ([]string, error) {
ents, err := caps.FS.ReadDir(".")
if err != nil {
return nil, err
}

var capabilitiesVersions []string
for _, ent := range ents {
capabilitiesVersions = append(capabilitiesVersions, strings.Replace(ent.Name(), ".json", "", 1))
}
return capabilitiesVersions, nil
}
39 changes: 39 additions & 0 deletions ast/capabilities_test.go
@@ -1,7 +1,10 @@
package ast

import (
"path"
"testing"

"github.com/open-policy-agent/opa/util/test"
)

func TestParserCatchesIllegalCapabilities(t *testing.T) {
Expand Down Expand Up @@ -83,3 +86,39 @@ func TestParserCapabilitiesWithWildcardOptInAndOlderOPA(t *testing.T) {
t.Fatal("unexpected error:", err)
}
}

func TestLoadCapabilitiesVersion(t *testing.T) {

capabilitiesVersions, err := LoadCapabilitiesVersions()
if err != nil {
t.Fatal("expected success", err)
}

if len(capabilitiesVersions) == 0 {
t.Fatal("expected a non-empty array of capabilities versions")
}
for _, cv := range capabilitiesVersions {
if _, err := LoadCapabilitiesVersion(cv); err != nil {
t.Fatal("expected success", err)
}
}
}

func TestLoadCapabilitiesFile(t *testing.T) {

files := map[string]string{
"test-capabilities.json": `
{
"builtins": []
}
`,
}

test.WithTempFS(files, func(root string) {
_, err := LoadCapabilitiesFile(path.Join(root, "test-capabilities.json"))
if err != nil {
t.Fatal("expected success", err)
}
})

}

0 comments on commit d208414

Please sign in to comment.