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

Adding --v1-compatible flag to opa build and opa eval #6478

Merged

Conversation

johanfylling
Copy link
Contributor

This PR implements a small subset of the commands in #6463; namely build and eval. I'm not including more commands here to keep the scope of the PR tight, in part to make it easier to review, but also so that implementation of the remaining commands can be parallelized between multiple developers.

When applied, the --rego-v1 flag will cause opa build and opa eval to behave strictly as they would in OPA 1.0 in regards to module parsing, compilation, and PE. The difference to the behavior of e.g. opa fmt --rego-v1 is that this strict 1.0 behavior allows for policies using the future keywords without first importing future.keywords or rego.v1. E.g.:

package example

allow if {
  input.x == 42
}

An open question is what this flag should be named. A couple of options:

  • --rego-v1: The current naming in this PR. This was selected because this flag already exists on the fmt and check commands. I'm now reevaluating this choice, as --rego-v1 on e.g. fmt means the policy will be formatted to be compatible with both Rego in OPA 0.x and 1.0, whereas for eval it enforces compatibility with only 1.0. In addition to this behavioral difference, reusing the --rego.v1 flag means that we can't provide exactly OPA 1.0 behavior for fmt and check in addition to this current v0/v1 compatibility.
  • --v1-compatible: This flag already exists in opa run, and will apply configuration default values as if OPA 1.0. E.g., the server defaults to listen to localhost instead of 0.0.0.0 (currently the only change). It could be argued that module processing is part of this "OPA 1.0 compatibility mode".
  • --rego-version=<version>: Allow the user to explicitly select what version/flavor of Rego to use. In this PR, we have internally have three flavors of Rego (we could allow the user to either select between no1 and no3; or all three, but that might become confusing):
    1. rego-v0: The current, default Rego version.
    2. rego-v0-compat-v1: A flavor of Rego compatible with both v0 and v1. What is currently enforced in opa check --rego-v1 and opa fmt --rego-v1.
    3. rego-v1: The future Rego version of OPA 1.0.

Copy link

netlify bot commented Dec 13, 2023

Deploy Preview for openpolicyagent ready!

Name Link
🔨 Latest commit 839fe01
🔍 Latest deploy log https://app.netlify.com/sites/openpolicyagent/deploys/6582b686953a7c0008f91940
😎 Deploy Preview https://deploy-preview-6478--openpolicyagent.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link
Contributor Author

@johanfylling johanfylling left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some notes.

ast/parser.go Outdated
@@ -105,8 +114,8 @@ type ParserOptions struct {
FutureKeywords []string
SkipRules bool
JSONOptions *astJSON.Options
RegoVersion RegoVersion
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a breaking change. We could also keep the old RegoV1Compatible parameter, but I think that'll just be confusing. It's unlikely anyone is using this yet, so I feel this isn't a huge transgression.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we deprecate the old one and remove it in a future release? I agree not many must be using this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added it back and added a deprecation notice.

@@ -103,7 +103,11 @@ type FileLoader interface {
WithCapabilities(*ast.Capabilities) FileLoader
WithJSONOptions(*astJSON.Options) FileLoader

// WithRegoV1Compatible
// Deprecated: use WithRegoVersion instead
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's unlikely many users are using this already, so we can probably remove the WithRegoV1Compatible func now.

@ashutosh-narkar
Copy link
Member

ashutosh-narkar commented Dec 14, 2023

In terms of naming the flag --v1-compatible seems like a good option as we're clear that this strict OPA v1.0 behavior. Also we have a proposed --v0-compatible flag.

bundle/bundle.go Show resolved Hide resolved
compile/compile.go Outdated Show resolved Hide resolved
ast/parser.go Show resolved Hide resolved
if params.regoV1 {
regoArgs = append(regoArgs, rego.SetRegoVersion(ast.RegoV1))
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For both eval and build, we need to document how the new flag works either in docs or the help text.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For sure 👍 . I'm thinking we should update the OPA 1.0 page.
It's not included here as I didn't want to spend time on writing that text before we locked down the flag name.

@johanfylling
Copy link
Contributor Author

Let's go with --v1-compatible for flag name. It'll allow us to also add this functionality to fmt and check.

@johanfylling johanfylling changed the title Adding --rego-v1 flag to opa build and opa eval Adding --v1-compatible flag to opa build and opa eval Dec 15, 2023
@johanfylling johanfylling force-pushed the rego-v1/flag_on_all_commands branch 3 times, most recently from ecd0189 to ee3291d Compare December 18, 2023 15:23
Fixes: open-policy-agent#6463
Signed-off-by: Johan Fylling <johan.dev@fylling.se>
Fixes: open-policy-agent#6463
Signed-off-by: Johan Fylling <johan.dev@fylling.se>
Signed-off-by: Johan Fylling <johan.dev@fylling.se>
…at-v1)

Signed-off-by: Johan Fylling <johan.dev@fylling.se>
Signed-off-by: Johan Fylling <johan.dev@fylling.se>
Signed-off-by: Johan Fylling <johan.dev@fylling.se>
…goVersion()`

Suggested by @ashutosh-narkar

Signed-off-by: Johan Fylling <johan.dev@fylling.se>
Requested by @ashutosh-narkar

Signed-off-by: Johan Fylling <johan.dev@fylling.se>
Signed-off-by: Johan Fylling <johan.dev@fylling.se>
Signed-off-by: Johan Fylling <johan.dev@fylling.se>
Signed-off-by: Johan Fylling <johan.dev@fylling.se>
Adding `--v1-compatible` flag to `opa test`

Fixes: open-policy-agent#6463
Signed-off-by: Johan Fylling <johan.dev@fylling.se>
Fixes: open-policy-agent#6463
Signed-off-by: Johan Fylling <johan.dev@fylling.se>
Fixes: open-policy-agent#6463
Signed-off-by: Johan Fylling <johan.dev@fylling.se>
@johanfylling
Copy link
Contributor Author

Added support for commands: test, fmt, and check.

Signed-off-by: Johan Fylling <johan.dev@fylling.se>
Copy link
Member

@ashutosh-narkar ashutosh-narkar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good. The test coverage is also nice. Few comments 👇 .

ast/parser.go Outdated
// RegoV1Compatible additionally affects the Rego version. Use EffectiveRegoVersion to get the effective Rego version.
RegoVersion RegoVersion
// RegoV1Compatible is equivalent to setting RegoVersion to RegoV0CompatV1.
// Setting RegoV1Compatible only has effect if RegoVersion is RegoV0.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't we kind of changing the meaning of RegoV1Compatible? It's fine I guess since I don't expect this has much usage.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True. I've changed this to make RegoV1Compatible take precedence.

`,
},
// Note: the rego.v1 import isn't added to the optimized module.
// This is ok, as the bundle was built with the --rego-v1 flag,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we mean the --v1-compatible flag or --rego-v1 flag?

cmd/fmt.go Outdated
@@ -206,6 +223,8 @@ func init() {
formatCommand.Flags().BoolVarP(&fmtParams.list, "list", "l", false, "list all files who would change when formatted")
formatCommand.Flags().BoolVarP(&fmtParams.diff, "diff", "d", false, "only display a diff of the changes")
formatCommand.Flags().BoolVar(&fmtParams.fail, "fail", false, "non zero exit code on reformat")
formatCommand.Flags().BoolVar(&fmtParams.regoV1, "rego-v1", false, "format as Rego v1")
addRegoV1FlagWithDescription(formatCommand.Flags(), &fmtParams.regoV1, false, "format as Rego v1")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to opa check the resulting policy will also be compatible with the current OPA version?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Changing description.

@@ -26,7 +26,7 @@ type Opts struct {
// carry along their original source locations.
IgnoreLocations bool

RegoV1 bool
RegoVersion ast.RegoVersion
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably need to deprecate RegoV1

@@ -1167,6 +1167,83 @@ func TestPrepareAndPartial(t *testing.T) {
}
}

func TestPartialWitRegoV1(t *testing.T) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: TestPartialWithRegoV1

t.Fatal(err)
}

fmt.Println(partialQuery)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: We can remove this

"policy.rego": `package test
x contains y if { y := 1 }`,
},
expectedErr: "rego_parse_error: var cannot be used for rule name", // FIXME: Improve error message
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this something to address in this PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this might require a larger set of changes in the parser. Let's not delay this PR and risk it not getting in this release, and fix this in the next release instead.

* `check`*
* `fmt`*
* `eval`
* `test`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it would be helpful to add a short note about what the --v1-compatible flag does in each command. For example, in test it will parse modules/bundles per v1 syntax.

* Changing `ParserOptions.RegoV1Compatible` take precedence over `ParserOptions.RegoVersion`
* Fixing comment in test
* Updating `fmt --rego-v1` CLI description

Signed-off-by: Johan Fylling <johan.dev@fylling.se>
* Changing `ParserOptions.RegoV1Compatible` take precedence over `ParserOptions.RegoVersion`
* Fixing comment in test
* Updating `fmt --rego-v1` CLI description
* Adding back `Opts.RegoV1` and deprecating.
  * Making `Opts.RegoV1` take precedence over `Opts.RegoVersion`

Signed-off-by: Johan Fylling <johan.dev@fylling.se>
* Changing `ParserOptions.RegoV1Compatible` take precedence over `ParserOptions.RegoVersion`
* Fixing comment in test
* Updating `fmt --rego-v1` CLI description
* Adding back `Opts.RegoV1` and deprecating.
  * Making `Opts.RegoV1` take precedence over `Opts.RegoVersion`
* `TestPartialWitRegoV1` -> `TestPartialWithRegoV1`

Signed-off-by: Johan Fylling <johan.dev@fylling.se>
* Changing `ParserOptions.RegoV1Compatible` take precedence over `ParserOptions.RegoVersion`
* Fixing comment in test
* Updating `fmt --rego-v1` CLI description
* Adding back `Opts.RegoV1` and deprecating.
  * Making `Opts.RegoV1` take precedence over `Opts.RegoVersion`
* `TestPartialWitRegoV1` -> `TestPartialWithRegoV1`
* removing `Println` in test

Signed-off-by: Johan Fylling <johan.dev@fylling.se>
* Changing `ParserOptions.RegoV1Compatible` take precedence over `ParserOptions.RegoVersion`
* Fixing comment in test
* Updating `fmt --rego-v1` CLI description
* Adding back `Opts.RegoV1` and deprecating.
  * Making `Opts.RegoV1` take precedence over `Opts.RegoVersion`
* `TestPartialWitRegoV1` -> `TestPartialWithRegoV1`
* removing `Println` in test
* Updating docs with per-command behavioural descriptions for `--v1-compatible`.

Signed-off-by: Johan Fylling <johan.dev@fylling.se>
@johanfylling johanfylling merged commit 38c2f0c into open-policy-agent:main Dec 20, 2023
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants