Пример #1
0
func setupBenchmark(nodes int, pods int) *topdown.QueryParams {

	// policy compilation
	c := ast.NewCompiler()
	modules := map[string]*ast.Module{
		"test": ast.MustParseModule(policy),
	}

	if c.Compile(modules); c.Failed() {
		panic(c.Errors)
	}

	// storage setup
	store := storage.New(storage.InMemoryConfig())

	// parameter setup
	ctx := context.Background()
	request := ast.ObjectTerm(ast.Item(ast.StringTerm("pod"), ast.MustParseTerm(requestedPod)))
	path := ast.MustParseRef("data.opa.test.scheduler.fit")
	txn := storage.NewTransactionOrDie(ctx, store)
	params := topdown.NewQueryParams(ctx, c, store, txn, request.Value, path)

	// data setup
	setupNodes(ctx, store, txn, nodes)
	setupRCs(ctx, store, txn, 1)
	setupPods(ctx, store, txn, pods, nodes)

	return params
}
Пример #2
0
func setup(t *testing.T, filename string) *topdown.QueryParams {

	// policy compilation
	c := ast.NewCompiler()
	modules := map[string]*ast.Module{
		"test": ast.MustParseModule(policy),
	}

	if c.Compile(modules); c.Failed() {
		t.Fatal("unexpected error:", c.Errors)
	}

	// storage setup
	store := storage.New(storage.Config{
		Builtin: loadDataStore(filename),
	})

	// parameter setup
	ctx := context.Background()
	request := ast.ObjectTerm(ast.Item(ast.StringTerm("pod"), ast.MustParseTerm(requestedPod)))
	path := ast.MustParseRef("data.opa.test.scheduler.fit")
	txn := storage.NewTransactionOrDie(ctx, store)
	params := topdown.NewQueryParams(ctx, c, store, txn, request.Value, path)

	return params
}
Пример #3
0
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>

}
Пример #4
0
// loadRequest returns the request defined in the REPL. The REPL loads the
// request from the data.repl.request document.
func (r *REPL) loadRequest(ctx context.Context, compiler *ast.Compiler) (ast.Value, error) {

	params := topdown.NewQueryParams(ctx, compiler, r.store, r.txn, nil, ast.MustParseRef("data.repl.request"))

	result, err := topdown.Query(params)

	if err != nil {
		return nil, err
	}

	if result.Undefined() {
		return nil, nil
	}

	return ast.InterfaceToValue(result[0].Result)
}
Пример #5
0
func executeQuery(data string, compiler *ast.Compiler, tracer topdown.Tracer) {
	topdown.ResetQueryIDs()

	d := map[string]interface{}{}

	if len(data) > 0 {
		if err := util.UnmarshalJSON([]byte(data), &d); err != nil {
			panic(err)
		}
	}

	ctx := context.Background()
	store := storage.New(storage.InMemoryWithJSONConfig(d))
	txn := storage.NewTransactionOrDie(ctx, store)
	defer store.Close(ctx, txn)
	params := topdown.NewQueryParams(ctx, compiler, store, txn, nil, ast.MustParseRef("data.test.p"))
	params.Tracer = tracer

	_, err := topdown.Query(params)
	if err != nil {
		panic(err)
	}
}
Пример #6
0
func (s *Server) v1DataGet(w http.ResponseWriter, r *http.Request) {

	// Gather request parameters.
	ctx := r.Context()
	vars := mux.Vars(r)
	path := stringPathToDataRef(vars["path"])
	pretty := getPretty(r.URL.Query()["pretty"])
	explainMode := getExplain(r.URL.Query()["explain"])
	request, nonGround, err := parseRequest(r.URL.Query()[ParamRequestV1])

	if err != nil {
		handleError(w, 400, err)
		return
	}

	if nonGround && explainMode != explainOffV1 {
		handleError(w, 400, fmt.Errorf("explanations with non-ground request values not supported"))
		return
	}

	// Prepare for query.
	txn, err := s.store.NewTransaction(ctx)
	if err != nil {
		handleErrorAuto(w, err)
		return
	}

	defer s.store.Close(ctx, txn)

	compiler := s.Compiler()
	params := topdown.NewQueryParams(ctx, compiler, s.store, txn, request, path)

	var buf *topdown.BufferTracer
	if explainMode != explainOffV1 {
		buf = topdown.NewBufferTracer()
		params.Tracer = buf
	}

	// Execute query.
	qrs, err := topdown.Query(params)

	// Handle results.
	if err != nil {
		handleErrorAuto(w, err)
		return
	}

	if qrs.Undefined() {
		if explainMode == explainFullV1 {
			handleResponseJSON(w, 404, newTraceV1(*buf), pretty)
		} else {
			handleResponse(w, 404, nil)
		}
		return
	}

	if nonGround {
		handleResponseJSON(w, 200, newQueryResultSetV1(qrs), pretty)
		return
	}

	result := qrs[0].Result

	switch explainMode {
	case explainOffV1:
		handleResponseJSON(w, 200, result, pretty)
	case explainFullV1:
		handleResponseJSON(w, 200, newTraceV1(*buf), pretty)
	case explainTruthV1:
		answer, err := explain.Truth(compiler, *buf)
		if err != nil {
			handleErrorAuto(w, err)
			return
		}
		handleResponseJSON(w, 200, newTraceV1(answer), pretty)
	}
}