package storage
import "github.com/open-policy-agent/opa/storage"
Package storage exposes the policy engine's storage layer.
Index ¶
- Constants
- func DeletePolicy(ctx context.Context, store *Storage, id string) error
- func GetPolicy(ctx context.Context, store *Storage, id string) (*ast.Module, []byte, error)
- func InsertPolicy(ctx context.Context, store *Storage, id string, mod *ast.Module, raw []byte, persist bool) error
- func IsInvalidPatch(err error) bool
- func IsNotFound(err error) bool
- type Config
- func InMemoryConfig() Config
- func InMemoryWithJSONConfig(data map[string]interface{}) Config
- func (c Config) WithPolicyDir(dir string) Config
- type DataStore
- func NewDataStore() *DataStore
- func NewDataStoreFromJSONObject(data map[string]interface{}) *DataStore
- func NewDataStoreFromReader(r io.Reader) *DataStore
- func (ds *DataStore) Begin(ctx context.Context, txn Transaction, params TransactionParams) error
- func (ds *DataStore) Close(ctx context.Context, txn Transaction)
- func (ds *DataStore) ID() string
- func (ds *DataStore) Read(ctx context.Context, txn Transaction, path Path) (interface{}, error)
- func (ds *DataStore) Register(id string, config TriggerConfig) error
- func (ds *DataStore) String() string
- func (ds *DataStore) Unregister(id string)
- func (ds *DataStore) Write(ctx context.Context, txn Transaction, op PatchOp, path Path, value interface{}) error
- type ErrCode
- type Error
- type PatchOp
- type Path
- func MustParsePath(s string) Path
- func NewPathForRef(ref ast.Ref) (path Path, err error)
- func ParsePath(str string) (path Path, ok bool)
- func (p Path) Compare(other Path) (cmp int)
- func (p Path) Equal(other Path) bool
- func (p Path) HasPrefix(other Path) bool
- func (p Path) Ref(head *ast.Term) (ref ast.Ref)
- func (p Path) String() string
- type Storage
- func New(config Config) *Storage
- func (s *Storage) BuildIndex(ctx context.Context, txn Transaction, ref ast.Ref) error
- func (s *Storage) Close(ctx context.Context, txn Transaction)
- func (s *Storage) DeletePolicy(txn Transaction, id string) error
- func (s *Storage) GetPolicy(txn Transaction, id string) (*ast.Module, []byte, error)
- func (s *Storage) Index(txn Transaction, ref ast.Ref, value interface{}, iter func(*ast.ValueMap) error) error
- func (s *Storage) IndexExists(ref ast.Ref) bool
- func (s *Storage) InsertPolicy(txn Transaction, id string, module *ast.Module, raw []byte, persist bool) error
- func (s *Storage) ListPolicies(txn Transaction) map[string]*ast.Module
- func (s *Storage) Mount(backend Store, path Path) error
- func (s *Storage) NewTransaction(ctx context.Context) (Transaction, error)
- func (s *Storage) NewTransactionWithParams(ctx context.Context, params TransactionParams) (Transaction, error)
- func (s *Storage) Open(ctx context.Context) error
- func (s *Storage) Read(ctx context.Context, txn Transaction, path Path) (interface{}, error)
- func (s *Storage) Unmount(path Path) error
- func (s *Storage) Write(ctx context.Context, txn Transaction, op PatchOp, path Path, value interface{}) error
- type Store
- type Transaction
- type TransactionParams
- func NewTransactionParams() TransactionParams
- func (params TransactionParams) WithPaths(paths []Path) TransactionParams
- type Trigger
- type TriggerCallback
- type TriggerConfig
- type TriggersNotSupported
- func (TriggersNotSupported) Register(string, TriggerConfig) error
- func (TriggersNotSupported) Unregister(string)
- type WritesNotSupported
Examples ¶
Constants ¶
const ( // InternalErr indicates an unknown, internal error has occurred. InternalErr ErrCode = iota // NotFoundErr indicates the path used in the storage operation does not // locate a document. NotFoundErr = iota // InvalidPatchErr indicates an invalid patch/write was issued. The patch // was rejected. InvalidPatchErr = iota // MountConflictErr indicates a mount attempt was made on a path that is // already used for a mount. MountConflictErr = iota // IndexNotFoundErr indicates the caller attempted to use indexing on a // reference that has not been indexed. IndexNotFoundErr = iota // IndexingNotSupportedErr indicates the caller attempted to index a // reference provided by a store that does not support indexing. IndexingNotSupportedErr = iota // TriggersNotSupportedErr indicates the caller attempted to register a // trigger against a store that does not support them. TriggersNotSupportedErr = iota // WritesNotSupportedErr indicate the caller attempted to perform a write // against a store that does not support them. WritesNotSupportedErr = iota )
Patch supports add, remove, and replace operations.
Functions ¶
func DeletePolicy ¶
DeletePolicy removes a policy module from storage inside a new transaction.
func GetPolicy ¶
GetPolicy returns a policy module from storage inside a new transaction.
func InsertPolicy ¶
func InsertPolicy(ctx context.Context, store *Storage, id string, mod *ast.Module, raw []byte, persist bool) error
InsertPolicy upserts a policy module into storage inside a new transaction.
func IsInvalidPatch ¶
IsInvalidPatch returns true if this error is a InvalidPatchErr.
func IsNotFound ¶
IsNotFound returns true if this error is a NotFoundErr.
Types ¶
type Config ¶
Config represents the configuration for the policy engine's storage layer.
func InMemoryConfig ¶
func InMemoryConfig() Config
InMemoryConfig returns a new Config for an in-memory storage layer.
func InMemoryWithJSONConfig ¶
InMemoryWithJSONConfig returns a new Config for an in-memory storage layer using existing JSON data. This is primarily for test purposes.
func (Config) WithPolicyDir ¶
WithPolicyDir returns a new Config with the policy directory configured.
type DataStore ¶
type DataStore struct {
// contains filtered or unexported fields
}
DataStore is a simple in-memory data store that implements the storage.Store interface.
func NewDataStore ¶
func NewDataStore() *DataStore
NewDataStore returns an empty DataStore.
func NewDataStoreFromJSONObject ¶
NewDataStoreFromJSONObject returns a new DataStore containing the supplied documents. This is mostly for test purposes.
func NewDataStoreFromReader ¶
NewDataStoreFromReader returns a new DataStore from a reader that produces a JSON serialized object. This function is for test purposes.
func (*DataStore) Begin ¶
func (ds *DataStore) Begin(ctx context.Context, txn Transaction, params TransactionParams) error
Begin is called when a new transaction is started.
func (*DataStore) Close ¶
func (ds *DataStore) Close(ctx context.Context, txn Transaction)
Close is called when a transaction is finished.
func (*DataStore) ID ¶
ID returns a unique identifier for the in-memory store.
func (*DataStore) Read ¶
Read fetches a value from the in-memory store.
func (*DataStore) Register ¶
func (ds *DataStore) Register(id string, config TriggerConfig) error
Register adds a trigger.
func (*DataStore) String ¶
func (*DataStore) Unregister ¶
Unregister removes a trigger.
func (*DataStore) Write ¶
func (ds *DataStore) Write(ctx context.Context, txn Transaction, op PatchOp, path Path, value interface{}) error
Write modifies a document referred to by path.
type ErrCode ¶
type ErrCode int
ErrCode represents the collection of errors that may be returned by the storage layer.
type Error ¶
Error is the error type returned by the storage layer.
func (*Error) Error ¶
type PatchOp ¶
type PatchOp int
PatchOp is the enumeration of supposed modifications.
type Path ¶
type Path []string
Path refers to a document in storage.
func MustParsePath ¶
MustParsePath returns a new Path for s. If s cannot be parsed, this function will panic. This is mostly for test purposes.
func NewPathForRef ¶
NewPathForRef returns a new path for the given ref.
func ParsePath ¶
ParsePath returns a new path for the given str.
func (Path) Compare ¶
Compare performs lexigraphical comparison on p and other and returns -1 if p is less than other, 0 if p is equal to other, or 1 if p is greater than other.
func (Path) Equal ¶
Equal returns true if p is the same as other.
func (Path) HasPrefix ¶
HasPrefix returns true if p starts with other.
func (Path) Ref ¶
Ref returns a ref that represents p rooted at head.
func (Path) String ¶
type Storage ¶
type Storage struct {
// contains filtered or unexported fields
}
Storage represents the policy engine's storage layer.
func New ¶
New returns a new instance of the policy engine's storage layer.
func (*Storage) BuildIndex ¶
BuildIndex causes the storage layer to create an index for the given reference over the snapshot identified by the transaction.
func (*Storage) Close ¶
func (s *Storage) Close(ctx context.Context, txn Transaction)
Close completes a transaction.
func (*Storage) DeletePolicy ¶
func (s *Storage) DeletePolicy(txn Transaction, id string) error
DeletePolicy removes a policy from the storage layer.
func (*Storage) GetPolicy ¶
GetPolicy returns the policy module with the given id. The return value includes the raw []byte representation of the policy if it was provided when inserting the policy module.
func (*Storage) Index ¶
func (s *Storage) Index(txn Transaction, ref ast.Ref, value interface{}, iter func(*ast.ValueMap) error) error
Index invokes the iterator with bindings for each variable in the reference that if plugged into the reference, would locate a document with a matching value.
func (*Storage) IndexExists ¶
IndexExists returns true if an index has been built for reference.
func (*Storage) InsertPolicy ¶
func (s *Storage) InsertPolicy(txn Transaction, id string, module *ast.Module, raw []byte, persist bool) error
InsertPolicy upserts a policy module into the storage layer. If the policy module already exists, it is replaced. If the persist flag is true, the storage layer will attempt to write the raw policy module content to disk.
func (*Storage) ListPolicies ¶
func (s *Storage) ListPolicies(txn Transaction) map[string]*ast.Module
ListPolicies returns a map of policy modules that have been loaded into the storage layer.
func (*Storage) Mount ¶
Mount adds a store into the storage layer at the given path. If the path conflicts with an existing mount, an error is returned.
func (*Storage) NewTransaction ¶
func (s *Storage) NewTransaction(ctx context.Context) (Transaction, error)
NewTransaction returns a new Transaction with default parameters.
func (*Storage) NewTransactionWithParams ¶
func (s *Storage) NewTransactionWithParams(ctx context.Context, params TransactionParams) (Transaction, error)
NewTransactionWithParams returns a new Transaction.
func (*Storage) Open ¶
Open initializes the storage layer. Open should normally be called
immediately after instantiating a new instance of the storage layer. If the
storage layer is configured to use in-memory storage and is not persisting
policy modules to disk, the call to Open() may be omitted.
Code:play
Output:Example¶
package main
import (
"context"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"github.com/open-policy-agent/opa/storage"
)
func main() {
// Initialize context for the example. Normally the caller would obtain the
// context from an input parameter or instantiate their own.
ctx := context.Background()
// Define two example modules and write them to disk in a temporary directory.
ex1 := `
package opa.example
p { q.r != 0 }
`
ex2 := `
package opa.example
q = {"r": 100}
`
path, err := ioutil.TempDir("", "")
if err != nil {
// Handle error.
}
defer os.RemoveAll(path)
if err = ioutil.WriteFile(filepath.Join(path, "ex1.rego"), []byte(ex1), 0644); err != nil {
// Handle error.
}
if err = ioutil.WriteFile(filepath.Join(path, "ex2.rego"), []byte(ex2), 0644); err != nil {
// Handle error.
}
// Instantiate storage layer and configure with a directory to persist policy modules.
store := storage.New(storage.InMemoryConfig().WithPolicyDir(path))
if err = store.Open(ctx); err != nil {
// Handle error.
}
// Inspect one of the loaded policies.
mod, _, err := storage.GetPolicy(ctx, store, "ex1.rego")
if err != nil {
// Handle error.
}
fmt.Println("Expr:", mod.Rules[0].Body[0])
}
Expr: q.r != 0
func (*Storage) Read ¶
Read fetches the value in storage referred to by path. The path may refer to
multiple stores in which case the storage layer will fetch the values from
each store and then stitch together the result.
Code:play
Output:Example¶
package main
import (
"bytes"
"context"
"encoding/json"
"fmt"
"github.com/open-policy-agent/opa/storage"
)
func main() {
// 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))
}
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
func (*Storage) Unmount ¶
Unmount removes a store from the storage layer. If the path does not locate an existing mount, an error is returned.
func (*Storage) Write ¶
func (s *Storage) Write(ctx context.Context, txn Transaction, op PatchOp, path Path, value interface{}) error
Write updates a value in storage.
Code:play
Output:Example¶
package main
import (
"bytes"
"context"
"encoding/json"
"fmt"
"github.com/open-policy-agent/opa/storage"
)
func main() {
// 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.
}
err0: <nil>
v1: -62.338889
err1: <nil>
err2: storage error (code: 1): bad path: /users/1/color, document does not exist
type Store ¶
type Store interface { Trigger // Returns a unique identifier for this store. The function should namespace // the identifier to avoid potential conflicts, e.g., // com.example/foo-service. ID() string // Begin is called to indicate that a new transaction has started. The store // can use the call to initialize any resources that may be required for the // transaction. Begin(ctx context.Context, txn Transaction, params TransactionParams) error // Read is called to fetch a document referred to by path. Read(ctx context.Context, txn Transaction, path Path) (interface{}, error) // Write is called to modify a document referred to by path. Write(ctx context.Context, txn Transaction, op PatchOp, path Path, value interface{}) error // Close indicates a transaction has finished. The store can use the call to // release any resources temporarily allocated for the transaction. Close(ctx context.Context, txn Transaction) }
Store defines the interface for the storage layer's backend. Users can implement their own stores and mount them into the storage layer to provide the policy engine access to external data sources.
type Transaction ¶
type Transaction interface { // ID returns a unique identifier for this transaction. ID() uint64 }
Transaction defines the interface that identifies a consistent snapshot over the policy engine's storage layer.
func NewTransactionOrDie ¶
func NewTransactionOrDie(ctx context.Context, store *Storage) Transaction
NewTransactionOrDie is a helper function to create a new transaction. If the storage layer cannot create a new transaction, this function will panic. This function should only be used for tests.
type TransactionParams ¶
type TransactionParams struct { // Paths represents a set of document paths that may be read during the // transaction. The paths may be provided by the caller to hint to the // storage layer that certain documents could be pre-loaded. Paths []Path }
TransactionParams describes a new transaction.
func NewTransactionParams ¶
func NewTransactionParams() TransactionParams
NewTransactionParams returns a new TransactionParams object.
func (TransactionParams) WithPaths ¶
func (params TransactionParams) WithPaths(paths []Path) TransactionParams
WithPaths returns a new TransactionParams object with the paths set.
type Trigger ¶
type Trigger interface { Register(id string, config TriggerConfig) error // Unregister instructs the trigger to remove the registration. Unregister(id string) }
Trigger defines the interface that stores implement to register for change notifications when data in the store changes.
type TriggerCallback ¶
type TriggerCallback func(ctx context.Context, txn Transaction, op PatchOp, path Path, value interface{}) error
TriggerCallback defines the interface that callers can implement to handle changes in the stores.
type TriggerConfig ¶
type TriggerConfig struct { // Before is called before the change is applied to the store. Before TriggerCallback // After is called after the change is applied to the store. After TriggerCallback }
TriggerConfig contains the trigger registration configuration.
type TriggersNotSupported ¶
type TriggersNotSupported struct{}
TriggersNotSupported provides default implementations of the Trigger interface which may be used if the backend does not support triggers.
func (TriggersNotSupported) Register ¶
func (TriggersNotSupported) Register(string, TriggerConfig) error
Register always returns an error indicating triggers are not supported.
func (TriggersNotSupported) Unregister ¶
func (TriggersNotSupported) Unregister(string)
Unregister is a no-op.
type WritesNotSupported ¶
type WritesNotSupported struct{}
WritesNotSupported provides a default implementation of the write interface which may be used if the backend does not support writes.
func (WritesNotSupported) Write ¶
func (WritesNotSupported) Write(ctx context.Context, txn Transaction, op PatchOp, path Path, value interface{}) error
Source Files ¶
datastore.go doc.go errors.go index.go interface.go path.go policystore.go storage.go transaction.go trigger.go
- Version
- v0.4.4
- Published
- Feb 15, 2017
- Platform
- darwin/amd64
- Imports
- 14 packages
- Last checked
- 51 seconds ago –
Tools for package owners.