Example #1
0
func TestQueryBindingIterationError(t *testing.T) {

	ctx := context.Background()
	store := storage.New(storage.InMemoryConfig())
	mock := &queryBindingErrStore{}

	if err := store.Mount(mock, storage.MustParsePath("/foo/bar")); err != nil {
		panic(err)
	}

	server, err := New(ctx, store, ":8182", false)
	if err != nil {
		panic(err)
	}
	recorder := httptest.NewRecorder()

	f := &fixture{
		server:   server,
		recorder: recorder,
		t:        t,
	}

	get := newReqV1("GET", `/query?q=a=data.foo.bar`, "")
	f.server.Handler.ServeHTTP(f.recorder, get)

	if f.recorder.Code != 500 {
		t.Fatalf("Expected 500 error due to unknown storage error but got: %v", f.recorder)
	}
}
Example #2
0
func setupNodes(ctx context.Context, store *storage.Storage, txn storage.Transaction, n int) {
	tmpl, err := template.New("node").Parse(nodeTemplate)
	if err != nil {
		panic(err)
	}
	if err := store.Write(ctx, txn, storage.AddOp, storage.MustParsePath("/nodes"), map[string]interface{}{}); err != nil {
		panic(err)
	}
	for i := 0; i < n; i++ {
		input := nodeTemplateInput{
			Name: fmt.Sprintf("node%v", i),
		}
		v := runTemplate(tmpl, input)
		path := storage.MustParsePath(fmt.Sprintf("/nodes/%v", input.Name))
		if err := store.Write(ctx, txn, storage.AddOp, path, v); err != nil {
			panic(err)
		}
	}
}
Example #3
0
func ExampleStorage_Write() {
	// Initialize context for the example. Normally the caller would obtain the
	// context from an input parameter or instantiate their own.
	ctx := context.Background()

	// Define some dummy data to initialize the DataStore with.
	exampleInput := `
    {
        "users": [
            {
                "name": "alice",
                "color": "red",
                "likes": ["clouds", "ships"]
            },
            {
                "name": "burt",
                "likes": ["cheese", "wine"]
            }
        ]
    }
    `

	var data map[string]interface{}

	// OPA uses Go's standard JSON library but assumes that numbers have been
	// decoded as json.Number instead of float64. You MUST decode with UseNumber
	// enabled.
	decoder := json.NewDecoder(bytes.NewBufferString(exampleInput))
	decoder.UseNumber()

	if err := decoder.Decode(&data); err != nil {
		// Handle error.
	}

	// Create the new DataStore with the dummy data.
	store := storage.New(storage.InMemoryWithJSONConfig(data))

	// Define dummy data to add to the DataStore.
	examplePatch := `{
        "longitude": 82.501389,
        "latitude": -62.338889
    }`

	var patch interface{}

	// See comment above regarding decoder usage.
	decoder = json.NewDecoder(bytes.NewBufferString(examplePatch))
	decoder.UseNumber()

	if err := decoder.Decode(&patch); err != nil {
		// Handle error.
	}

	txn, err := store.NewTransaction(ctx)
	if err != nil {
		// Handle error.
	}

	defer store.Close(ctx, txn)

	// Write values into storage and read result.
	err0 := store.Write(ctx, txn, storage.AddOp, storage.MustParsePath("/users/0/location"), patch)
	v1, err1 := store.Read(ctx, txn, storage.MustParsePath("/users/0/location/latitude"))
	err2 := store.Write(ctx, txn, storage.ReplaceOp, storage.MustParsePath("/users/1/color"), "red")

	// Inspect the return values.
	fmt.Println("err0:", err0)
	fmt.Println("v1:", v1)
	fmt.Println("err1:", err1)
	fmt.Println("err2:", err2)

	// Rollback transaction because write failed.

	// Output:
	// err0: <nil>
	// v1: -62.338889
	// err1: <nil>
	// err2: storage error (code: 1): bad path: /users/1/color, document does not exist

}
Example #4
0
func TestInit(t *testing.T) {
	ctx := context.Background()

	tmp1, err := ioutil.TempFile("", "docFile")
	if err != nil {
		panic(err)
	}
	defer os.Remove(tmp1.Name())

	doc1 := `{"foo": "bar", "x": {"y": {"z": [1]}}}`
	if _, err := tmp1.Write([]byte(doc1)); err != nil {
		panic(err)
	}
	if err := tmp1.Close(); err != nil {
		panic(err)
	}

	tmp2, err := ioutil.TempFile("", "policyFile")
	if err != nil {
		panic(err)
	}
	defer os.Remove(tmp2.Name())
	mod1 := `
	package a.b.c
	import data.foo
	p = true :- foo = "bar"
	p = true :- 1 = 2
	`
	if _, err := tmp2.Write([]byte(mod1)); err != nil {
		panic(err)
	}
	if err := tmp2.Close(); err != nil {
		panic(err)
	}

	tmp3, err := ioutil.TempDir("", "policyDir")
	if err != nil {
		panic(err)
	}

	defer os.RemoveAll(tmp3)

	tmp4 := filepath.Join(tmp3, "existingPolicy")

	err = ioutil.WriteFile(tmp4, []byte(`
	package a.b.c
	q = true :- false
	`), 0644)
	if err != nil {
		panic(err)
	}

	rt := Runtime{}

	err = rt.init(ctx, &Params{
		Paths:     []string{tmp1.Name(), tmp2.Name()},
		PolicyDir: tmp3,
	})

	if err != nil {
		t.Errorf("Unexpected error: %v", err)
		return
	}

	txn := storage.NewTransactionOrDie(ctx, rt.Store)

	node, err := rt.Store.Read(ctx, txn, storage.MustParsePath("/foo"))
	if util.Compare(node, "bar") != 0 || err != nil {
		t.Errorf("Expected %v but got %v (err: %v)", "bar", node, err)
		return
	}

	modules := rt.Store.ListPolicies(txn)
	expected := ast.MustParseModule(mod1)

	if !expected.Equal(modules[tmp2.Name()]) {
		t.Fatalf("Expected %v but got: %v", expected, modules[tmp2.Name()])
	}

}
Example #5
0
func ExampleStorage_Read() {
	// Initialize context for the example. Normally the caller would obtain the
	// context from an input parameter or instantiate their own.
	ctx := context.Background()

	// Define some dummy data to initialize the built-in store with.
	exampleInput := `
    {
        "users": [
            {
                "name": "alice",
                "color": "red",
                "likes": ["clouds", "ships"]
            },
            {
                "name": "burt",
                "likes": ["cheese", "wine"]
            }
        ]
    }
    `

	var data map[string]interface{}

	// OPA uses Go's standard JSON library but assumes that numbers have been
	// decoded as json.Number instead of float64. You MUST decode with UseNumber
	// enabled.
	decoder := json.NewDecoder(bytes.NewBufferString(exampleInput))
	decoder.UseNumber()

	if err := decoder.Decode(&data); err != nil {
		// Handle error.
	}

	// Instantiate the storage layer.
	store := storage.New(storage.InMemoryWithJSONConfig(data))

	txn, err := store.NewTransaction(ctx)
	if err != nil {
		// Handle error.
	}

	defer store.Close(ctx, txn)

	// Read values out of storage.
	v1, err1 := store.Read(ctx, txn, storage.MustParsePath("/users/1/likes/1"))
	v2, err2 := store.Read(ctx, txn, storage.MustParsePath("/users/0/age"))

	// Inspect the return values.
	fmt.Println("v1:", v1)
	fmt.Println("err1:", err1)
	fmt.Println("v2:", v2)
	fmt.Println("err2:", err2)
	fmt.Println("err2 is not found:", storage.IsNotFound(err2))

	// Output:
	// v1: wine
	// err1: <nil>
	// v2: <nil>
	// err2: storage error (code: 1): bad path: /users/0/age, document does not exist
	// err2 is not found: true
}