feat: kubesphere 4.0 (#6115)
* feat: kubesphere 4.0 Signed-off-by: ci-bot <ci-bot@kubesphere.io> * feat: kubesphere 4.0 Signed-off-by: ci-bot <ci-bot@kubesphere.io> --------- Signed-off-by: ci-bot <ci-bot@kubesphere.io> Co-authored-by: ks-ci-bot <ks-ci-bot@example.com> Co-authored-by: joyceliu <joyceliu@yunify.com>
This commit is contained in:
committed by
GitHub
parent
b5015ec7b9
commit
447a51f08b
43
vendor/github.com/open-policy-agent/opa/rego/plugins.go
generated
vendored
Normal file
43
vendor/github.com/open-policy-agent/opa/rego/plugins.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
// Copyright 2023 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 rego
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/open-policy-agent/opa/ast"
|
||||
"github.com/open-policy-agent/opa/ir"
|
||||
)
|
||||
|
||||
var targetPlugins = map[string]TargetPlugin{}
|
||||
var pluginMtx sync.Mutex
|
||||
|
||||
type TargetPlugin interface {
|
||||
IsTarget(string) bool
|
||||
PrepareForEval(context.Context, *ir.Policy, ...PrepareOption) (TargetPluginEval, error)
|
||||
}
|
||||
|
||||
type TargetPluginEval interface {
|
||||
Eval(context.Context, *EvalContext, ast.Value) (ast.Value, error)
|
||||
}
|
||||
|
||||
func (r *Rego) targetPlugin(tgt string) TargetPlugin {
|
||||
for _, p := range targetPlugins {
|
||||
if p.IsTarget(tgt) {
|
||||
return p
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func RegisterPlugin(name string, p TargetPlugin) {
|
||||
pluginMtx.Lock()
|
||||
defer pluginMtx.Unlock()
|
||||
if _, ok := targetPlugins[name]; ok {
|
||||
panic("plugin already registered " + name)
|
||||
}
|
||||
targetPlugins[name] = p
|
||||
}
|
||||
380
vendor/github.com/open-policy-agent/opa/rego/rego.go
generated
vendored
380
vendor/github.com/open-policy-agent/opa/rego/rego.go
generated
vendored
@@ -25,6 +25,7 @@ import (
|
||||
"github.com/open-policy-agent/opa/ir"
|
||||
"github.com/open-policy-agent/opa/loader"
|
||||
"github.com/open-policy-agent/opa/metrics"
|
||||
"github.com/open-policy-agent/opa/plugins"
|
||||
"github.com/open-policy-agent/opa/resolver"
|
||||
"github.com/open-policy-agent/opa/storage"
|
||||
"github.com/open-policy-agent/opa/storage/inmem"
|
||||
@@ -122,6 +123,55 @@ type EvalContext struct {
|
||||
copyMaps bool
|
||||
printHook print.Hook
|
||||
capabilities *ast.Capabilities
|
||||
strictBuiltinErrors bool
|
||||
}
|
||||
|
||||
func (e *EvalContext) RawInput() *interface{} {
|
||||
return e.rawInput
|
||||
}
|
||||
|
||||
func (e *EvalContext) ParsedInput() ast.Value {
|
||||
return e.parsedInput
|
||||
}
|
||||
|
||||
func (e *EvalContext) Time() time.Time {
|
||||
return e.time
|
||||
}
|
||||
|
||||
func (e *EvalContext) Seed() io.Reader {
|
||||
return e.seed
|
||||
}
|
||||
|
||||
func (e *EvalContext) InterQueryBuiltinCache() cache.InterQueryCache {
|
||||
return e.interQueryBuiltinCache
|
||||
}
|
||||
|
||||
func (e *EvalContext) PrintHook() print.Hook {
|
||||
return e.printHook
|
||||
}
|
||||
|
||||
func (e *EvalContext) Metrics() metrics.Metrics {
|
||||
return e.metrics
|
||||
}
|
||||
|
||||
func (e *EvalContext) StrictBuiltinErrors() bool {
|
||||
return e.strictBuiltinErrors
|
||||
}
|
||||
|
||||
func (e *EvalContext) NDBCache() builtins.NDBCache {
|
||||
return e.ndBuiltinCache
|
||||
}
|
||||
|
||||
func (e *EvalContext) CompiledQuery() ast.Body {
|
||||
return e.compiledQuery.query
|
||||
}
|
||||
|
||||
func (e *EvalContext) Capabilities() *ast.Capabilities {
|
||||
return e.capabilities
|
||||
}
|
||||
|
||||
func (e *EvalContext) Transaction() storage.Transaction {
|
||||
return e.txn
|
||||
}
|
||||
|
||||
// EvalOption defines a function to set an option on an EvalConfig
|
||||
@@ -314,23 +364,24 @@ func (pq preparedQuery) Modules() map[string]*ast.Module {
|
||||
// been opened.
|
||||
func (pq preparedQuery) newEvalContext(ctx context.Context, options []EvalOption) (*EvalContext, func(context.Context), error) {
|
||||
ectx := &EvalContext{
|
||||
hasInput: false,
|
||||
rawInput: nil,
|
||||
parsedInput: nil,
|
||||
metrics: nil,
|
||||
txn: nil,
|
||||
instrument: false,
|
||||
instrumentation: nil,
|
||||
partialNamespace: pq.r.partialNamespace,
|
||||
queryTracers: nil,
|
||||
unknowns: pq.r.unknowns,
|
||||
parsedUnknowns: pq.r.parsedUnknowns,
|
||||
compiledQuery: compiledQuery{},
|
||||
indexing: true,
|
||||
earlyExit: true,
|
||||
resolvers: pq.r.resolvers,
|
||||
printHook: pq.r.printHook,
|
||||
capabilities: pq.r.capabilities,
|
||||
hasInput: false,
|
||||
rawInput: nil,
|
||||
parsedInput: nil,
|
||||
metrics: nil,
|
||||
txn: nil,
|
||||
instrument: false,
|
||||
instrumentation: nil,
|
||||
partialNamespace: pq.r.partialNamespace,
|
||||
queryTracers: nil,
|
||||
unknowns: pq.r.unknowns,
|
||||
parsedUnknowns: pq.r.parsedUnknowns,
|
||||
compiledQuery: compiledQuery{},
|
||||
indexing: true,
|
||||
earlyExit: true,
|
||||
resolvers: pq.r.resolvers,
|
||||
printHook: pq.r.printHook,
|
||||
capabilities: pq.r.capabilities,
|
||||
strictBuiltinErrors: pq.r.strictBuiltinErrors,
|
||||
}
|
||||
|
||||
for _, o := range options {
|
||||
@@ -377,7 +428,9 @@ func (pq preparedQuery) newEvalContext(ctx context.Context, options []EvalOption
|
||||
// Note that it could still be nil
|
||||
ectx.rawInput = pq.r.rawInput
|
||||
}
|
||||
if pq.r.target != targetWasm {
|
||||
|
||||
if pq.r.targetPlugin(pq.r.target) == nil && // no plugin claims this target
|
||||
pq.r.target != targetWasm {
|
||||
ectx.parsedInput, err = pq.r.parseRawInput(ectx.rawInput, ectx.metrics)
|
||||
if err != nil {
|
||||
return nil, finishFunc, err
|
||||
@@ -471,10 +524,10 @@ type queryType int
|
||||
// Define a query type for each of the top level Rego
|
||||
// API's that compile queries differently.
|
||||
const (
|
||||
evalQueryType queryType = iota
|
||||
partialResultQueryType queryType = iota
|
||||
partialQueryType queryType = iota
|
||||
compileQueryType queryType = iota
|
||||
evalQueryType queryType = iota
|
||||
partialResultQueryType
|
||||
partialQueryType
|
||||
compileQueryType
|
||||
)
|
||||
|
||||
type loadPaths struct {
|
||||
@@ -538,11 +591,16 @@ type Rego struct {
|
||||
enablePrintStatements bool
|
||||
distributedTacingOpts tracing.Options
|
||||
strict bool
|
||||
pluginMgr *plugins.Manager
|
||||
plugins []TargetPlugin
|
||||
targetPrepState TargetPluginEval
|
||||
regoVersion ast.RegoVersion
|
||||
}
|
||||
|
||||
// Function represents a built-in function that is callable in Rego.
|
||||
type Function struct {
|
||||
Name string
|
||||
Description string
|
||||
Decl *types.Function
|
||||
Memoize bool
|
||||
Nondeterministic bool
|
||||
@@ -573,6 +631,7 @@ type (
|
||||
func RegisterBuiltin1(decl *Function, impl Builtin1) {
|
||||
ast.RegisterBuiltin(&ast.Builtin{
|
||||
Name: decl.Name,
|
||||
Description: decl.Description,
|
||||
Decl: decl.Decl,
|
||||
Nondeterministic: decl.Nondeterministic,
|
||||
})
|
||||
@@ -586,6 +645,7 @@ func RegisterBuiltin1(decl *Function, impl Builtin1) {
|
||||
func RegisterBuiltin2(decl *Function, impl Builtin2) {
|
||||
ast.RegisterBuiltin(&ast.Builtin{
|
||||
Name: decl.Name,
|
||||
Description: decl.Description,
|
||||
Decl: decl.Decl,
|
||||
Nondeterministic: decl.Nondeterministic,
|
||||
})
|
||||
@@ -599,6 +659,7 @@ func RegisterBuiltin2(decl *Function, impl Builtin2) {
|
||||
func RegisterBuiltin3(decl *Function, impl Builtin3) {
|
||||
ast.RegisterBuiltin(&ast.Builtin{
|
||||
Name: decl.Name,
|
||||
Description: decl.Description,
|
||||
Decl: decl.Decl,
|
||||
Nondeterministic: decl.Nondeterministic,
|
||||
})
|
||||
@@ -612,6 +673,7 @@ func RegisterBuiltin3(decl *Function, impl Builtin3) {
|
||||
func RegisterBuiltin4(decl *Function, impl Builtin4) {
|
||||
ast.RegisterBuiltin(&ast.Builtin{
|
||||
Name: decl.Name,
|
||||
Description: decl.Description,
|
||||
Decl: decl.Decl,
|
||||
Nondeterministic: decl.Nondeterministic,
|
||||
})
|
||||
@@ -625,6 +687,7 @@ func RegisterBuiltin4(decl *Function, impl Builtin4) {
|
||||
func RegisterBuiltinDyn(decl *Function, impl BuiltinDyn) {
|
||||
ast.RegisterBuiltin(&ast.Builtin{
|
||||
Name: decl.Name,
|
||||
Description: decl.Description,
|
||||
Decl: decl.Decl,
|
||||
Nondeterministic: decl.Nondeterministic,
|
||||
})
|
||||
@@ -1131,6 +1194,12 @@ func Strict(yes bool) func(r *Rego) {
|
||||
}
|
||||
}
|
||||
|
||||
func SetRegoVersion(version ast.RegoVersion) func(r *Rego) {
|
||||
return func(r *Rego) {
|
||||
r.regoVersion = version
|
||||
}
|
||||
}
|
||||
|
||||
// New returns a new Rego object.
|
||||
func New(options ...func(r *Rego)) *Rego {
|
||||
|
||||
@@ -1156,7 +1225,13 @@ func New(options ...func(r *Rego)) *Rego {
|
||||
WithCapabilities(r.capabilities).
|
||||
WithEnablePrintStatements(r.enablePrintStatements).
|
||||
WithStrict(r.strict).
|
||||
WithUseTypeCheckAnnotations(r.schemaSet != nil)
|
||||
WithUseTypeCheckAnnotations(true)
|
||||
|
||||
// topdown could be target "" or "rego", but both could be overridden by
|
||||
// a target plugin (checked below)
|
||||
if r.target == targetWasm {
|
||||
r.compiler = r.compiler.WithEvalMode(ast.EvalModeIR)
|
||||
}
|
||||
}
|
||||
|
||||
if r.store == nil {
|
||||
@@ -1188,6 +1263,19 @@ func New(options ...func(r *Rego)) *Rego {
|
||||
r.generateJSON = generateJSON
|
||||
}
|
||||
|
||||
if r.pluginMgr != nil {
|
||||
for _, name := range r.pluginMgr.Plugins() {
|
||||
p := r.pluginMgr.Plugin(name)
|
||||
if p0, ok := p.(TargetPlugin); ok {
|
||||
r.plugins = append(r.plugins, p0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if t := r.targetPlugin(r.target); t != nil {
|
||||
r.compiler = r.compiler.WithEvalMode(ast.EvalModeIR)
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
@@ -1401,64 +1489,32 @@ func (r *Rego) Compile(ctx context.Context, opts ...CompileOption) (*CompileResu
|
||||
queries = []ast.Body{r.compiledQueries[compileQueryType].query}
|
||||
}
|
||||
|
||||
return r.compileWasm(modules, queries, compileQueryType)
|
||||
if tgt := r.targetPlugin(r.target); tgt != nil {
|
||||
return nil, fmt.Errorf("unsupported for rego target plugins")
|
||||
}
|
||||
|
||||
return r.compileWasm(modules, queries, compileQueryType) // TODO(sr) control flow is funky here
|
||||
}
|
||||
|
||||
func (r *Rego) compileWasm(modules []*ast.Module, queries []ast.Body, qType queryType) (*CompileResult, error) {
|
||||
decls := make(map[string]*ast.Builtin, len(r.builtinDecls)+len(ast.BuiltinMap))
|
||||
|
||||
for k, v := range ast.BuiltinMap {
|
||||
decls[k] = v
|
||||
}
|
||||
|
||||
for k, v := range r.builtinDecls {
|
||||
decls[k] = v
|
||||
}
|
||||
|
||||
const queryName = "eval" // NOTE(tsandall): the query name is arbitrary
|
||||
|
||||
p := planner.New().
|
||||
WithQueries([]planner.QuerySet{
|
||||
{
|
||||
Name: queryName,
|
||||
Queries: queries,
|
||||
RewrittenVars: r.compiledQueries[qType].compiler.RewrittenVars(),
|
||||
},
|
||||
}).
|
||||
WithModules(modules).
|
||||
WithBuiltinDecls(decls).
|
||||
WithDebug(r.dump)
|
||||
policy, err := p.Plan()
|
||||
policy, err := r.planQuery(queries, qType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if r.dump != nil {
|
||||
fmt.Fprintln(r.dump, "PLAN:")
|
||||
fmt.Fprintln(r.dump, "-----")
|
||||
err = ir.Pretty(r.dump, policy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fmt.Fprintln(r.dump)
|
||||
}
|
||||
|
||||
m, err := wasm.New().WithPolicy(policy).Compile()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var out bytes.Buffer
|
||||
|
||||
if err := encoding.WriteModule(&out, m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := &CompileResult{
|
||||
return &CompileResult{
|
||||
Bytes: out.Bytes(),
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}, nil
|
||||
}
|
||||
|
||||
// PrepareOption defines a function to set an option to control
|
||||
@@ -1470,6 +1526,7 @@ type PrepareOption func(*PrepareConfig)
|
||||
type PrepareConfig struct {
|
||||
doPartialEval bool
|
||||
disableInlining *[]string
|
||||
builtinFuncs map[string]*topdown.Builtin
|
||||
}
|
||||
|
||||
// WithPartialEval configures an option for PrepareForEval
|
||||
@@ -1488,6 +1545,25 @@ func WithNoInline(paths []string) PrepareOption {
|
||||
}
|
||||
}
|
||||
|
||||
// WithBuiltinFuncs carries the rego.Function{1,2,3} per-query function definitions
|
||||
// to the target plugins.
|
||||
func WithBuiltinFuncs(bis map[string]*topdown.Builtin) PrepareOption {
|
||||
return func(p *PrepareConfig) {
|
||||
if p.builtinFuncs == nil {
|
||||
p.builtinFuncs = make(map[string]*topdown.Builtin, len(bis))
|
||||
}
|
||||
for k, v := range bis {
|
||||
p.builtinFuncs[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BuiltinFuncs allows retrieving the builtin funcs set via PrepareOption
|
||||
// WithBuiltinFuncs.
|
||||
func (p *PrepareConfig) BuiltinFuncs() map[string]*topdown.Builtin {
|
||||
return p.builtinFuncs
|
||||
}
|
||||
|
||||
// PrepareForEval will parse inputs, modules, and query arguments in preparation
|
||||
// of evaluating them.
|
||||
func (r *Rego) PrepareForEval(ctx context.Context, opts ...PrepareOption) (PreparedEvalQuery, error) {
|
||||
@@ -1541,7 +1617,8 @@ func (r *Rego) PrepareForEval(ctx context.Context, opts ...PrepareOption) (Prepa
|
||||
return PreparedEvalQuery{}, err
|
||||
}
|
||||
|
||||
if r.target == targetWasm {
|
||||
switch r.target {
|
||||
case targetWasm: // TODO(sr): make wasm a target plugin, too
|
||||
|
||||
if r.hasWasmModule() {
|
||||
_ = txnClose(ctx, err) // Ignore error
|
||||
@@ -1580,6 +1657,22 @@ func (r *Rego) PrepareForEval(ctx context.Context, opts ...PrepareOption) (Prepa
|
||||
return PreparedEvalQuery{}, err
|
||||
}
|
||||
r.opa = o
|
||||
|
||||
case targetRego: // do nothing, don't lookup default plugin
|
||||
default: // either a specific plugin target, or one that is default
|
||||
if tgt := r.targetPlugin(r.target); tgt != nil {
|
||||
queries := []ast.Body{r.compiledQueries[evalQueryType].query}
|
||||
pol, err := r.planQuery(queries, evalQueryType)
|
||||
if err != nil {
|
||||
return PreparedEvalQuery{}, err
|
||||
}
|
||||
// always add the builtins provided via rego.FunctionN options
|
||||
opts = append(opts, WithBuiltinFuncs(r.builtinFuncs))
|
||||
r.targetPrepState, err = tgt.PrepareForEval(ctx, pol, opts...)
|
||||
if err != nil {
|
||||
return PreparedEvalQuery{}, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
txnErr := txnClose(ctx, err) // Always call closer
|
||||
@@ -1689,22 +1782,20 @@ func (r *Rego) prepare(ctx context.Context, qType queryType, extras []extraStage
|
||||
}
|
||||
|
||||
func (r *Rego) parseModules(ctx context.Context, txn storage.Transaction, m metrics.Metrics) error {
|
||||
if len(r.modules) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
ids, err := r.store.ListPolicies(ctx, txn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// if there are no raw modules, nor modules in the store, then there
|
||||
// is nothing to do.
|
||||
if len(r.modules) == 0 && len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
m.Timer(metrics.RegoModuleParse).Start()
|
||||
defer m.Timer(metrics.RegoModuleParse).Stop()
|
||||
var errs Errors
|
||||
|
||||
// Parse any modules in the are saved to the store, but only if
|
||||
// Parse any modules that are saved to the store, but only if
|
||||
// another compile step is going to occur (ie. we have parsed modules
|
||||
// that need to be compiled).
|
||||
for _, id := range ids {
|
||||
@@ -1719,7 +1810,7 @@ func (r *Rego) parseModules(ctx context.Context, txn storage.Transaction, m metr
|
||||
return err
|
||||
}
|
||||
|
||||
parsed, err := ast.ParseModule(id, string(bs))
|
||||
parsed, err := ast.ParseModuleWithOpts(id, string(bs), ast.ParserOptions{RegoVersion: r.regoVersion})
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
@@ -1729,9 +1820,16 @@ func (r *Rego) parseModules(ctx context.Context, txn storage.Transaction, m metr
|
||||
|
||||
// Parse any passed in as arguments to the Rego object
|
||||
for _, module := range r.modules {
|
||||
p, err := module.Parse()
|
||||
p, err := module.ParseWithOpts(ast.ParserOptions{RegoVersion: r.regoVersion})
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
switch errorWithType := err.(type) {
|
||||
case ast.Errors:
|
||||
for _, e := range errorWithType {
|
||||
errs = append(errs, e)
|
||||
}
|
||||
default:
|
||||
errs = append(errs, errorWithType)
|
||||
}
|
||||
}
|
||||
r.parsedModules[module.filename] = p
|
||||
}
|
||||
@@ -1753,7 +1851,8 @@ func (r *Rego) loadFiles(ctx context.Context, txn storage.Transaction, m metrics
|
||||
|
||||
result, err := loader.NewFileLoader().
|
||||
WithMetrics(m).
|
||||
WithProcessAnnotation(r.schemaSet != nil).
|
||||
WithProcessAnnotation(true).
|
||||
WithRegoVersion(r.regoVersion).
|
||||
Filtered(r.loadPaths.paths, r.loadPaths.filter)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -1782,8 +1881,9 @@ func (r *Rego) loadBundles(ctx context.Context, txn storage.Transaction, m metri
|
||||
for _, path := range r.bundlePaths {
|
||||
bndl, err := loader.NewFileLoader().
|
||||
WithMetrics(m).
|
||||
WithProcessAnnotation(r.schemaSet != nil).
|
||||
WithProcessAnnotation(true).
|
||||
WithSkipBundleVerification(r.skipBundleVerification).
|
||||
WithRegoVersion(r.regoVersion).
|
||||
AsBundle(path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("loading error: %s", err)
|
||||
@@ -1849,13 +1949,14 @@ func (r *Rego) compileModules(ctx context.Context, txn storage.Transaction, m me
|
||||
// Use this as the single-point of compiling everything only a
|
||||
// single time.
|
||||
opts := &bundle.ActivateOpts{
|
||||
Ctx: ctx,
|
||||
Store: r.store,
|
||||
Txn: txn,
|
||||
Compiler: r.compilerForTxn(ctx, r.store, txn),
|
||||
Metrics: m,
|
||||
Bundles: r.bundles,
|
||||
ExtraModules: r.parsedModules,
|
||||
Ctx: ctx,
|
||||
Store: r.store,
|
||||
Txn: txn,
|
||||
Compiler: r.compilerForTxn(ctx, r.store, txn),
|
||||
Metrics: m,
|
||||
Bundles: r.bundles,
|
||||
ExtraModules: r.parsedModules,
|
||||
ParserOptions: ast.ParserOptions{RegoVersion: r.regoVersion},
|
||||
}
|
||||
err := bundle.Activate(opts)
|
||||
if err != nil {
|
||||
@@ -1952,8 +2053,20 @@ func (r *Rego) compileQuery(query ast.Body, imports []*ast.Import, m metrics.Met
|
||||
}
|
||||
|
||||
func (r *Rego) eval(ctx context.Context, ectx *EvalContext) (ResultSet, error) {
|
||||
if r.opa != nil {
|
||||
switch {
|
||||
case r.targetPrepState != nil: // target plugin flow
|
||||
var val ast.Value
|
||||
if r.runtime != nil {
|
||||
val = r.runtime.Value
|
||||
}
|
||||
s, err := r.targetPrepState.Eval(ctx, ectx, val)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return r.valueToQueryResult(s, ectx)
|
||||
case r.target == targetWasm:
|
||||
return r.evalWasm(ctx, ectx)
|
||||
case r.target == targetRego: // continue
|
||||
}
|
||||
|
||||
q := topdown.NewQuery(ectx.compiledQuery.query).
|
||||
@@ -2050,7 +2163,11 @@ func (r *Rego) evalWasm(ctx context.Context, ectx *EvalContext) (ResultSet, erro
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resultSet, ok := parsed.Value.(ast.Set)
|
||||
return r.valueToQueryResult(parsed.Value, ectx)
|
||||
}
|
||||
|
||||
func (r *Rego) valueToQueryResult(res ast.Value, ectx *EvalContext) (ResultSet, error) {
|
||||
resultSet, ok := res.(ast.Set)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("illegal result type")
|
||||
}
|
||||
@@ -2060,7 +2177,7 @@ func (r *Rego) evalWasm(ctx context.Context, ectx *EvalContext) (ResultSet, erro
|
||||
}
|
||||
|
||||
var rs ResultSet
|
||||
err = resultSet.Iter(func(term *ast.Term) error {
|
||||
err := resultSet.Iter(func(term *ast.Term) error {
|
||||
obj, ok := term.Value.(ast.Object)
|
||||
if !ok {
|
||||
return fmt.Errorf("illegal result type")
|
||||
@@ -2137,16 +2254,17 @@ func (r *Rego) partialResult(ctx context.Context, pCfg *PrepareConfig) (PartialR
|
||||
}
|
||||
|
||||
ectx := &EvalContext{
|
||||
parsedInput: r.parsedInput,
|
||||
metrics: r.metrics,
|
||||
txn: r.txn,
|
||||
partialNamespace: r.partialNamespace,
|
||||
queryTracers: r.queryTracers,
|
||||
compiledQuery: r.compiledQueries[partialResultQueryType],
|
||||
instrumentation: r.instrumentation,
|
||||
indexing: true,
|
||||
resolvers: r.resolvers,
|
||||
capabilities: r.capabilities,
|
||||
parsedInput: r.parsedInput,
|
||||
metrics: r.metrics,
|
||||
txn: r.txn,
|
||||
partialNamespace: r.partialNamespace,
|
||||
queryTracers: r.queryTracers,
|
||||
compiledQuery: r.compiledQueries[partialResultQueryType],
|
||||
instrumentation: r.instrumentation,
|
||||
indexing: true,
|
||||
resolvers: r.resolvers,
|
||||
capabilities: r.capabilities,
|
||||
strictBuiltinErrors: r.strictBuiltinErrors,
|
||||
}
|
||||
|
||||
disableInlining := r.disableInlining
|
||||
@@ -2249,7 +2367,7 @@ func (r *Rego) partial(ctx context.Context, ectx *EvalContext) (*PartialQueries,
|
||||
WithSkipPartialNamespace(r.skipPartialNamespace).
|
||||
WithShallowInlining(r.shallowInlining).
|
||||
WithInterQueryBuiltinCache(ectx.interQueryBuiltinCache).
|
||||
WithStrictBuiltinErrors(r.strictBuiltinErrors).
|
||||
WithStrictBuiltinErrors(ectx.strictBuiltinErrors).
|
||||
WithSeed(ectx.seed).
|
||||
WithPrintHook(ectx.printHook)
|
||||
|
||||
@@ -2383,11 +2501,13 @@ func (r *Rego) rewriteEqualsForPartialQueryCompile(_ ast.QueryCompiler, query as
|
||||
|
||||
func (r *Rego) generateTermVar() *ast.Term {
|
||||
r.termVarID++
|
||||
|
||||
if r.target == targetWasm {
|
||||
return ast.VarTerm(wasmVarPrefix + fmt.Sprintf("term%v", r.termVarID))
|
||||
prefix := ast.WildcardPrefix
|
||||
if p := r.targetPlugin(r.target); p != nil {
|
||||
prefix = wasmVarPrefix
|
||||
} else if r.target == targetWasm {
|
||||
prefix = wasmVarPrefix
|
||||
}
|
||||
return ast.VarTerm(ast.WildcardPrefix + fmt.Sprintf("term%v", r.termVarID))
|
||||
return ast.VarTerm(fmt.Sprintf("%sterm%v", prefix, r.termVarID))
|
||||
}
|
||||
|
||||
func (r Rego) hasQuery() bool {
|
||||
@@ -2504,6 +2624,10 @@ func (m rawModule) Parse() (*ast.Module, error) {
|
||||
return ast.ParseModule(m.filename, m.module)
|
||||
}
|
||||
|
||||
func (m rawModule) ParseWithOpts(opts ast.ParserOptions) (*ast.Module, error) {
|
||||
return ast.ParseModuleWithOpts(m.filename, m.module, opts)
|
||||
}
|
||||
|
||||
type extraStage struct {
|
||||
after string
|
||||
stage ast.QueryCompilerStageDefinition
|
||||
@@ -2570,17 +2694,19 @@ func finishFunction(name string, bctx topdown.BuiltinContext, result *ast.Term,
|
||||
if err != nil {
|
||||
var e *HaltError
|
||||
if errors.As(err, &e) {
|
||||
return topdown.Halt{Err: &topdown.Error{
|
||||
tdErr := &topdown.Error{
|
||||
Code: topdown.BuiltinErr,
|
||||
Message: fmt.Sprintf("%v: %v", name, e.Error()),
|
||||
Location: bctx.Location,
|
||||
}}
|
||||
}
|
||||
return topdown.Halt{Err: tdErr.Wrap(e)}
|
||||
}
|
||||
return &topdown.Error{
|
||||
tdErr := &topdown.Error{
|
||||
Code: topdown.BuiltinErr,
|
||||
Message: fmt.Sprintf("%v: %v", name, err.Error()),
|
||||
Location: bctx.Location,
|
||||
}
|
||||
return tdErr.Wrap(err)
|
||||
}
|
||||
if result == nil {
|
||||
return nil
|
||||
@@ -2610,3 +2736,49 @@ func generateJSON(term *ast.Term, ectx *EvalContext) (interface{}, error) {
|
||||
CopyMaps: ectx.copyMaps,
|
||||
})
|
||||
}
|
||||
|
||||
func (r *Rego) planQuery(queries []ast.Body, evalQueryType queryType) (*ir.Policy, error) {
|
||||
modules := make([]*ast.Module, 0, len(r.compiler.Modules))
|
||||
for _, module := range r.compiler.Modules {
|
||||
modules = append(modules, module)
|
||||
}
|
||||
|
||||
decls := make(map[string]*ast.Builtin, len(r.builtinDecls)+len(ast.BuiltinMap))
|
||||
|
||||
for k, v := range ast.BuiltinMap {
|
||||
decls[k] = v
|
||||
}
|
||||
|
||||
for k, v := range r.builtinDecls {
|
||||
decls[k] = v
|
||||
}
|
||||
|
||||
const queryName = "eval" // NOTE(tsandall): the query name is arbitrary
|
||||
|
||||
p := planner.New().
|
||||
WithQueries([]planner.QuerySet{
|
||||
{
|
||||
Name: queryName,
|
||||
Queries: queries,
|
||||
RewrittenVars: r.compiledQueries[evalQueryType].compiler.RewrittenVars(),
|
||||
},
|
||||
}).
|
||||
WithModules(modules).
|
||||
WithBuiltinDecls(decls).
|
||||
WithDebug(r.dump)
|
||||
|
||||
policy, err := p.Plan()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if r.dump != nil {
|
||||
fmt.Fprintln(r.dump, "PLAN:")
|
||||
fmt.Fprintln(r.dump, "-----")
|
||||
err = ir.Pretty(r.dump, policy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fmt.Fprintln(r.dump)
|
||||
}
|
||||
return policy, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user