Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Charles/eopa engine #1000

Merged
merged 39 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
149ce1e
check in PoC with capabilities
charlesdaniels Aug 20, 2024
88f1ab0
remove eopa capabilities
charlesdaniels Aug 20, 2024
655a373
use enterprise-opa's capabilities package
charlesdaniels Aug 20, 2024
2c89dd7
try to fix go.mod
charlesdaniels Aug 20, 2024
eeb16a7
LSP+capabilities working correctly
charlesdaniels Aug 20, 2024
ceae653
refactor LSP capabilities handling
charlesdaniels Aug 20, 2024
f92073f
implement URL-based caps lookup
charlesdaniels Aug 21, 2024
70e1991
unify config + LSP on new capabilities.Lookup()
charlesdaniels Aug 21, 2024
b666348
unbreak tests
charlesdaniels Aug 21, 2024
247ebc6
remove global lock
charlesdaniels Aug 22, 2024
4cb276a
simplify http access in capabilities package
charlesdaniels Aug 22, 2024
327cffc
WiP: initial work to fetch eopa caps
charlesdaniels Aug 22, 2024
804d850
fully implement do.rq fetch
charlesdaniels Aug 23, 2024
d159426
fix broken caps, add tests to embedded
charlesdaniels Aug 23, 2024
0e60495
remove enterprise-opa dep
charlesdaniels Aug 23, 2024
c43422f
move capabilities to be internal
charlesdaniels Aug 26, 2024
95604b4
move docs into README
charlesdaniels Aug 26, 2024
1358083
add LSP test for new embedded EOPA caps
charlesdaniels Aug 27, 2024
aaa18e7
remove debug statements
charlesdaniels Aug 27, 2024
19fbb99
drop pre-1.0.0 eopa tags
charlesdaniels Aug 27, 2024
0cd5e4f
fix lint errors
charlesdaniels Aug 27, 2024
e94e99c
fix typo in do.rq
charlesdaniels Aug 27, 2024
1098d12
improve rq.write comprehension
charlesdaniels Aug 27, 2024
3713d41
fix incorrect test
charlesdaniels Aug 27, 2024
8689de7
apply golangci fixes
charlesdaniels Aug 27, 2024
35a1e74
fix some linter issues
charlesdaniels Aug 27, 2024
d11047e
use some ... in in fetch task
charlesdaniels Aug 28, 2024
a8d9442
fix remaining lint issues
charlesdaniels Aug 28, 2024
4d0b937
fix lint issue with main.rego
charlesdaniels Aug 28, 2024
723c057
remove scope:document from report
charlesdaniels Aug 28, 2024
eda0a23
format server_test
charlesdaniels Aug 28, 2024
fc39b64
restore metadata for report
charlesdaniels Aug 28, 2024
52dc471
fix lint issue
charlesdaniels Aug 28, 2024
caf0860
format server_test
charlesdaniels Aug 28, 2024
03376bc
use nolint to make golint stop complaining
charlesdaniels Aug 28, 2024
dbfd68c
explicitly wait for builtins map to update
charlesdaniels Aug 28, 2024
e893548
implement PR review suggestions
charlesdaniels Aug 29, 2024
d6a4e98
temporarily increase server_test timeout
charlesdaniels Aug 29, 2024
d3f1f15
Revert "temporarily increase server_test timeout"
charlesdaniels Aug 29, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,28 @@ capabilities:
type: object
```

### Loading Capabilities from URLs

Starting with Regal version TODO, Regal can load capabilities from URLs with
the `http`, or `https` schemes using the `capabilities.from.url` config key.
For example, to load capabilities from `https://example.org/capabilities.json`,
this configuration could be used:

```yaml
capabilities:
from:
url: https://example.org/capabilities.json
```

### Supported Engines

Regal includes capabilities files for the following engines:

| Engine | Website | Description |
|--------|---------|-------------|
| `opa` | [OPA website](https://www.openpolicyagent.org/) | Open Policy Agent |
| `eopa` | [Enterprise OPA website](https://www.styra.com/enterprise-opa/) | Styra Enterprise OPA |

## Exit Codes

Exit codes are used to indicate the result of the `lint` command. The `--fail-level` provided for `regal lint` may be
Expand Down
160 changes: 160 additions & 0 deletions build/do.rq
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,19 @@ package script

import future.keywords

# Path to Regal's project root. (./build/do.rq/../.. => ./)
regal_root := rq.abs(rq.dir(rq.dir(rq.scriptpath())))

build_dir := rq.joinpath([regal_root, "build"])

# Root of the directory hierarchy where engine-specific capabilities JSON for
# embedding into the Regal binary should be placed.
embedded_caps_dir := rq.joinpath([regal_root, "internal", "capabilities", "embedded"])

# Directory where EOPA-specific JSON capabilities for embedding should be
# placed.
eopa_caps_dir := rq.joinpath([embedded_caps_dir, "eopa"])

main contains do[what] if some what in rq.args()
main contains job[what] if some what in rq.args()
main contains job.tasks if {
Expand Down Expand Up @@ -93,6 +106,14 @@ job.test {
test
}

# METADATA
# title: fetch
# description: Fetch third-party artifacts, such as capabilities JSON files for engines.
job.fetch {
fetch_engine_caps
}


# METADATA
# title: lint
# description: Run `regal lint` on the Regal bundle
Expand Down Expand Up @@ -141,6 +162,7 @@ test {

e2e {
run("go test -tags e2e ./e2e")
run("go test -tags integration ./internal/capabilities")
}

lint {
Expand All @@ -163,6 +185,137 @@ write_readme {
run("./regal table --write-to-readme bundle")
}

fetch_engine_caps {
fetch_eopa_caps
}

fetch_eopa_caps {

# git ls-remote --tags output looks like this:
#
# ...
# bab5bdd4bb2de45c7d1bcf5d7b5df3c61a131f38 refs/tags/v1.0.0
# bab5bdd4bb2de45c7d1bcf5d7b5df3c61a131f38 refs/tags/v1.0.1
# 9ace37dda9859a1afd2fcd6a87dd7f1955be4dc4 refs/tags/v1.10.1
# ...
#
# so .stdout will look like this:
#
# ...
# [
# "bab5bdd4bb2de45c7d1bcf5d7b5df3c61a131f38\trefs",
# "tags",
# "v1.0.0"
# ],
# [
# "bab5bdd4bb2de45c7d1bcf5d7b5df3c61a131f38\trefs",
# "tags",
# "v1.0.1"
# ],
# [
# "bab5bdd4bb2de45c7d1bcf5d7b5df3c61a131f38\trefs",
# "tags",
# "v1.1.0"
# ],
# ...

print("fetching tags for enterprise-opa repository")

eopa_tags_result := rq.run([
"git",
"ls-remote",
"--tags",
"https://github.com/styrainc/enterprise-opa"
], {
"stdout_spec": {
"format": "raw",
"options": {
"raw.fs": "/",
"raw.rs": "[\n\r]"
},
}
}
)

error_nonzero(eopa_tags_result, "failed to fetch tags from GitHub")

# We assume that tags and capabilities files are 1:1, but some EOPA
# release tags in the past did not correctly get capabilities files, so
# we eliminate them from consideration.

known_bad_tags := {
"v1.15.0", # tag missing capabilities file (misnamed v0.15.0)
"v1.4.1", # tag missing capabilities file
"v1.5.0", # tag missing capabilities file
}

# Note that we use the `not startswith` to explicitly drop any
# pre-1.0.0 tags. There is little reason anyone would want them, and if
# they really have a need, they can manually download them and use the
# file locally.

eopa_tags := {
t
|
some r in eopa_tags_result.stdout
t := r[2]
not known_bad_tags[t]
not startswith(t, "v0.")
}

# Get a directory listing for the capabilities directory, filtering for
# only nonzero size files with JSON extensions. The size check is to
# avoid long-tail edge cases where we crashed after opening the file
# for writing but before committing any content.
eopa_caps_tree := {
p: f
|
f := rq.tree(eopa_caps_dir, {})[p]
f.size != 0
f.ext == "json"
}

# Determine which capabilities files are missing, what URL they
# should be fetched from, and where they should end up on disk.
missing_locally := {
{"local": p, "remote": r}

|

# construct the local path we expect the caps to exist at
t := eopa_tags[_]
p := rq.joinpath([eopa_caps_dir, sprintf("%s.json", [t])])

not eopa_caps_tree[p]

# construct the URL to fetch the content from
r := rq.template("https://raw.githubusercontent.com/StyraInc/enterprise-opa/main/capabilities/{{.tag}}.json", {"tag": t})
}

print(sprintf("fetching %d capabilities files missing locally", [count(missing_locally)]))

# Download the capabilities from the constructed URLs.
new_caps := {
{"local": m.local, "content": c}
|
m := missing_locally[_]
print("\tfetching ", m.remote)
resp := http.send({"url": m.remote, "method": "GET"})

{ rq.error(sprintf("non-200 status code '%d' for URL '%s'", [resp.status_code, m.remote])) | resp.status_code != 200 }

c := resp.raw_body
}

# Commit the retrieved content to disk.
{
rq.write(cap.content, {"format": "raw", "file_path": cap.local})
|
some cap in new_caps
}
}


fmt_all {
gci
gofumpt
Expand Down Expand Up @@ -226,3 +379,10 @@ github(what, j) {
} else := true

is_github if rq.env().GITHUB_ACTION

error_nonzero(run_result, message) if {
run_result.exitcode != 0
rq.error(sprintf("%s\nstdout:%s\nstderr:\n%s\n", [message, run_result.stdout, run_result.stderr]))
} else {
true
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.22.5
require (
dario.cat/mergo v1.0.1
github.com/anderseknert/roast v0.1.0
github.com/coreos/go-semver v0.3.1
github.com/fatih/color v1.17.0
github.com/fsnotify/fsnotify v1.7.0
github.com/gobwas/glob v0.2.3
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=
github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down
4 changes: 3 additions & 1 deletion internal/ast/rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ func GetRuleDetail(rule *ast.Rule) string {
case ast.Call:
name := v[0].String()

if builtin, ok := rego.BuiltIns[name]; ok {
bis := rego.GetBuiltins()

if builtin, ok := bis[name]; ok {
retType := builtin.Decl.NamedResult().String()

detail += fmt.Sprintf(" (%s)", simplifyType(retType))
Expand Down
Loading
Loading