func ExampleQuery() { // Initialize context for the example. Normally the caller would obtain the // context from an input parameter or instantiate their own. ctx := context.Background() compiler := ast.NewCompiler() // Define a dummy module with rules that produce documents that we will query below. module, err := ast.ParseModule("my_module.rego", ` package opa.example p[x] :- q[x], not r[x] q[y] :- a = [1,2,3], y = a[_] r[z] :- b = [2,4], z = b[_] `) mods := map[string]*ast.Module{ "my_module": module, } if compiler.Compile(mods); compiler.Failed() { fmt.Println(compiler.Errors) } if err != nil { // Handle error. } // Instantiate the policy engine's storage layer. store := storage.New(storage.InMemoryConfig()) // Create a new transaction. Transactions allow the policy engine to // evaluate the query over a consistent snapshot fo the storage layer. txn, err := store.NewTransaction(ctx) if err != nil { // Handle error. } defer store.Close(ctx, txn) // Prepare query parameters. In this case, there are no additional documents // required by the policy so the request is nil. var request ast.Value params := topdown.NewQueryParams(ctx, compiler, store, txn, request, ast.MustParseRef("data.opa.example.p")) // Execute the query against "p". v1, err1 := topdown.Query(params) // Inspect the result. fmt.Println("v1:", v1[0].Result) fmt.Println("err1:", err1) // Output: // v1: [1 3] // err1: <nil> }
func regoLoad(path string) (interface{}, error) { bs, err := ioutil.ReadFile(path) if err != nil { return nil, err } module, err := ast.ParseModule(path, string(bs)) if err != nil { return nil, err } result := &loadedModule{ Parsed: module, Raw: bs, } return result, nil }
func ExampleCompiler_Compile() { // Define an input module that will be compiled. exampleModule := ` package opa.example import data.foo import request.bar p[x] :- foo[x], not bar[x], x >= min_x min_x = 100 ` // Parse the input module to obtain the AST representation. mod, err := ast.ParseModule("my_module", exampleModule) if err != nil { fmt.Println("Parse error:", err) } // Create a new compiler instance and compile the module. c := ast.NewCompiler() mods := map[string]*ast.Module{ "my_module": mod, } if c.Compile(mods); c.Failed() { fmt.Println("Compile error:", c.Errors) } fmt.Println("Expr 1:", c.Modules["my_module"].Rules[0].Body[0]) fmt.Println("Expr 2:", c.Modules["my_module"].Rules[0].Body[1]) fmt.Println("Expr 3:", c.Modules["my_module"].Rules[0].Body[2]) // Output: // // Expr 1: data.foo[x] // Expr 2: not request.bar[x] // Expr 3: gte(x, data.opa.example.min_x) }
// loadPolicies is the default callback function that will be used when // opening the policy store. func loadPolicies(bufs map[string][]byte) (map[string]*ast.Module, error) { parsed := map[string]*ast.Module{} for id, bs := range bufs { mod, err := ast.ParseModule(id, string(bs)) if err != nil { return nil, err } parsed[id] = mod } c := ast.NewCompiler() if c.Compile(parsed); c.Failed() { return nil, c.Errors } return parsed, nil }
func ExampleQueryCompiler_Compile() { // Define an input module that will be compiled. exampleModule := ` package opa.example import data.foo import request.bar p[x] :- foo[x], not bar[x], x >= min_x min_x = 100 ` // Parse the input module to obtain the AST representation. mod, err := ast.ParseModule("my_module", exampleModule) if err != nil { fmt.Println("Parse error:", err) } // Create a new compiler instance and compile the module. c := ast.NewCompiler() mods := map[string]*ast.Module{ "my_module": mod, } if c.Compile(mods); c.Failed() { fmt.Println("Compile error:", c.Errors) } // Obtain the QueryCompiler from the compiler instance. Note, we will // compile this query within the context of the opa.example package and // declare that a query input named "queryinput" must be supplied. qc := c.QueryCompiler(). WithContext( ast.NewQueryContext( // Note, the ast.MustParse<X> functions are meant for test // purposes only. They will panic if an error occurs. Prefer the // ast.Parse<X> functions that return meaningful error messages // instead. ast.MustParsePackage("package opa.example"), ast.MustParseImports("import request.queryinput"), )) // Parse the input query to obtain the AST representation. query, err := ast.ParseBody("p[x], x < queryinput") if err != nil { fmt.Println("Parse error:", err) } compiled, err := qc.Compile(query) if err != nil { fmt.Println("Compile error:", err) } fmt.Println("Compiled:", compiled) // Output: // // Compiled: data.opa.example.p[x], lt(x, request.queryinput) }
func (s *Server) v1PoliciesPut(w http.ResponseWriter, r *http.Request) { ctx := r.Context() vars := mux.Vars(r) id := vars["id"] buf, err := ioutil.ReadAll(r.Body) if err != nil { handleError(w, 500, err) return } parsedMod, err := ast.ParseModule(id, string(buf)) if err != nil { switch err := err.(type) { case ast.Errors: handleErrorAST(w, 400, compileModErrMsg, err) default: handleError(w, 400, err) } return } if parsedMod == nil { handleErrorf(w, 400, "refusing to add empty module") return } txn, err := s.store.NewTransaction(ctx) if err != nil { handleErrorAuto(w, err) return } defer s.store.Close(ctx, txn) mods := s.store.ListPolicies(txn) mods[id] = parsedMod c := ast.NewCompiler() if c.Compile(mods); c.Failed() { handleErrorAST(w, 400, compileModErrMsg, c.Errors) return } if err := s.store.InsertPolicy(txn, id, parsedMod, buf, s.persist); err != nil { handleErrorAuto(w, err) return } s.setCompiler(c) policy := &policyV1{ ID: id, Module: c.Modules[id], } handleResponseJSON(w, 200, policy, true) }