mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-07-13 09:02:09 -04:00
build(deps): bump github.com/open-policy-agent/opa from 1.14.1 to 1.15.0 (#2535)
Bumps [github.com/open-policy-agent/opa](https://github.com/open-policy-agent/opa) from 1.14.1 to 1.15.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/v1.14.1...v1.15.0) --- updated-dependencies: - dependency-name: github.com/open-policy-agent/opa dependency-version: 1.15.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
2
go.mod
2
go.mod
@@ -62,7 +62,7 @@ require (
|
||||
github.com/onsi/ginkgo v1.16.5
|
||||
github.com/onsi/ginkgo/v2 v2.28.1
|
||||
github.com/onsi/gomega v1.39.1
|
||||
github.com/open-policy-agent/opa v1.14.1
|
||||
github.com/open-policy-agent/opa v1.15.1
|
||||
github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89
|
||||
github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260310090739-853d972b282d
|
||||
github.com/opencloud-eu/reva/v2 v2.42.6
|
||||
|
||||
4
go.sum
4
go.sum
@@ -949,8 +949,8 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28=
|
||||
github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg=
|
||||
github.com/open-policy-agent/opa v1.14.1 h1:MhurLB9mSbXmojYFCmGbiC1Uagu1+aFAV4XVotDA86M=
|
||||
github.com/open-policy-agent/opa v1.14.1/go.mod h1:B5gykwJ2l0g0wZS4ClCcpfSSEx51n4NHpTsWfuPwqnQ=
|
||||
github.com/open-policy-agent/opa v1.15.1 h1:ZE4JaXsVUzDiHFSlOMBS3nJohR5BRGB/RNz6gTNugzE=
|
||||
github.com/open-policy-agent/opa v1.15.1/go.mod h1:c6SN+7jSsUcKJLQc5P4yhwx8YYDRbjpAiGkBOTqxaa4=
|
||||
github.com/opencloud-eu/go-micro-plugins/v4/store/nats-js-kv v0.0.0-20250512152754-23325793059a h1:Sakl76blJAaM6NxylVkgSzktjo2dS504iDotEFJsh3M=
|
||||
github.com/opencloud-eu/go-micro-plugins/v4/store/nats-js-kv v0.0.0-20250512152754-23325793059a/go.mod h1:pjcozWijkNPbEtX5SIQaxEW/h8VAVZYTLx+70bmB3LY=
|
||||
github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89 h1:W1ms+lP5lUUIzjRGDg93WrQfZJZCaV1ZP3KeyXi8bzY=
|
||||
|
||||
2
vendor/github.com/open-policy-agent/opa/ast/builtins.go
generated
vendored
2
vendor/github.com/open-policy-agent/opa/ast/builtins.go
generated
vendored
@@ -29,7 +29,7 @@ var BuiltinMap = v1.BuiltinMap
|
||||
// Deprecated: Builtins can now be directly annotated with the
|
||||
// Nondeterministic property, and when set to true, will be ignored
|
||||
// for partial evaluation.
|
||||
var IgnoreDuringPartialEval = v1.IgnoreDuringPartialEval
|
||||
var IgnoreDuringPartialEval = v1.IgnoreDuringPartialEval //nolint:staticcheck
|
||||
|
||||
/**
|
||||
* Unification
|
||||
|
||||
4
vendor/github.com/open-policy-agent/opa/ast/visit.go
generated
vendored
4
vendor/github.com/open-policy-agent/opa/ast/visit.go
generated
vendored
@@ -12,13 +12,13 @@ import v1 "github.com/open-policy-agent/opa/v1/ast"
|
||||
// visited.
|
||||
//
|
||||
// Deprecated: use GenericVisitor or another visitor implementation
|
||||
type Visitor = v1.Visitor
|
||||
type Visitor = v1.Visitor //nolint:staticcheck
|
||||
|
||||
// BeforeAndAfterVisitor wraps Visitor to provide hooks for being called before
|
||||
// and after the AST has been visited.
|
||||
//
|
||||
// Deprecated: use GenericVisitor or another visitor implementation
|
||||
type BeforeAndAfterVisitor = v1.BeforeAndAfterVisitor
|
||||
type BeforeAndAfterVisitor = v1.BeforeAndAfterVisitor //nolint:staticcheck
|
||||
|
||||
// Walk iterates the AST by calling the Visit function on the Visitor
|
||||
// v for x before recursing.
|
||||
|
||||
4916
vendor/github.com/open-policy-agent/opa/capabilities/v1.15.0.json
generated
vendored
Normal file
4916
vendor/github.com/open-policy-agent/opa/capabilities/v1.15.0.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4916
vendor/github.com/open-policy-agent/opa/capabilities/v1.15.1.json
generated
vendored
Normal file
4916
vendor/github.com/open-policy-agent/opa/capabilities/v1.15.1.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/wasm.go
generated
vendored
1
vendor/github.com/open-policy-agent/opa/internal/compiler/wasm/wasm.go
generated
vendored
@@ -32,7 +32,6 @@ const (
|
||||
opaWasmABIMinorVersionVar = "opa_wasm_abi_minor_version"
|
||||
)
|
||||
|
||||
// nolint: varcheck
|
||||
const (
|
||||
opaTypeNull int32 = iota + 1
|
||||
opaTypeBoolean
|
||||
|
||||
2
vendor/github.com/open-policy-agent/opa/internal/gojsonschema/utils.go
generated
vendored
2
vendor/github.com/open-policy-agent/opa/internal/gojsonschema/utils.go
generated
vendored
@@ -23,7 +23,7 @@
|
||||
//
|
||||
// created 26-02-2013
|
||||
|
||||
// nolint:unused,varcheck // Package in development (2021).
|
||||
// nolint:unused // Package in development (2021).
|
||||
package gojsonschema
|
||||
|
||||
import (
|
||||
|
||||
59
vendor/github.com/open-policy-agent/opa/internal/providers/aws/crypto/ecc.go
generated
vendored
59
vendor/github.com/open-policy-agent/opa/internal/providers/aws/crypto/ecc.go
generated
vendored
@@ -2,6 +2,7 @@ package crypto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/ecdh"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/hmac"
|
||||
@@ -27,27 +28,77 @@ func ECDSAKey(curve elliptic.Curve, d []byte) *ecdsa.PrivateKey {
|
||||
// ECDSAKeyFromPoint takes the given elliptic curve and point and returns the
|
||||
// private and public keypair
|
||||
func ECDSAKeyFromPoint(curve elliptic.Curve, d *big.Int) *ecdsa.PrivateKey {
|
||||
pX, pY := curve.ScalarBaseMult(d.Bytes())
|
||||
dBytes := make([]byte, (curve.Params().BitSize+7)/8)
|
||||
d.FillBytes(dBytes)
|
||||
|
||||
privKey := &ecdsa.PrivateKey{
|
||||
PublicKey: ecdsa.PublicKey{
|
||||
Curve: curve,
|
||||
X: pX,
|
||||
Y: pY,
|
||||
},
|
||||
D: d,
|
||||
}
|
||||
|
||||
var pubBytes []byte
|
||||
switch curve {
|
||||
case elliptic.P256():
|
||||
if ecdhPriv, err := ecdh.P256().NewPrivateKey(dBytes); err == nil {
|
||||
pubBytes = ecdhPriv.PublicKey().Bytes()
|
||||
}
|
||||
case elliptic.P384():
|
||||
if ecdhPriv, err := ecdh.P384().NewPrivateKey(dBytes); err == nil {
|
||||
pubBytes = ecdhPriv.PublicKey().Bytes()
|
||||
}
|
||||
case elliptic.P521():
|
||||
if ecdhPriv, err := ecdh.P521().NewPrivateKey(dBytes); err == nil {
|
||||
pubBytes = ecdhPriv.PublicKey().Bytes()
|
||||
}
|
||||
}
|
||||
|
||||
if len(pubBytes) > 0 {
|
||||
byteLen := (curve.Params().BitSize + 7) / 8
|
||||
privKey.X = new(big.Int).SetBytes(pubBytes[1 : 1+byteLen])
|
||||
privKey.Y = new(big.Int).SetBytes(pubBytes[1+byteLen:])
|
||||
} else {
|
||||
panic(fmt.Sprintf("unsupported curve or invalid private key: %v", curve))
|
||||
}
|
||||
|
||||
return privKey
|
||||
}
|
||||
|
||||
// mathIntToBytes writes val as a big-endian, fixed-length byte slice into out,
|
||||
// zero-padding on the left when val.Bytes() is shorter than out. This satisfies
|
||||
// the uncompressed SEC 1 encoding (0x04 || X || Y) expected by crypto/ecdh's
|
||||
// NewPublicKey: https://pkg.go.dev/crypto/ecdh#Curve.NewPublicKey
|
||||
func mathIntToBytes(val *big.Int, out []byte) {
|
||||
valBytes := val.Bytes()
|
||||
copy(out[len(out)-len(valBytes):], valBytes)
|
||||
}
|
||||
|
||||
// ECDSAPublicKey takes the provide curve and (x, y) coordinates and returns
|
||||
// *ecdsa.PublicKey. Returns an error if the given points are not on the curve.
|
||||
func ECDSAPublicKey(curve elliptic.Curve, x, y []byte) (*ecdsa.PublicKey, error) {
|
||||
xPoint := (&big.Int{}).SetBytes(x)
|
||||
yPoint := (&big.Int{}).SetBytes(y)
|
||||
|
||||
if !curve.IsOnCurve(xPoint, yPoint) {
|
||||
byteLen := (curve.Params().BitSize + 7) / 8
|
||||
buf := make([]byte, 1+2*byteLen)
|
||||
buf[0] = 4 // uncompressed point
|
||||
mathIntToBytes(xPoint, buf[1:1+byteLen])
|
||||
mathIntToBytes(yPoint, buf[1+byteLen:])
|
||||
|
||||
var err error
|
||||
switch curve {
|
||||
case elliptic.P256():
|
||||
_, err = ecdh.P256().NewPublicKey(buf)
|
||||
case elliptic.P384():
|
||||
_, err = ecdh.P384().NewPublicKey(buf)
|
||||
case elliptic.P521():
|
||||
_, err = ecdh.P521().NewPublicKey(buf)
|
||||
default:
|
||||
err = fmt.Errorf("unsupported curve for ECDSA: %v", curve)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("point(%v, %v) is not on the given curve", xPoint.String(), yPoint.String())
|
||||
}
|
||||
|
||||
|
||||
14
vendor/github.com/open-policy-agent/opa/internal/providers/aws/signing_v4a.go
generated
vendored
14
vendor/github.com/open-policy-agent/opa/internal/providers/aws/signing_v4a.go
generated
vendored
@@ -4,6 +4,7 @@ package aws
|
||||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"crypto/ecdh"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
@@ -115,7 +116,18 @@ func deriveKeyFromAccessKeyPair(accessKey, secretKey string) (*ecdsa.PrivateKey,
|
||||
priv := new(ecdsa.PrivateKey)
|
||||
priv.PublicKey.Curve = p256
|
||||
priv.D = d
|
||||
priv.PublicKey.X, priv.PublicKey.Y = p256.ScalarBaseMult(d.Bytes())
|
||||
|
||||
dBytes := make([]byte, 32)
|
||||
d.FillBytes(dBytes)
|
||||
|
||||
ecdhPriv, err := ecdh.P256().NewPrivateKey(dBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pubBytes := ecdhPriv.PublicKey().Bytes()
|
||||
|
||||
priv.PublicKey.X = new(big.Int).SetBytes(pubBytes[1:33])
|
||||
priv.PublicKey.Y = new(big.Int).SetBytes(pubBytes[33:])
|
||||
|
||||
return priv, nil
|
||||
}
|
||||
|
||||
2
vendor/github.com/open-policy-agent/opa/internal/uuid/uuid.go
generated
vendored
2
vendor/github.com/open-policy-agent/opa/internal/uuid/uuid.go
generated
vendored
@@ -86,7 +86,7 @@ func byteDecimalToHexMAC(bytes []byte, sep string) string {
|
||||
hexs.Grow((l * 3) - 1) // 1 byte -> 2 hexes + 1 separator (if one char)
|
||||
|
||||
for i, b := range bytes {
|
||||
hexs.WriteString(fmt.Sprintf("%02x", b))
|
||||
fmt.Fprintf(&hexs, "%02x", b)
|
||||
if i < l-1 {
|
||||
hexs.WriteString(sep)
|
||||
}
|
||||
|
||||
399
vendor/github.com/open-policy-agent/opa/v1/ast/index.go
generated
vendored
399
vendor/github.com/open-policy-agent/opa/v1/ast/index.go
generated
vendored
@@ -5,7 +5,6 @@
|
||||
package ast
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
@@ -68,6 +67,7 @@ var (
|
||||
globMatchRef = GlobMatch.Ref()
|
||||
internalPrintRef = InternalPrint.Ref()
|
||||
internalTestCaseRef = InternalTestCase.Ref()
|
||||
internalMemberRef = Member.Ref()
|
||||
|
||||
skipIndexing = NewSet(NewTerm(internalPrintRef), NewTerm(internalTestCaseRef))
|
||||
)
|
||||
@@ -87,6 +87,7 @@ func (i *baseDocEqIndex) Build(rules []*Rule) bool {
|
||||
|
||||
i.kind = rules[0].Head.RuleKind()
|
||||
indices := newrefindices(i.isVirtual)
|
||||
values := make(map[Var]Value)
|
||||
|
||||
// build indices for each rule.
|
||||
for idx := range rules {
|
||||
@@ -106,8 +107,9 @@ func (i *baseDocEqIndex) Build(rules []*Rule) bool {
|
||||
}
|
||||
}
|
||||
if !skip {
|
||||
clear(values)
|
||||
for i := range rule.Body {
|
||||
indices.Update(rule, rule.Body[i])
|
||||
indices.Update(rule, rule.Body[i], values)
|
||||
}
|
||||
}
|
||||
return false
|
||||
@@ -124,7 +126,46 @@ func (i *baseDocEqIndex) Build(rules []*Rule) bool {
|
||||
node := i.root
|
||||
if indices.Indexed(rule) {
|
||||
for _, ref := range indices.Sorted() {
|
||||
node = node.Insert(ref, indices.Value(rule, ref), indices.Mapper(rule, ref))
|
||||
var values []*refindex
|
||||
for _, ri := range indices.rules[rule] {
|
||||
if ri.Ref.Equal(ref) {
|
||||
values = append(values, ri)
|
||||
}
|
||||
}
|
||||
if len(values) == 0 {
|
||||
node = node.Insert(ref, nil, nil)
|
||||
} else if len(values) == 1 {
|
||||
node = node.Insert(ref, values[0].Value, values[0].Mapper)
|
||||
} else {
|
||||
var hasVar bool
|
||||
for i := range values {
|
||||
if _, isVar := values[i].Value.(Var); isVar {
|
||||
hasVar = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if hasVar {
|
||||
child := node.Insert(ref, anyValue, values[0].Mapper)
|
||||
for i := range values {
|
||||
if values[i].Mapper != nil {
|
||||
node.next.addMapper(values[i].Mapper)
|
||||
}
|
||||
}
|
||||
node = child
|
||||
} else {
|
||||
// When a rule has multiple scalar values (e.g., internal.member_2 with a set),
|
||||
// each value should have its own child node, and the rule is appended to each.
|
||||
// This creates separate paths for each value so different rules with overlapping
|
||||
// values don't interfere with each other.
|
||||
for _, val := range values {
|
||||
child := node.Insert(ref, val.Value, val.Mapper)
|
||||
child.append([...]int{idx, prio}, rule)
|
||||
}
|
||||
prio++
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Insert rule into trie with (insertion order, priority order)
|
||||
@@ -292,7 +333,7 @@ var anyValue = Var("__any__")
|
||||
// Update attempts to update the refindices for the given expression in the
|
||||
// given rule. If the expression cannot be indexed the update does not affect
|
||||
// the indices.
|
||||
func (i *refindices) Update(rule *Rule, expr *Expr) {
|
||||
func (i *refindices) Update(rule *Rule, expr *Expr, values map[Var]Value) {
|
||||
|
||||
if len(expr.With) > 0 {
|
||||
// NOTE(tsandall): In the future, we may need to consider expressions
|
||||
@@ -314,30 +355,44 @@ func (i *refindices) Update(rule *Rule, expr *Expr) {
|
||||
// function with a undefined argument, there's no point to recording
|
||||
// "needs to be anything" for function args
|
||||
if ref, ok := ts.Value.(Ref); ok { // "naked ref"
|
||||
i.updateEq(rule, ref, anyValue)
|
||||
i.updateEq(rule, ref, anyValue, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a, b := expr.Operand(0), expr.Operand(1)
|
||||
switch {
|
||||
case op.Equal(equalityRef):
|
||||
i.updateEq(rule, a.Value, b.Value)
|
||||
|
||||
case op.Equal(equalRef) && len(expr.Operands()) == 2:
|
||||
equalish := op.Equal(equalityRef) || // unification, no 3-operands version exists
|
||||
// NOTE(tsandall): if equal() is called with more than two arguments the
|
||||
// output value is being captured in which case the indexer cannot
|
||||
// exclude the rule if the equal() call would return false (because the
|
||||
// false value must still be produced.)
|
||||
i.updateEq(rule, a.Value, b.Value)
|
||||
(op.Equal(equalRef) && len(expr.Operands()) == 2)
|
||||
|
||||
a, b := expr.Operand(0), expr.Operand(1)
|
||||
switch {
|
||||
case equalish:
|
||||
if !i.updateEqWildcardRef(rule, a.Value, b.Value, values) {
|
||||
i.updateEq(rule, a.Value, b.Value, values)
|
||||
}
|
||||
|
||||
case op.Equal(globMatchRef) && len(expr.Operands()) == 3:
|
||||
// NOTE(sr): Same as with equal() above -- 4 operands means the output
|
||||
// of `glob.match` is captured and the rule can thus not be excluded.
|
||||
i.updateGlobMatch(rule, expr)
|
||||
|
||||
case op.Equal(internalMemberRef) && len(expr.Operands()) == 2:
|
||||
// NOTE(sr): Again, 3 operands means captured output (like above).
|
||||
i.updateMember(rule, expr, values)
|
||||
}
|
||||
}
|
||||
|
||||
func (i *refindices) isValidIndexRef(ref Ref) bool {
|
||||
// NB(sr): the ordering is intentional, cheapest-first
|
||||
return RootDocumentNames.Contains(ref[0]) &&
|
||||
!ref.IsNested() &&
|
||||
ref.IsGround() &&
|
||||
!i.isVirtual(ref)
|
||||
}
|
||||
|
||||
// Sorted returns a sorted list of references that the indices were built from.
|
||||
// References that appear more frequently in the indexed rules are ordered
|
||||
// before less frequently appearing references.
|
||||
@@ -384,16 +439,46 @@ func (i *refindices) Mapper(rule *Rule, ref Ref) *valueMapper {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *refindices) updateEq(rule *Rule, a, b Value) {
|
||||
func (i *refindices) updateEq(rule *Rule, a, b Value, constants map[Var]Value) {
|
||||
args := rule.Head.Args
|
||||
if idx, ok := eqOperandsToRefAndValue(i.isVirtual, args, a, b); ok {
|
||||
i.insert(rule, idx)
|
||||
return
|
||||
if !i.eqOperandsToRefAndValue(rule, args, a, b, constants) {
|
||||
i.eqOperandsToRefAndValue(rule, args, b, a, constants)
|
||||
}
|
||||
if idx, ok := eqOperandsToRefAndValue(i.isVirtual, args, b, a); ok {
|
||||
i.insert(rule, idx)
|
||||
return
|
||||
}
|
||||
|
||||
func (i *refindices) updateEqWildcardRef(rule *Rule, a, b Value, constants map[Var]Value) bool {
|
||||
return i.tryIndexWildcardRef(rule, a, b, constants) ||
|
||||
i.tryIndexWildcardRef(rule, b, a, constants)
|
||||
}
|
||||
|
||||
func (i *refindices) tryIndexWildcardRef(rule *Rule, a, b Value, constants map[Var]Value) bool {
|
||||
ref, ok := a.(Ref)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
groundPrefix := ref.GroundPrefix()
|
||||
if len(groundPrefix) != len(ref)-1 || !i.isValidIndexRef(groundPrefix) {
|
||||
return false
|
||||
}
|
||||
|
||||
resolvedValue := b
|
||||
if bvar, ok := b.(Var); ok {
|
||||
if resolved, ok := constants[bvar]; ok {
|
||||
resolvedValue = resolved
|
||||
}
|
||||
} else if val, ok := indexValue(b); ok {
|
||||
resolvedValue = val
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
|
||||
if !IsScalar(resolvedValue) {
|
||||
return false
|
||||
}
|
||||
|
||||
i.insert(rule, &refindex{Ref: groundPrefix, Value: resolvedValue})
|
||||
return true
|
||||
}
|
||||
|
||||
func (i *refindices) updateGlobMatch(rule *Rule, expr *Expr) {
|
||||
@@ -409,21 +494,8 @@ func (i *refindices) updateGlobMatch(rule *Rule, expr *Expr) {
|
||||
// 3rd operand was a reference that has been rewritten and bound to a
|
||||
// variable earlier in the query OR a function argument variable.
|
||||
match := expr.Operand(2)
|
||||
if _, ok := match.Value.(Var); ok {
|
||||
var ref Ref
|
||||
for _, other := range i.rules[rule] {
|
||||
if ov, ok := other.Value.(Var); ok && ov.Equal(match.Value) {
|
||||
ref = other.Ref
|
||||
}
|
||||
}
|
||||
if ref == nil {
|
||||
for j, arg := range args {
|
||||
if arg.Equal(match) {
|
||||
ref = Ref{FunctionArgRootDocument, InternedTerm(j)}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ref != nil {
|
||||
if v, ok := match.Value.(Var); ok {
|
||||
if ref := resolveVarToRef(i.rules[rule], args, v); ref != nil {
|
||||
i.insert(rule, &refindex{
|
||||
Ref: ref,
|
||||
Value: arr.Value,
|
||||
@@ -442,14 +514,137 @@ func (i *refindices) updateGlobMatch(rule *Rule, expr *Expr) {
|
||||
}
|
||||
}
|
||||
|
||||
func (i *refindices) updateMember(rule *Rule, expr *Expr, constants map[Var]Value) {
|
||||
args := rule.Head.Args
|
||||
lhs, rhs := expr.Operand(0), expr.Operand(1)
|
||||
|
||||
lvar, ok := lhs.Value.(Var)
|
||||
if ok {
|
||||
lref := resolveVarToRef(i.rules[rule], args, lvar)
|
||||
if lref != nil {
|
||||
i.updateMemberRefInValue(rule, lref, rhs, constants) // `ref in value`
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// `var0 in var1` case (var0 may be constant, var1 ref)
|
||||
i.updateMemberValueInRef(rule, args, lhs.Value, rhs, constants)
|
||||
}
|
||||
|
||||
func (i *refindices) updateMemberValueInRef(rule *Rule, args []*Term, lval Value, rhs *Term, constants map[Var]Value) {
|
||||
if lvar, ok := lval.(Var); ok {
|
||||
val, ok := constants[lvar]
|
||||
if ok {
|
||||
lval = val
|
||||
}
|
||||
} else if !IsScalar(lval) {
|
||||
return
|
||||
}
|
||||
|
||||
rref := i.resolveAndValidateRef(rule, args, rhs)
|
||||
if rref == nil {
|
||||
return
|
||||
}
|
||||
|
||||
i.insert(rule, &refindex{Ref: rref, Value: lval})
|
||||
}
|
||||
|
||||
func (i *refindices) updateMemberRefInValue(rule *Rule, ref Ref, rhs *Term, constants map[Var]Value) {
|
||||
rval := rhs.Value
|
||||
if rvar, ok := rval.(Var); ok { // rhs is var, try to resolve
|
||||
if resolved, ok := constants[rvar]; ok {
|
||||
rval = resolved
|
||||
}
|
||||
}
|
||||
|
||||
addRef := func(t *Term) error {
|
||||
i.insert(rule, &refindex{Ref: ref, Value: t.Value})
|
||||
return nil
|
||||
}
|
||||
|
||||
switch rcol := rval.(type) {
|
||||
case *Array:
|
||||
_ = rcol.Iter(addRef)
|
||||
case Set:
|
||||
_ = rcol.Iter(addRef)
|
||||
case Object:
|
||||
_ = rcol.Iter(func(_, v *Term) error {
|
||||
return addRef(v)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (i *refindices) resolveAndValidateRef(rule *Rule, args []*Term, term *Term) Ref {
|
||||
var ref Ref
|
||||
switch v := term.Value.(type) {
|
||||
case Ref:
|
||||
ref = v
|
||||
case Var:
|
||||
ref = resolveVarToRef(i.rules[rule], args, v)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
if ref == nil || !i.isValidIndexRef(ref) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return ref
|
||||
}
|
||||
|
||||
// resolveVarToRef checks the previously prepared `*refindex` slice for
|
||||
// occurrences of the var `v`. Since we store `ref = var` expressions for
|
||||
// "any" lookups (i.e. "return the rule if ref is anything"), we can
|
||||
// resolve vars to refs in these simple cases:
|
||||
//
|
||||
// __local2__ = input.foo
|
||||
// __local2__ = <something>
|
||||
//
|
||||
// This what builtin calls involving refs are rewritten to, so it is used
|
||||
// for var -> ref lookup when buiding the RI for glob.match or `v in col`.
|
||||
//
|
||||
// For convenience, we also resolve function arg vars here.
|
||||
//
|
||||
// NB: This also covers explicit var assignments, like `role := input.rule`,
|
||||
// but it is no help with chains of assignments, like
|
||||
//
|
||||
// x := input.role
|
||||
// y := x
|
||||
// <something with x>
|
||||
//
|
||||
// as we're not capturing `var = var` expressions in the index.
|
||||
func resolveVarToRef(ri []*refindex, args []*Term, v Var) Ref {
|
||||
for _, other := range ri {
|
||||
if ov, ok := other.Value.(Var); ok && ov.Equal(v) {
|
||||
return other.Ref
|
||||
}
|
||||
}
|
||||
for j, arg := range args {
|
||||
if arg.Value.Compare(v) == 0 {
|
||||
return Ref{FunctionArgRootDocument, InternedTerm(j)}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *refindices) insert(rule *Rule, index *refindex) {
|
||||
count, _ := i.frequency.Get(index.Ref)
|
||||
i.frequency.Put(index.Ref, count+1)
|
||||
|
||||
_, indexValueIsVar := index.Value.(Var)
|
||||
|
||||
for pos, other := range i.rules[rule] {
|
||||
if other.Ref.Equal(index.Ref) {
|
||||
i.rules[rule][pos] = index
|
||||
return
|
||||
|
||||
if ValueEqual(other.Value, index.Value) {
|
||||
return
|
||||
}
|
||||
_, otherValueIsVar := other.Value.(Var)
|
||||
if !indexValueIsVar && otherValueIsVar {
|
||||
i.rules[rule][pos] = index
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -495,7 +690,12 @@ func (tr *trieTraversalResult) Add(t *trieNode) {
|
||||
if !ok {
|
||||
tr.ordering = append(tr.ordering, root)
|
||||
}
|
||||
tr.unordered[root] = append(nodes, node)
|
||||
// Deduplicate: check if a ruleNode with this priority already exists
|
||||
if !slices.ContainsFunc(nodes, func(existing *ruleNode) bool {
|
||||
return existing.prio == node.prio
|
||||
}) {
|
||||
tr.unordered[root] = append(nodes, node)
|
||||
}
|
||||
}
|
||||
if t.multiple {
|
||||
tr.multiple = true
|
||||
@@ -523,45 +723,6 @@ type trieNode struct {
|
||||
multiple bool
|
||||
}
|
||||
|
||||
func (node *trieNode) String() string {
|
||||
var flags []string
|
||||
flags = append(flags, fmt.Sprintf("self:%p", node))
|
||||
if len(node.ref) > 0 {
|
||||
flags = append(flags, node.ref.String())
|
||||
}
|
||||
if node.next != nil {
|
||||
flags = append(flags, fmt.Sprintf("next:%p", node.next))
|
||||
}
|
||||
if node.any != nil {
|
||||
flags = append(flags, fmt.Sprintf("any:%p", node.any))
|
||||
}
|
||||
if node.undefined != nil {
|
||||
flags = append(flags, fmt.Sprintf("undefined:%p", node.undefined))
|
||||
}
|
||||
if node.array != nil {
|
||||
flags = append(flags, fmt.Sprintf("array:%p", node.array))
|
||||
}
|
||||
if node.scalars.Len() > 0 {
|
||||
buf := make([]string, 0, node.scalars.Len())
|
||||
node.scalars.Iter(func(key Value, val *trieNode) bool {
|
||||
buf = append(buf, fmt.Sprintf("scalar(%v):%p", key, val))
|
||||
return false
|
||||
})
|
||||
sort.Strings(buf)
|
||||
flags = append(flags, strings.Join(buf, " "))
|
||||
}
|
||||
if len(node.rules) > 0 {
|
||||
flags = append(flags, fmt.Sprintf("%d rule(s)", len(node.rules)))
|
||||
}
|
||||
if len(node.mappers) > 0 {
|
||||
flags = append(flags, fmt.Sprintf("%d mapper(s)", len(node.mappers)))
|
||||
}
|
||||
if node.value != nil {
|
||||
flags = append(flags, "value exists")
|
||||
}
|
||||
return strings.Join(flags, " ")
|
||||
}
|
||||
|
||||
func (node *trieNode) append(prio [2]int, rule *Rule) {
|
||||
node.rules = append(node.rules, &ruleNode{prio, rule})
|
||||
|
||||
@@ -741,8 +902,20 @@ func (node *trieNode) traverse(resolver ValueResolver, tr *trieTraversalResult)
|
||||
func (node *trieNode) traverseValue(resolver ValueResolver, tr *trieTraversalResult, value Value) error {
|
||||
|
||||
switch value := value.(type) {
|
||||
case *Array:
|
||||
return node.array.traverseArray(resolver, tr, value)
|
||||
case *Array, Set, Object:
|
||||
if node.array != nil {
|
||||
if arr, ok := value.(*Array); ok {
|
||||
if err := node.array.traverseArray(resolver, tr, arr); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if node.scalars.Len() > 0 {
|
||||
return node.traverseCollectionMembership(resolver, tr, value)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
case Null, Boolean, Number, String:
|
||||
child, ok := node.scalars.Get(value)
|
||||
@@ -755,6 +928,29 @@ func (node *trieNode) traverseValue(resolver ValueResolver, tr *trieTraversalRes
|
||||
return nil
|
||||
}
|
||||
|
||||
func (node *trieNode) traverseCollectionMembership(resolver ValueResolver, tr *trieTraversalResult, collection Value) error {
|
||||
checkMember := func(t *Term) error {
|
||||
if IsScalar(t.Value) {
|
||||
child, _ := node.scalars.Get(t.Value)
|
||||
return child.Traverse(resolver, tr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
switch col := collection.(type) {
|
||||
case *Array:
|
||||
return col.Iter(checkMember)
|
||||
case Set:
|
||||
return col.Iter(checkMember)
|
||||
case Object:
|
||||
return col.Iter(func(_, v *Term) error {
|
||||
return checkMember(v)
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (node *trieNode) traverseArray(resolver ValueResolver, tr *trieTraversalResult, arr *Array) error {
|
||||
if node == nil {
|
||||
return nil
|
||||
@@ -817,31 +1013,42 @@ func (node *trieNode) traverseUnknown(resolver ValueResolver, tr *trieTraversalR
|
||||
// for the argument number. So for `f(x, y) { x = 10; y = 12 }`, we'll
|
||||
// bind `args[0]` and `args[1]` to this rule when called for (x=10) and
|
||||
// (y=12) respectively.
|
||||
func eqOperandsToRefAndValue(isVirtual func(Ref) bool, args []*Term, a, b Value) (*refindex, bool) {
|
||||
func (i *refindices) eqOperandsToRefAndValue(rule *Rule, args []*Term, a, b Value, constants map[Var]Value) bool {
|
||||
switch v := a.(type) {
|
||||
case Var:
|
||||
for i, arg := range args {
|
||||
if arg.Value.Compare(a) == 0 {
|
||||
if bval, ok := indexValue(b); ok {
|
||||
return &refindex{Ref: Ref{FunctionArgRootDocument, InternedTerm(i)}, Value: bval}, true
|
||||
}
|
||||
}
|
||||
// a is a var, but we have not been able to resolve it to a ref, save for later
|
||||
if IsConstant(b) {
|
||||
constants[v] = b
|
||||
}
|
||||
|
||||
bval, ok := indexValue(b)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if ref := resolveVarToRef(i.rules[rule], args, v); ref != nil {
|
||||
i.insert(rule, &refindex{Ref: ref, Value: bval})
|
||||
return true
|
||||
}
|
||||
|
||||
case Ref:
|
||||
if !RootDocumentNames.Contains(v[0]) {
|
||||
return nil, false
|
||||
if !i.isValidIndexRef(v) {
|
||||
return false
|
||||
}
|
||||
if isVirtual(v) {
|
||||
return nil, false
|
||||
}
|
||||
if v.IsNested() || !v.IsGround() {
|
||||
return nil, false
|
||||
}
|
||||
if bval, ok := indexValue(b); ok {
|
||||
return &refindex{Ref: v, Value: bval}, true
|
||||
|
||||
if bvar, ok := b.(Var); ok { // cheaper lookup first: constants
|
||||
if resolved, ok := constants[bvar]; ok {
|
||||
b = resolved
|
||||
}
|
||||
} else if bval, ok := indexValue(b); ok {
|
||||
b = bval
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
|
||||
i.insert(rule, &refindex{Ref: v, Value: b})
|
||||
return true
|
||||
}
|
||||
return nil, false
|
||||
return false
|
||||
}
|
||||
|
||||
func indexValue(b Value) (Value, bool) {
|
||||
|
||||
219
vendor/github.com/open-policy-agent/opa/v1/ast/index_debug.go
generated
vendored
Normal file
219
vendor/github.com/open-policy-agent/opa/v1/ast/index_debug.go
generated
vendored
Normal file
@@ -0,0 +1,219 @@
|
||||
// Copyright 2026 The OPA Authors. All rights reserved.
|
||||
// Use of this source code is governed by an Apache2
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ast
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (node *trieNode) mermaid() string {
|
||||
var sb strings.Builder
|
||||
sb.WriteString("graph TD\n")
|
||||
nodeCounter := 0
|
||||
nodeIDs := make(map[*trieNode]string)
|
||||
node.mermaidFormat(&sb, &nodeCounter, nodeIDs, "")
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
func (node *trieNode) mermaidFormat(sb *strings.Builder, counter *int, nodeIDs map[*trieNode]string, parentID string) {
|
||||
currentID, exists := nodeIDs[node]
|
||||
if !exists {
|
||||
currentID = fmt.Sprintf("n%d", *counter)
|
||||
*counter++
|
||||
nodeIDs[node] = currentID
|
||||
label := node.mermaidLabel()
|
||||
fmt.Fprintf(sb, " %s[\"%s\"]\n", currentID, label)
|
||||
}
|
||||
|
||||
if parentID != "" {
|
||||
fmt.Fprintf(sb, " %s --> %s\n", parentID, currentID)
|
||||
}
|
||||
|
||||
if exists {
|
||||
return
|
||||
}
|
||||
|
||||
if node.undefined != nil {
|
||||
if childID, childExists := nodeIDs[node.undefined]; childExists {
|
||||
fmt.Fprintf(sb, " %s -->|undefined| %s\n", currentID, childID)
|
||||
} else {
|
||||
node.undefined.mermaidFormat(sb, counter, nodeIDs, "")
|
||||
fmt.Fprintf(sb, " %s -->|undefined| %s\n", currentID, nodeIDs[node.undefined])
|
||||
}
|
||||
}
|
||||
|
||||
if node.any != nil {
|
||||
if childID, childExists := nodeIDs[node.any]; childExists {
|
||||
fmt.Fprintf(sb, " %s -->|any| %s\n", currentID, childID)
|
||||
} else {
|
||||
node.any.mermaidFormat(sb, counter, nodeIDs, "")
|
||||
fmt.Fprintf(sb, " %s -->|any| %s\n", currentID, nodeIDs[node.any])
|
||||
}
|
||||
}
|
||||
|
||||
if node.scalars.Len() > 0 {
|
||||
type scalarPair struct {
|
||||
key Value
|
||||
node *trieNode
|
||||
}
|
||||
pairs := make([]scalarPair, 0, node.scalars.Len())
|
||||
node.scalars.Iter(func(key Value, val *trieNode) bool {
|
||||
pairs = append(pairs, scalarPair{key, val})
|
||||
return false
|
||||
})
|
||||
sort.Slice(pairs, func(a, b int) bool {
|
||||
return pairs[a].key.Compare(pairs[b].key) < 0
|
||||
})
|
||||
for _, pair := range pairs {
|
||||
var scalarLabel string
|
||||
if s, ok := pair.key.(String); ok {
|
||||
scalarLabel = string(s)
|
||||
} else {
|
||||
scalarLabel = pair.key.String()
|
||||
}
|
||||
if len(scalarLabel) > 20 {
|
||||
scalarLabel = scalarLabel[:20] + "..."
|
||||
}
|
||||
scalarLabel = mermaidEscape(scalarLabel)
|
||||
if childID, childExists := nodeIDs[pair.node]; childExists {
|
||||
fmt.Fprintf(sb, " %s -->|\"%s\"| %s\n", currentID, scalarLabel, childID)
|
||||
} else {
|
||||
pair.node.mermaidFormat(sb, counter, nodeIDs, "")
|
||||
fmt.Fprintf(sb, " %s -->|\"%s\"| %s\n", currentID, scalarLabel, nodeIDs[pair.node])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if node.array != nil {
|
||||
if childID, childExists := nodeIDs[node.array]; childExists {
|
||||
fmt.Fprintf(sb, " %s -->|array| %s\n", currentID, childID)
|
||||
} else {
|
||||
node.array.mermaidFormat(sb, counter, nodeIDs, "")
|
||||
fmt.Fprintf(sb, " %s -->|array| %s\n", currentID, nodeIDs[node.array])
|
||||
}
|
||||
}
|
||||
|
||||
if node.next != nil {
|
||||
node.next.mermaidFormat(sb, counter, nodeIDs, currentID)
|
||||
}
|
||||
}
|
||||
|
||||
func (node *trieNode) mermaidLabel() string {
|
||||
var parts []string
|
||||
|
||||
if len(node.ref) > 0 {
|
||||
parts = append(parts, node.ref.String())
|
||||
}
|
||||
|
||||
if len(node.rules) > 0 {
|
||||
for _, rn := range node.rules {
|
||||
bodyStr := ""
|
||||
if rn.rule.Body != nil {
|
||||
bodyStr = rn.rule.Body.String()
|
||||
if len(bodyStr) > 50 {
|
||||
bodyStr = bodyStr[:50] + "..."
|
||||
}
|
||||
}
|
||||
bodyStr = mermaidEscape(bodyStr)
|
||||
parts = append(parts, bodyStr)
|
||||
}
|
||||
}
|
||||
|
||||
if len(node.mappers) > 0 {
|
||||
parts = append(parts, fmt.Sprintf("%d mapper(s)", len(node.mappers)))
|
||||
}
|
||||
if node.multiple {
|
||||
parts = append(parts, "multiple")
|
||||
}
|
||||
|
||||
if len(parts) == 0 {
|
||||
return "·"
|
||||
}
|
||||
|
||||
return strings.Join(parts, "<br/>")
|
||||
}
|
||||
|
||||
func mermaidEscape(s string) string {
|
||||
s = strings.ReplaceAll(s, `"`, `"`)
|
||||
return s
|
||||
}
|
||||
|
||||
func (node *trieNode) String() string {
|
||||
var sb strings.Builder
|
||||
node.format(&sb, 0)
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
func (node *trieNode) format(sb *strings.Builder, depth int) {
|
||||
indent := strings.Repeat(" ", depth)
|
||||
|
||||
if len(node.ref) > 0 {
|
||||
sb.WriteString(indent)
|
||||
sb.WriteString(node.ref.String())
|
||||
} else if depth == 0 {
|
||||
sb.WriteString("root")
|
||||
}
|
||||
|
||||
if len(node.rules) > 0 {
|
||||
fmt.Fprintf(sb, " [%d rule(s)]", len(node.rules))
|
||||
}
|
||||
if len(node.mappers) > 0 {
|
||||
fmt.Fprintf(sb, " [%d mapper(s)]", len(node.mappers))
|
||||
}
|
||||
if node.value != nil {
|
||||
fmt.Fprintf(sb, " value=%v", node.value)
|
||||
}
|
||||
if node.multiple {
|
||||
sb.WriteString(" [multiple]")
|
||||
}
|
||||
sb.WriteString("\n")
|
||||
|
||||
if node.undefined != nil {
|
||||
sb.WriteString(indent)
|
||||
sb.WriteString(" undefined:\n")
|
||||
node.undefined.format(sb, depth+2)
|
||||
}
|
||||
|
||||
if node.any != nil {
|
||||
sb.WriteString(indent)
|
||||
sb.WriteString(" any:\n")
|
||||
node.any.format(sb, depth+2)
|
||||
}
|
||||
|
||||
if node.scalars.Len() > 0 {
|
||||
scalars := make([]Value, 0, node.scalars.Len())
|
||||
nodes := make([]*trieNode, 0, node.scalars.Len())
|
||||
node.scalars.Iter(func(key Value, val *trieNode) bool {
|
||||
scalars = append(scalars, key)
|
||||
nodes = append(nodes, val)
|
||||
return false
|
||||
})
|
||||
sort.Slice(scalars, func(a, b int) bool {
|
||||
return scalars[a].Compare(scalars[b]) < 0
|
||||
})
|
||||
for i := range scalars {
|
||||
sb.WriteString(indent)
|
||||
fmt.Fprintf(sb, " %v:\n", scalars[i])
|
||||
for j := range nodes {
|
||||
if ValueEqual(scalars[i], scalars[j]) {
|
||||
nodes[j].format(sb, depth+2)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if node.array != nil {
|
||||
sb.WriteString(indent)
|
||||
sb.WriteString(" array:\n")
|
||||
node.array.format(sb, depth+2)
|
||||
}
|
||||
|
||||
if node.next != nil {
|
||||
node.next.format(sb, depth)
|
||||
}
|
||||
}
|
||||
18
vendor/github.com/open-policy-agent/opa/v1/ast/policy_appenders.go
generated
vendored
18
vendor/github.com/open-policy-agent/opa/v1/ast/policy_appenders.go
generated
vendored
@@ -3,6 +3,8 @@ package ast
|
||||
import (
|
||||
"encoding"
|
||||
"fmt"
|
||||
|
||||
"github.com/open-policy-agent/opa/v1/util"
|
||||
)
|
||||
|
||||
func (m *Module) AppendText(buf []byte) ([]byte, error) {
|
||||
@@ -322,3 +324,19 @@ func (d *SomeDecl) AppendText(buf []byte) ([]byte, error) {
|
||||
func (c *Comment) AppendText(buf []byte) ([]byte, error) {
|
||||
return append(append(buf, '#'), c.Text...), nil
|
||||
}
|
||||
|
||||
// RulePath returns the string representation of the rule's path, i.e. its package path followed by the rule head ref.
|
||||
func RulePath(r *Rule) string {
|
||||
if r == nil {
|
||||
return "<nil rule>"
|
||||
}
|
||||
if r.Module == nil {
|
||||
return "<rule " + r.Head.Reference.String() + " without module>"
|
||||
}
|
||||
buf := make([]byte, 0, r.Module.Package.Path.StringLength()+r.Head.Ref().StringLength()+1)
|
||||
buf, _ = r.Module.Package.Path.AppendText(buf)
|
||||
buf = append(buf, '.')
|
||||
buf, _ = r.Head.Ref().AppendText(buf)
|
||||
|
||||
return util.ByteSliceToString(buf)
|
||||
}
|
||||
|
||||
2
vendor/github.com/open-policy-agent/opa/v1/capabilities/capabilities.go
generated
vendored
2
vendor/github.com/open-policy-agent/opa/v1/capabilities/capabilities.go
generated
vendored
@@ -5,7 +5,7 @@
|
||||
package capabilities
|
||||
|
||||
import (
|
||||
v0 "github.com/open-policy-agent/opa/capabilities"
|
||||
v0 "github.com/open-policy-agent/opa/capabilities" //nolint:staticcheck
|
||||
)
|
||||
|
||||
// FS contains the embedded capabilities/ directory of the built version,
|
||||
|
||||
182
vendor/github.com/open-policy-agent/opa/v1/logging/buffered_logger.go
generated
vendored
Normal file
182
vendor/github.com/open-policy-agent/opa/v1/logging/buffered_logger.go
generated
vendored
Normal file
@@ -0,0 +1,182 @@
|
||||
package logging
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"maps"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type logEntry struct {
|
||||
level Level
|
||||
message string
|
||||
fields map[string]any
|
||||
time time.Time
|
||||
}
|
||||
|
||||
// BufferedLogger captures log entries in memory until Flush is called,
|
||||
// at which point it replays all buffered entries to the target logger.
|
||||
// After Flush() is called, the BufferedLogger should not be used anymore.
|
||||
type BufferedLogger struct {
|
||||
mu sync.Mutex
|
||||
buffer []logEntry
|
||||
maxEntries int
|
||||
currentLevel Level
|
||||
}
|
||||
|
||||
// NewBufferedLogger creates a new buffered logger that will buffer up to maxEntries.
|
||||
func NewBufferedLogger(maxEntries int) *BufferedLogger {
|
||||
if maxEntries <= 0 {
|
||||
maxEntries = 1000
|
||||
}
|
||||
return &BufferedLogger{
|
||||
buffer: make([]logEntry, 0, maxEntries),
|
||||
maxEntries: maxEntries,
|
||||
currentLevel: Info,
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BufferedLogger) addToBuffer(level Level, format string, args []any, fields map[string]any) {
|
||||
message := format
|
||||
if len(args) > 0 {
|
||||
message = fmt.Sprintf(format, args...)
|
||||
}
|
||||
|
||||
entry := logEntry{
|
||||
level: level,
|
||||
message: message,
|
||||
fields: fields,
|
||||
time: time.Now(),
|
||||
}
|
||||
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
|
||||
if len(b.buffer) >= b.maxEntries {
|
||||
b.buffer = b.buffer[1:]
|
||||
}
|
||||
b.buffer = append(b.buffer, entry)
|
||||
}
|
||||
|
||||
func (*BufferedLogger) logToTarget(target Logger, entry logEntry) {
|
||||
fields := make(map[string]any, len(entry.fields))
|
||||
maps.Copy(fields, entry.fields)
|
||||
fields["time"] = entry.time
|
||||
|
||||
logger := target.WithFields(fields)
|
||||
|
||||
switch entry.level {
|
||||
case Debug:
|
||||
logger.Debug("%s", entry.message)
|
||||
case Info:
|
||||
logger.Info("%s", entry.message)
|
||||
case Warn:
|
||||
logger.Warn("%s", entry.message)
|
||||
case Error:
|
||||
logger.Error("%s", entry.message)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BufferedLogger) Debug(format string, args ...any) {
|
||||
b.addToBuffer(Debug, format, args, nil)
|
||||
}
|
||||
|
||||
func (b *BufferedLogger) Info(format string, args ...any) {
|
||||
b.addToBuffer(Info, format, args, nil)
|
||||
}
|
||||
|
||||
func (b *BufferedLogger) Warn(format string, args ...any) {
|
||||
b.addToBuffer(Warn, format, args, nil)
|
||||
}
|
||||
|
||||
func (b *BufferedLogger) Error(format string, args ...any) {
|
||||
b.addToBuffer(Error, format, args, nil)
|
||||
}
|
||||
|
||||
// WithFields returns a new logger with additional fields.
|
||||
func (b *BufferedLogger) WithFields(fields map[string]any) Logger {
|
||||
return &bufferedLoggerWithFields{
|
||||
parent: b,
|
||||
fields: fields,
|
||||
}
|
||||
}
|
||||
|
||||
// GetLevel returns the current log level.
|
||||
func (b *BufferedLogger) GetLevel() Level {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
return b.currentLevel
|
||||
}
|
||||
|
||||
// SetLevel sets the log level.
|
||||
func (b *BufferedLogger) SetLevel(level Level) {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
b.currentLevel = level
|
||||
}
|
||||
|
||||
// Close discards all buffered entries without flushing them.
|
||||
// After calling Close, the BufferedLogger should not be used anymore.
|
||||
func (b *BufferedLogger) Close() {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
b.buffer = nil
|
||||
}
|
||||
|
||||
// Flush replays all buffered entries to the target logger.
|
||||
// After calling Flush, the BufferedLogger should not be used anymore.
|
||||
// The caller should switch to using the target logger directly.
|
||||
func (b *BufferedLogger) Flush(targetLogger Logger) {
|
||||
if targetLogger == nil {
|
||||
return
|
||||
}
|
||||
|
||||
b.mu.Lock()
|
||||
targetLogger.SetLevel(b.currentLevel)
|
||||
entries := b.buffer
|
||||
b.buffer = nil
|
||||
b.mu.Unlock()
|
||||
|
||||
for _, entry := range entries {
|
||||
b.logToTarget(targetLogger, entry)
|
||||
}
|
||||
}
|
||||
|
||||
type bufferedLoggerWithFields struct {
|
||||
parent *BufferedLogger
|
||||
fields map[string]any
|
||||
}
|
||||
|
||||
func (b *bufferedLoggerWithFields) Debug(format string, args ...any) {
|
||||
b.parent.addToBuffer(Debug, format, args, b.fields)
|
||||
}
|
||||
|
||||
func (b *bufferedLoggerWithFields) Info(format string, args ...any) {
|
||||
b.parent.addToBuffer(Info, format, args, b.fields)
|
||||
}
|
||||
|
||||
func (b *bufferedLoggerWithFields) Warn(format string, args ...any) {
|
||||
b.parent.addToBuffer(Warn, format, args, b.fields)
|
||||
}
|
||||
|
||||
func (b *bufferedLoggerWithFields) Error(format string, args ...any) {
|
||||
b.parent.addToBuffer(Error, format, args, b.fields)
|
||||
}
|
||||
|
||||
func (b *bufferedLoggerWithFields) WithFields(fields map[string]any) Logger {
|
||||
merged := make(map[string]any, len(b.fields)+len(fields))
|
||||
maps.Copy(merged, b.fields)
|
||||
maps.Copy(merged, fields)
|
||||
return &bufferedLoggerWithFields{
|
||||
parent: b.parent,
|
||||
fields: merged,
|
||||
}
|
||||
}
|
||||
|
||||
func (b *bufferedLoggerWithFields) GetLevel() Level {
|
||||
return b.parent.GetLevel()
|
||||
}
|
||||
|
||||
func (b *bufferedLoggerWithFields) SetLevel(level Level) {
|
||||
b.parent.SetLevel(level)
|
||||
}
|
||||
196
vendor/github.com/open-policy-agent/opa/v1/logging/logging.go
generated
vendored
196
vendor/github.com/open-policy-agent/opa/v1/logging/logging.go
generated
vendored
@@ -2,9 +2,12 @@ package logging
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"maps"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
@@ -36,6 +39,23 @@ type Logger interface {
|
||||
SetLevel(Level)
|
||||
}
|
||||
|
||||
// LoggerWithContext is an optional interface that Logger implementations
|
||||
// can implement to support extracting trace information from a context.
|
||||
// Use WithContext to call this method on a Logger if it is supported.
|
||||
type LoggerWithContext interface {
|
||||
WithContext(context.Context) Logger
|
||||
}
|
||||
|
||||
// WithContext returns a logger with context information if the logger
|
||||
// supports it (i.e., implements LoggerWithContext). Otherwise, the
|
||||
// logger is returned unchanged.
|
||||
func WithContext(logger Logger, ctx context.Context) Logger {
|
||||
if lc, ok := logger.(LoggerWithContext); ok {
|
||||
return lc.WithContext(ctx)
|
||||
}
|
||||
return logger
|
||||
}
|
||||
|
||||
// StandardLogger is the default OPA logger implementation.
|
||||
type StandardLogger struct {
|
||||
logger *logrus.Logger
|
||||
@@ -272,3 +292,179 @@ func BatchDecisionIDFromContext(ctx context.Context) (string, bool) {
|
||||
s, ok := ctx.Value(batchDecisionCtxKey).(string)
|
||||
return s, ok
|
||||
}
|
||||
|
||||
// SlogHandler adapts a Logger to slog.Handler interface
|
||||
type SlogHandler struct {
|
||||
logger Logger
|
||||
}
|
||||
|
||||
// NewSlogHandler creates an slog.Handler from a Logger
|
||||
func NewSlogHandler(logger Logger) slog.Handler {
|
||||
return &SlogHandler{logger: logger}
|
||||
}
|
||||
|
||||
func (h *SlogHandler) Enabled(_ context.Context, level slog.Level) bool {
|
||||
lvl := h.logger.GetLevel()
|
||||
switch level {
|
||||
case slog.LevelDebug:
|
||||
return lvl >= Debug
|
||||
case slog.LevelInfo:
|
||||
return lvl >= Info
|
||||
case slog.LevelWarn:
|
||||
return lvl >= Warn
|
||||
case slog.LevelError:
|
||||
return lvl >= Error
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (h *SlogHandler) Handle(ctx context.Context, record slog.Record) error {
|
||||
attrs := make(map[string]any)
|
||||
record.Attrs(func(a slog.Attr) bool {
|
||||
attrs[a.Key] = a.Value.Any()
|
||||
return true
|
||||
})
|
||||
|
||||
logger := h.logger
|
||||
if len(attrs) > 0 {
|
||||
logger = logger.WithFields(attrs)
|
||||
}
|
||||
if ctx != nil {
|
||||
logger = WithContext(logger, ctx)
|
||||
}
|
||||
|
||||
msg := record.Message
|
||||
switch record.Level {
|
||||
case slog.LevelDebug:
|
||||
logger.Debug(msg)
|
||||
case slog.LevelInfo:
|
||||
logger.Info(msg)
|
||||
case slog.LevelWarn:
|
||||
logger.Warn(msg)
|
||||
case slog.LevelError:
|
||||
logger.Error(msg)
|
||||
default:
|
||||
logger.Info(msg)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *SlogHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
|
||||
fields := make(map[string]any, len(attrs))
|
||||
for _, a := range attrs {
|
||||
fields[a.Key] = a.Value.Any()
|
||||
}
|
||||
return &SlogHandler{
|
||||
logger: h.logger.WithFields(fields),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *SlogHandler) WithGroup(name string) slog.Handler {
|
||||
return h
|
||||
}
|
||||
|
||||
// loggerFromSlogHandler wraps an slog.Handler to implement the Logger interface
|
||||
type loggerFromSlogHandler struct {
|
||||
handler slog.Handler
|
||||
level Level
|
||||
fields map[string]any
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
var _ LoggerWithContext = (*loggerFromSlogHandler)(nil)
|
||||
|
||||
// NewLoggerFromSlogHandler creates a Logger from an slog.Handler
|
||||
func NewLoggerFromSlogHandler(handler slog.Handler, level Level) Logger {
|
||||
return &loggerFromSlogHandler{
|
||||
handler: handler,
|
||||
level: level,
|
||||
fields: make(map[string]any),
|
||||
ctx: context.Background(),
|
||||
}
|
||||
}
|
||||
|
||||
func (l *loggerFromSlogHandler) log(level slog.Level, format string, args ...any) {
|
||||
if !l.handler.Enabled(l.ctx, level) {
|
||||
return
|
||||
}
|
||||
msg := format
|
||||
if len(args) > 0 {
|
||||
msg = fmt.Sprintf(format, args...)
|
||||
}
|
||||
|
||||
attrs := make([]slog.Attr, 0, len(l.fields))
|
||||
for k, v := range l.fields {
|
||||
var attr slog.Attr
|
||||
switch val := v.(type) {
|
||||
case string:
|
||||
attr = slog.String(k, val)
|
||||
case int:
|
||||
attr = slog.Int(k, val)
|
||||
case int64:
|
||||
attr = slog.Int64(k, val)
|
||||
case uint64:
|
||||
attr = slog.Uint64(k, val)
|
||||
case float64:
|
||||
attr = slog.Float64(k, val)
|
||||
case bool:
|
||||
attr = slog.Bool(k, val)
|
||||
case time.Time:
|
||||
attr = slog.Time(k, val)
|
||||
case time.Duration:
|
||||
attr = slog.Duration(k, val)
|
||||
default:
|
||||
attr = slog.Any(k, v)
|
||||
}
|
||||
attrs = append(attrs, attr)
|
||||
}
|
||||
|
||||
record := slog.NewRecord(time.Now(), level, msg, 0)
|
||||
record.AddAttrs(attrs...)
|
||||
|
||||
_ = l.handler.Handle(l.ctx, record)
|
||||
}
|
||||
|
||||
func (l *loggerFromSlogHandler) Debug(format string, args ...any) {
|
||||
l.log(slog.LevelDebug, format, args...)
|
||||
}
|
||||
|
||||
func (l *loggerFromSlogHandler) Info(format string, args ...any) {
|
||||
l.log(slog.LevelInfo, format, args...)
|
||||
}
|
||||
|
||||
func (l *loggerFromSlogHandler) Warn(format string, args ...any) {
|
||||
l.log(slog.LevelWarn, format, args...)
|
||||
}
|
||||
|
||||
func (l *loggerFromSlogHandler) Error(format string, args ...any) {
|
||||
l.log(slog.LevelError, format, args...)
|
||||
}
|
||||
|
||||
func (l *loggerFromSlogHandler) WithFields(fields map[string]any) Logger {
|
||||
merged := make(map[string]any, len(l.fields)+len(fields))
|
||||
maps.Copy(merged, l.fields)
|
||||
maps.Copy(merged, fields)
|
||||
return &loggerFromSlogHandler{
|
||||
handler: l.handler,
|
||||
level: l.level,
|
||||
fields: merged,
|
||||
ctx: l.ctx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *loggerFromSlogHandler) WithContext(ctx context.Context) Logger {
|
||||
return &loggerFromSlogHandler{
|
||||
handler: l.handler,
|
||||
level: l.level,
|
||||
fields: l.fields,
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *loggerFromSlogHandler) GetLevel() Level {
|
||||
return l.level
|
||||
}
|
||||
|
||||
func (l *loggerFromSlogHandler) SetLevel(level Level) {
|
||||
l.level = level
|
||||
}
|
||||
|
||||
6
vendor/github.com/open-policy-agent/opa/v1/rego/plugins.go
generated
vendored
6
vendor/github.com/open-policy-agent/opa/v1/rego/plugins.go
generated
vendored
@@ -41,3 +41,9 @@ func RegisterPlugin(name string, p TargetPlugin) {
|
||||
}
|
||||
targetPlugins[name] = p
|
||||
}
|
||||
|
||||
func ResetTargetPlugins() {
|
||||
pluginMtx.Lock()
|
||||
defer pluginMtx.Unlock()
|
||||
targetPlugins = map[string]TargetPlugin{}
|
||||
}
|
||||
|
||||
8
vendor/github.com/open-policy-agent/opa/v1/rego/rego.go
generated
vendored
8
vendor/github.com/open-policy-agent/opa/v1/rego/rego.go
generated
vendored
@@ -42,10 +42,7 @@ import (
|
||||
const (
|
||||
defaultPartialNamespace = "partial"
|
||||
wasmVarPrefix = "^"
|
||||
)
|
||||
|
||||
// nolint:varcheck
|
||||
const (
|
||||
targetWasm = "wasm"
|
||||
targetRego = "rego"
|
||||
)
|
||||
@@ -1371,6 +1368,7 @@ func New(options ...func(r *Rego)) *Rego {
|
||||
callHook := r.compiler == nil // call hook only if we created the compiler here
|
||||
|
||||
if r.compiler == nil {
|
||||
//nolint:staticcheck
|
||||
r.compiler = ast.NewCompiler().
|
||||
WithUnsafeBuiltins(r.unsafeBuiltins).
|
||||
WithBuiltins(r.builtinDecls).
|
||||
@@ -2496,7 +2494,7 @@ func (r *Rego) partialResult(ctx context.Context, pCfg *PrepareConfig) (PartialR
|
||||
Module: module,
|
||||
}
|
||||
module.Rules[i] = rule
|
||||
if checkPartialResultForRecursiveRefs(body, rule.Path()) {
|
||||
if checkPartialResultForRecursiveRefs(body, module.Package.Path.Extend(rule.Head.Reference.GroundPrefix())) {
|
||||
return PartialResult{}, Errors{errPartialEvaluationNotEffective}
|
||||
}
|
||||
}
|
||||
@@ -2687,7 +2685,7 @@ func (r *Rego) rewriteQueryToCaptureValue(_ ast.QueryCompiler, query ast.Body) (
|
||||
expr.Terms = ast.Equality.Expr(terms, capture).Terms
|
||||
r.capture[expr] = capture.Value.(ast.Var)
|
||||
case []*ast.Term:
|
||||
tpe := r.compiler.TypeEnv.Get(terms[0])
|
||||
tpe := r.compiler.TypeEnv.GetByValue(terms[0].Value)
|
||||
if !types.Void(tpe) && types.Arity(tpe) == len(terms)-1 {
|
||||
capture = r.generateTermVar()
|
||||
expr.Terms = append(terms, capture)
|
||||
|
||||
29
vendor/github.com/open-policy-agent/opa/v1/topdown/eval.go
generated
vendored
29
vendor/github.com/open-policy-agent/opa/v1/topdown/eval.go
generated
vendored
@@ -318,7 +318,6 @@ func (e *eval) traceUnify(a, b *ast.Term) {
|
||||
}
|
||||
|
||||
func (e *eval) traceEvent(op Op, x ast.Node, msg string, target *ast.Ref) {
|
||||
|
||||
if !e.traceEnabled {
|
||||
return
|
||||
}
|
||||
@@ -3374,15 +3373,26 @@ func (vcKeyScope) IsGround() bool {
|
||||
}
|
||||
|
||||
func (q vcKeyScope) String() string {
|
||||
buf := make([]string, 0, len(q.Ref))
|
||||
buf, _ := q.AppendText(make([]byte, 0, 2+q.StringLength()))
|
||||
return util.ByteSliceToString(buf)
|
||||
}
|
||||
|
||||
func (q vcKeyScope) AppendText(buf []byte) ([]byte, error) {
|
||||
buf = append(buf, '<')
|
||||
for _, t := range q.Ref {
|
||||
if _, ok := t.Value.(ast.Var); ok {
|
||||
buf = append(buf, "_")
|
||||
buf = append(buf, '_')
|
||||
} else {
|
||||
buf = append(buf, t.String())
|
||||
var err error
|
||||
if buf, err = t.AppendText(buf); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
buf = append(buf, ',')
|
||||
}
|
||||
return fmt.Sprintf("<%s>", strings.Join(buf, ","))
|
||||
buf[len(buf)-1] = '>'
|
||||
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
// reduce removes vars from the tail of the ref.
|
||||
@@ -3633,6 +3643,7 @@ func (e evalVirtualComplete) evalValueRule(iter unifyIterator, rule *ast.Rule, p
|
||||
e.e.childWithBindingSizeHint(rule.Body, child, ast.EstimateBodyBindingCount(rule.Body))
|
||||
child.findOne = findOne
|
||||
child.traceEnter(rule)
|
||||
|
||||
var result *ast.Term
|
||||
err := child.eval(func(child *eval) error {
|
||||
child.traceExit(rule)
|
||||
@@ -3651,8 +3662,7 @@ func (e evalVirtualComplete) evalValueRule(iter unifyIterator, rule *ast.Rule, p
|
||||
e.e.virtualCache.Put(e.plugged[:e.pos+1], result)
|
||||
|
||||
term, termbindings := child.bindings.apply(rule.Head.Value)
|
||||
err := e.evalTerm(iter, term, termbindings)
|
||||
if err != nil {
|
||||
if err := e.evalTerm(iter, term, termbindings); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -3676,8 +3686,7 @@ func (e evalVirtualComplete) partialEval(iter unifyIterator) error {
|
||||
child.traceExit(rule)
|
||||
term, termbindings := child.bindings.apply(rule.Head.Value)
|
||||
|
||||
err := e.evalTerm(iter, term, termbindings)
|
||||
if err != nil {
|
||||
if err := e.evalTerm(iter, term, termbindings); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -4329,7 +4338,7 @@ func isFunction(env *ast.TypeEnv, ref any) bool {
|
||||
default:
|
||||
panic("expected ast.Value or *ast.Term")
|
||||
}
|
||||
_, ok := env.Get(r).(*types.Function)
|
||||
_, ok := env.GetByRef(r).(*types.Function)
|
||||
return ok
|
||||
}
|
||||
|
||||
|
||||
10
vendor/github.com/open-policy-agent/opa/v1/topdown/graphql.go
generated
vendored
10
vendor/github.com/open-policy-agent/opa/v1/topdown/graphql.go
generated
vendored
@@ -13,15 +13,15 @@ import (
|
||||
gqlast "github.com/vektah/gqlparser/v2/ast"
|
||||
gqlparser "github.com/vektah/gqlparser/v2/parser"
|
||||
gqlvalidator "github.com/vektah/gqlparser/v2/validator"
|
||||
|
||||
// Side-effecting import. Triggers GraphQL library's validation rule init() functions.
|
||||
_ "github.com/vektah/gqlparser/v2/validator/rules"
|
||||
"github.com/vektah/gqlparser/v2/validator/rules"
|
||||
|
||||
"github.com/open-policy-agent/opa/v1/ast"
|
||||
"github.com/open-policy-agent/opa/v1/topdown/builtins"
|
||||
"github.com/open-policy-agent/opa/v1/topdown/cache"
|
||||
)
|
||||
|
||||
var defaultRules = rules.NewDefaultRules()
|
||||
|
||||
// Parses a GraphQL schema, and returns the GraphQL AST for the schema.
|
||||
func parseSchema(schema string) (*gqlast.SchemaDocument, error) {
|
||||
// NOTE(philipc): We don't include the "built-in schema defs" from the
|
||||
@@ -51,8 +51,7 @@ func parseQuery(query string) (*gqlast.QueryDocument, error) {
|
||||
// just the first error message in the list.
|
||||
func validateQuery(schema *gqlast.Schema, query *gqlast.QueryDocument) error {
|
||||
// Validate the query against the schema, erroring if there's an issue.
|
||||
err := gqlvalidator.Validate(schema, query)
|
||||
if err != nil {
|
||||
if err := gqlvalidator.ValidateWithRules(schema, query, defaultRules); err != nil {
|
||||
return formatGqlParserError(err)
|
||||
}
|
||||
return nil
|
||||
@@ -674,7 +673,6 @@ func cacheKeyWithPrefix(bctx BuiltinContext, t *ast.Term, prefix string) (string
|
||||
const gqlCacheName = "graphql"
|
||||
|
||||
func init() {
|
||||
|
||||
var defaultCacheEntries = 10
|
||||
var graphqlCacheConfig = cache.NamedValueCacheConfig{
|
||||
MaxNumEntries: &defaultCacheEntries,
|
||||
|
||||
2
vendor/github.com/open-policy-agent/opa/v1/topdown/trace.go
generated
vendored
2
vendor/github.com/open-policy-agent/opa/v1/topdown/trace.go
generated
vendored
@@ -411,7 +411,7 @@ func formatEvent(event *Event, depth int) string {
|
||||
|
||||
var details any
|
||||
if node, ok := event.Node.(*ast.Rule); ok {
|
||||
details = node.Path()
|
||||
details = ast.RulePath(node)
|
||||
} else if event.Ref != nil {
|
||||
details = event.Ref
|
||||
} else {
|
||||
|
||||
2
vendor/github.com/open-policy-agent/opa/v1/version/version.go
generated
vendored
2
vendor/github.com/open-policy-agent/opa/v1/version/version.go
generated
vendored
@@ -10,7 +10,7 @@ import (
|
||||
"runtime/debug"
|
||||
)
|
||||
|
||||
var Version = "1.14.1"
|
||||
var Version = "1.15.1"
|
||||
|
||||
// GoVersion is the version of Go this was built with
|
||||
var GoVersion = runtime.Version()
|
||||
|
||||
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@@ -1285,7 +1285,7 @@ github.com/onsi/gomega/matchers/support/goraph/edge
|
||||
github.com/onsi/gomega/matchers/support/goraph/node
|
||||
github.com/onsi/gomega/matchers/support/goraph/util
|
||||
github.com/onsi/gomega/types
|
||||
# github.com/open-policy-agent/opa v1.14.1
|
||||
# github.com/open-policy-agent/opa v1.15.1
|
||||
## explicit; go 1.25.0
|
||||
github.com/open-policy-agent/opa/ast
|
||||
github.com/open-policy-agent/opa/ast/json
|
||||
|
||||
Reference in New Issue
Block a user