mirror of
https://github.com/open-policy-agent/opa.git
synced 2026-08-12 19:32:48 -06:00
rego: Add Data function to simplify adding data from map (#8166)
Add rego.Data function to allow setting data directly from a map[string]any, providing a simpler alternative to using Store(inmem.NewFromObject(data)). This improves the Go SDK API by reducing boilerplate for the common case of using an in-memory store with static data. Fixes: #5961 Signed-off-by: majiayu000 <1835304752@qq.com>
This commit is contained in:
@@ -408,6 +408,14 @@ func Store(s storage.Store) func(r *Rego) {
|
||||
return v1.Store(s)
|
||||
}
|
||||
|
||||
// Data returns an argument that sets the Rego data document. Data should be
|
||||
// a map representing the data document. This is a simpler alternative to
|
||||
// using Store with inmem.NewFromObject for cases where an in-memory store
|
||||
// with static data is sufficient.
|
||||
func Data(x map[string]any) func(r *Rego) {
|
||||
return v1.Data(x)
|
||||
}
|
||||
|
||||
// StoreReadAST returns an argument that sets whether the store should eagerly convert data to AST values.
|
||||
//
|
||||
// Only applicable when no store has been set on the Rego object through the Store option.
|
||||
|
||||
@@ -1080,6 +1080,16 @@ func Store(s storage.Store) func(r *Rego) {
|
||||
}
|
||||
}
|
||||
|
||||
// Data returns an argument that sets the Rego data document. Data should be
|
||||
// a map representing the data document. This is a simpler alternative to
|
||||
// using Store with inmem.NewFromObject for cases where an in-memory store
|
||||
// with static data is sufficient.
|
||||
func Data(x map[string]any) func(r *Rego) {
|
||||
return func(r *Rego) {
|
||||
r.store = inmem.NewFromObject(x)
|
||||
}
|
||||
}
|
||||
|
||||
// StoreReadAST returns an argument that sets whether the store should eagerly convert data to AST values.
|
||||
//
|
||||
// Only applicable when no store has been set on the Rego object through the Store option.
|
||||
|
||||
@@ -3449,3 +3449,71 @@ result := test.module("policy.rego")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestRegoData(t *testing.T) {
|
||||
ctx := t.Context()
|
||||
|
||||
r := New(
|
||||
Query("data.x.y"),
|
||||
Data(map[string]any{
|
||||
"x": map[string]any{
|
||||
"y": "hello",
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
rs, err := r.Eval(ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if len(rs) != 1 || len(rs[0].Expressions) != 1 {
|
||||
t.Fatalf("Expected one result with one expression but got: %v", rs)
|
||||
}
|
||||
|
||||
if rs[0].Expressions[0].Value != "hello" {
|
||||
t.Fatalf("Expected 'hello' but got: %v", rs[0].Expressions[0].Value)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegoDataWithModule(t *testing.T) {
|
||||
ctx := t.Context()
|
||||
|
||||
mod := `
|
||||
package test
|
||||
import rego.v1
|
||||
|
||||
result := data.users[input.user_id].role
|
||||
`
|
||||
|
||||
r := New(
|
||||
Query("data.test.result"),
|
||||
Module("test.rego", mod),
|
||||
Data(map[string]any{
|
||||
"users": map[string]any{
|
||||
"alice": map[string]any{
|
||||
"role": "admin",
|
||||
},
|
||||
"bob": map[string]any{
|
||||
"role": "viewer",
|
||||
},
|
||||
},
|
||||
}),
|
||||
Input(map[string]any{
|
||||
"user_id": "alice",
|
||||
}),
|
||||
)
|
||||
|
||||
rs, err := r.Eval(ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if len(rs) != 1 || len(rs[0].Expressions) != 1 {
|
||||
t.Fatalf("Expected one result with one expression but got: %v", rs)
|
||||
}
|
||||
|
||||
if rs[0].Expressions[0].Value != "admin" {
|
||||
t.Fatalf("Expected 'admin' but got: %v", rs[0].Expressions[0].Value)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user