build(deps): bump github.com/open-policy-agent/opa from 0.51.0 to 0.59.0

Bumps [github.com/open-policy-agent/opa](https://github.com/open-policy-agent/opa) from 0.51.0 to 0.59.0.
- [Release notes](https://github.com/open-policy-agent/opa/releases)
- [Changelog](https://github.com/open-policy-agent/opa/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-policy-agent/opa/compare/v0.51.0...v0.59.0)

---
updated-dependencies:
- dependency-name: github.com/open-policy-agent/opa
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
dependabot[bot]
2023-12-05 09:47:11 +01:00
committed by Ralf Haferkamp
parent a6a6c22c14
commit 1f069c7c00
197 changed files with 73803 additions and 3024 deletions
+133 -72
View File
@@ -21,9 +21,12 @@ import (
"github.com/open-policy-agent/opa/ast/internal/scanner"
"github.com/open-policy-agent/opa/ast/internal/tokens"
astJSON "github.com/open-policy-agent/opa/ast/json"
"github.com/open-policy-agent/opa/ast/location"
)
var RegoV1CompatibleRef = Ref{VarTerm("rego"), StringTerm("v1")}
// Note: This state is kept isolated from the parser so that we
// can do efficient shallow copies of these values when doing a
// save() and restore().
@@ -84,7 +87,7 @@ func (c parsedTermCache) String() string {
s.WriteRune('{')
var e *parsedTermCacheItem
for e = c.m; e != nil; e = e.next {
fmt.Fprintf(&s, "%v", e)
s.WriteString(fmt.Sprintf("%v", e))
}
s.WriteRune('}')
return s.String()
@@ -101,37 +104,9 @@ type ParserOptions struct {
AllFutureKeywords bool
FutureKeywords []string
SkipRules bool
JSONOptions *JSONOptions
JSONOptions *astJSON.Options
unreleasedKeywords bool // TODO(sr): cleanup
}
// JSONOptions defines the options for JSON operations,
// currently only marshaling can be configured
type JSONOptions struct {
MarshalOptions JSONMarshalOptions
}
// JSONMarshalOptions defines the options for JSON marshaling,
// currently only toggling the marshaling of location information is supported
type JSONMarshalOptions struct {
IncludeLocation NodeToggle
}
// NodeToggle is a generic struct to allow the toggling of
// settings for different ast node types
type NodeToggle struct {
Term bool
Package bool
Comment bool
Import bool
Rule bool
Head bool
Expr bool
SomeDecl bool
Every bool
With bool
Annotations bool
AnnotationsRef bool
RegoV1Compatible bool
}
// NewParser creates and initializes a Parser.
@@ -207,9 +182,9 @@ func (p *Parser) WithSkipRules(skip bool) *Parser {
return p
}
// WithJSONOptions sets the JSONOptions which will be set on nodes to configure
// WithJSONOptions sets the Options which will be set on nodes to configure
// their JSON marshaling behavior.
func (p *Parser) WithJSONOptions(jsonOptions *JSONOptions) *Parser {
func (p *Parser) WithJSONOptions(jsonOptions *astJSON.Options) *Parser {
p.po.JSONOptions = jsonOptions
return p
}
@@ -356,9 +331,14 @@ func (p *Parser) Parse() ([]Statement, []*Comment, Errors) {
s = p.save()
if imp := p.parseImport(); imp != nil {
if RegoRootDocument.Equal(imp.Path.Value.(Ref)[0]) {
p.regoV1Import(imp)
}
if FutureRootDocument.Equal(imp.Path.Value.(Ref)[0]) {
p.futureImport(imp, allowedFutureKeywords)
}
stmts = append(stmts, imp)
continue
} else if len(p.s.errors) > 0 {
@@ -561,9 +541,9 @@ func (p *Parser) parseImport() *Import {
path := imp.Path.Value.(Ref)
if !RootDocumentNames.Contains(path[0]) && !FutureRootDocument.Equal(path[0]) {
if !RootDocumentNames.Contains(path[0]) && !FutureRootDocument.Equal(path[0]) && !RegoRootDocument.Equal(path[0]) {
p.errorf(imp.Path.Location, "unexpected import path, must begin with one of: %v, got: %v",
RootDocumentNames.Union(NewSet(FutureRootDocument)),
RootDocumentNames.Union(NewSet(FutureRootDocument, RegoRootDocument)),
path[0])
return nil
}
@@ -609,26 +589,32 @@ func (p *Parser) parseRules() []*Rule {
return nil
}
if usesContains {
rule.Head.keywords = append(rule.Head.keywords, tokens.Contains)
}
if rule.Default {
if !p.validateDefaultRuleValue(&rule) {
return nil
}
if len(rule.Head.Args) > 0 {
if !p.validateDefaultRuleArgs(&rule) {
return nil
}
}
rule.Body = NewBody(NewExpr(BooleanTerm(true).SetLocation(rule.Location)).SetLocation(rule.Location))
return []*Rule{&rule}
}
if usesContains && !rule.Head.Reference.IsGround() {
p.error(p.s.Loc(), "multi-value rules need ground refs")
return nil
}
// back-compat with `p[x] { ... }``
hasIf := p.s.tok == tokens.If
// p[x] if ... becomes a single-value rule p[x]
if hasIf && !usesContains && len(rule.Head.Ref()) == 2 {
if rule.Head.Value == nil {
rule.Head.generatedValue = true
rule.Head.Value = BooleanTerm(true).SetLocation(rule.Head.Location)
} else {
// p[x] = y if becomes a single-value rule p[x] with value y, but needs name for compat
@@ -657,6 +643,7 @@ func (p *Parser) parseRules() []*Rule {
switch {
case hasIf:
rule.Head.keywords = append(rule.Head.keywords, tokens.If)
p.scan()
s := p.save()
if expr := p.parseLiteral(); expr != nil {
@@ -688,6 +675,7 @@ func (p *Parser) parseRules() []*Rule {
case usesContains:
rule.Body = NewBody(NewExpr(BooleanTerm(true).SetLocation(rule.Location)).SetLocation(rule.Location))
rule.generatedBody = true
return []*Rule{&rule}
default:
@@ -695,7 +683,7 @@ func (p *Parser) parseRules() []*Rule {
}
if p.s.tok == tokens.Else {
if r := rule.Head.Ref(); len(r) > 1 && !r[len(r)-1].Value.IsGround() {
if r := rule.Head.Ref(); len(r) > 1 && !r.IsGround() {
p.error(p.s.Loc(), "else keyword cannot be used on rules with variables in head")
return nil
}
@@ -737,6 +725,7 @@ func (p *Parser) parseRules() []*Rule {
// rule's head AST but have their location
// set to the rule body.
next.Head = rule.Head.Copy()
next.Head.keywords = rule.Head.keywords
for i := range next.Head.Args {
if v, ok := next.Head.Args[i].Value.(Var); ok && v.IsWildcard() {
next.Head.Args[i].Value = Var(p.genwildcard())
@@ -756,6 +745,7 @@ func (p *Parser) parseElse(head *Head) *Rule {
rule.SetLoc(p.s.Loc())
rule.Head = head.Copy()
rule.Head.generatedValue = false
for i := range rule.Head.Args {
if v, ok := rule.Head.Args[i].Value.(Var); ok && v.IsWildcard() {
rule.Head.Args[i].Value = Var(p.genwildcard())
@@ -771,6 +761,7 @@ func (p *Parser) parseElse(head *Head) *Rule {
switch p.s.tok {
case tokens.LBrace, tokens.If: // no value, but a body follows directly
rule.Head.generatedValue = true
rule.Head.Value = BooleanTerm(true)
case tokens.Assign, tokens.Unify:
rule.Head.Assign = tokens.Assign == p.s.tok
@@ -786,42 +777,37 @@ func (p *Parser) parseElse(head *Head) *Rule {
}
hasIf := p.s.tok == tokens.If
hasLBrace := p.s.tok == tokens.LBrace
if hasIf {
p.scan()
s := p.save()
if expr := p.parseLiteral(); expr != nil {
// NOTE(sr): set literals are never false or undefined, so parsing this as
// p if false else if { true }
// ^^^^^^^^ set of one element, `true`
// isn't valid.
isSetLiteral := false
if t, ok := expr.Terms.(*Term); ok {
_, isSetLiteral = t.Value.(Set)
}
// expr.Term is []*Term or Every
if !isSetLiteral {
rule.Body.Append(expr)
setLocRecursive(rule.Body, rule.Location)
return &rule
}
}
p.restore(s)
}
if p.s.tok != tokens.LBrace {
if !hasIf && !hasLBrace {
rule.Body = NewBody(NewExpr(BooleanTerm(true)))
rule.generatedBody = true
setLocRecursive(rule.Body, rule.Location)
return &rule
}
p.scan()
if rule.Body = p.parseBody(tokens.RBrace); rule.Body == nil {
return nil
if hasIf {
rule.Head.keywords = append(rule.Head.keywords, tokens.If)
p.scan()
}
p.scan()
if p.s.tok == tokens.LBrace {
p.scan()
if rule.Body = p.parseBody(tokens.RBrace); rule.Body == nil {
return nil
}
p.scan()
} else if p.s.tok != tokens.EOF {
expr := p.parseLiteral()
if expr == nil {
return nil
}
rule.Body.Append(expr)
setLocRecursive(rule.Body, rule.Location)
} else {
p.illegal("rule body expected")
return nil
}
if p.s.tok == tokens.Else {
if rule.Else = p.parseElse(head); rule.Else == nil {
@@ -832,7 +818,6 @@ func (p *Parser) parseElse(head *Head) *Rule {
}
func (p *Parser) parseHead(defaultRule bool) (*Head, bool) {
head := &Head{}
loc := p.s.Loc()
defer func() {
@@ -855,7 +840,9 @@ func (p *Parser) parseHead(defaultRule bool) (*Head, bool) {
switch x := ref.Value.(type) {
case Var:
head = NewHead(x)
// Modify the code to add the location to the head ref
// and set the head ref's jsonOptions.
head = VarHead(x, ref.Location, p.po.JSONOptions)
case Ref:
head = RefHead(x)
case Call:
@@ -922,6 +909,7 @@ func (p *Parser) parseHead(defaultRule bool) (*Head, bool) {
if head.Value == nil && head.Key == nil {
if len(head.Ref()) != 2 || len(head.Args) > 0 {
head.generatedValue = true
head.Value = BooleanTerm(true).SetLocation(head.Location)
}
}
@@ -2001,7 +1989,7 @@ func (p *Parser) error(loc *location.Location, reason string) {
func (p *Parser) errorf(loc *location.Location, f string, a ...interface{}) {
msg := strings.Builder{}
fmt.Fprintf(&msg, f, a...)
msg.WriteString(fmt.Sprintf(f, a...))
switch len(p.s.hints) {
case 0: // nothing to do
@@ -2176,6 +2164,38 @@ func (p *Parser) validateDefaultRuleValue(rule *Rule) bool {
return valid
}
func (p *Parser) validateDefaultRuleArgs(rule *Rule) bool {
valid := true
vars := NewVarSet()
vis := NewGenericVisitor(func(x interface{}) bool {
switch x := x.(type) {
case Var:
if vars.Contains(x) {
p.error(rule.Loc(), fmt.Sprintf("illegal default rule (arguments cannot be repeated %v)", x))
valid = false
return true
}
vars.Add(x)
case *Term:
switch v := x.Value.(type) {
case Var: // do nothing
default:
p.error(rule.Loc(), fmt.Sprintf("illegal default rule (arguments cannot contain %v)", TypeName(v)))
valid = false
return true
}
}
return false
})
vis.Walk(rule.Head.Args)
return valid
}
// We explicitly use yaml unmarshalling, to accommodate for the '_' in 'related_resources',
// which isn't handled properly by json for some reason.
type rawAnnotation struct {
@@ -2508,6 +2528,11 @@ func (p *Parser) futureImport(imp *Import, allowedFutureKeywords map[string]toke
return
}
if p.s.s.RegoV1Compatible() {
p.errorf(imp.Path.Location, "the `%s` import implies `future.keywords`, these are therefore mutually exclusive", RegoV1CompatibleRef)
return
}
kwds := make([]string, 0, len(allowedFutureKeywords))
for k := range allowedFutureKeywords {
kwds = append(kwds, k)
@@ -2535,3 +2560,39 @@ func (p *Parser) futureImport(imp *Import, allowedFutureKeywords map[string]toke
p.s.s.AddKeyword(kw, allowedFutureKeywords[kw])
}
}
func (p *Parser) regoV1Import(imp *Import) {
if !p.po.Capabilities.ContainsFeature(FeatureRegoV1Import) {
p.errorf(imp.Path.Location, "invalid import, `%s` is not supported by current capabilities", RegoV1CompatibleRef)
return
}
path := imp.Path.Value.(Ref)
if len(path) == 1 || !path[1].Equal(RegoV1CompatibleRef[1]) || len(path) > 2 {
p.errorf(imp.Path.Location, "invalid import, must be `%s`", RegoV1CompatibleRef)
return
}
if imp.Alias != "" {
p.errorf(imp.Path.Location, "`rego` imports cannot be aliased")
return
}
// import all future keywords with the rego.v1 import
kwds := make([]string, 0, len(futureKeywords))
for k := range futureKeywords {
kwds = append(kwds, k)
}
if p.s.s.HasKeyword(futureKeywords) && !p.s.s.RegoV1Compatible() {
// We have imported future keywords, but they didn't come from another `rego.v1` import.
p.errorf(imp.Path.Location, "the `%s` import implies `future.keywords`, these are therefore mutually exclusive", RegoV1CompatibleRef)
return
}
p.s.s.SetRegoV1Compatible()
for _, kw := range kwds {
p.s.s.AddKeyword(kw, futureKeywords[kw])
}
}