Documentation ¶
Index ¶
- Variables
- func ChecksumFromContext(ctx context.Context) (uint32, bool)
- func NamespaceConfigTimestampFromContext(ctx context.Context, namespace string) (time.Time, bool)
- func NewContextWithChecksum(ctx context.Context, hashringChecksum uint32) context.Context
- func NewContextWithNamespaceConfigTimestamp(ctx context.Context, namespace string, timestamp time.Time) context.Context
- type AccessController
- func (a *AccessController) Check(ctx context.Context, req *aclpb.CheckRequest) (*aclpb.CheckResponse, error)
- func (a *AccessController) Close() error
- func (a *AccessController) Expand(ctx context.Context, req *aclpb.ExpandRequest) (*aclpb.ExpandResponse, error)
- func (a *AccessController) GetBroadcasts(overhead, limit int) [][]byte
- func (a *AccessController) HealthCheck(ctx context.Context, req *grpc_health_v1.HealthCheckRequest) (*grpc_health_v1.HealthCheckResponse, error)
- func (a *AccessController) ListRelationTuples(ctx context.Context, req *aclpb.ListRelationTuplesRequest) (*aclpb.ListRelationTuplesResponse, error)
- func (a *AccessController) LocalState(join bool) []byte
- func (a *AccessController) MergeRemoteState(buf []byte, join bool)
- func (a *AccessController) NodeMeta(limit int) []byte
- func (a *AccessController) NotifyJoin(member *memberlist.Node)
- func (a *AccessController) NotifyLeave(member *memberlist.Node)
- func (a *AccessController) NotifyMsg(msg []byte)
- func (a *AccessController) NotifyUpdate(member *memberlist.Node)
- func (a *AccessController) ReadConfig(ctx context.Context, req *aclpb.ReadConfigRequest) (*aclpb.ReadConfigResponse, error)
- func (a *AccessController) WriteConfig(ctx context.Context, req *aclpb.WriteConfigRequest) (*aclpb.WriteConfigResponse, error)
- func (a *AccessController) WriteRelationTuplesTxn(ctx context.Context, req *aclpb.WriteRelationTuplesTxnRequest) (*aclpb.WriteRelationTuplesTxnResponse, error)
- type AccessControllerOption
- type ChangelogIterator
- type ClientRouter
- type ConsistentHashring
- type Hashring
- type HashringMember
- type HealthChecker
- type InternalRelationTuple
- type NamespaceChangelogEntry
- type NamespaceConfigError
- type NamespaceConfigErrorType
- type NamespaceConfigSnapshot
- type NamespaceManager
- type NamespaceOperation
- type NodeConfigs
- type NodeMetadata
- type NodeType
- type Object
- type PeerNamespaceConfigStore
- type RelationTupleQuery
- type RelationTupleStore
- type Subject
- type SubjectID
- type SubjectSet
- type SubjectTree
Constants ¶
This section is empty.
Variables ¶
var ErrClientNotFound = fmt.Errorf("the client with the provided identifier was not found")
ErrClientNotFound is an error that occurrs if a ClientRouter.GetClient call is invoked with a nodeID that does not exist.
var ErrInvalidSubjectSetString = fmt.Errorf("the provided SubjectSet string is malformed")
ErrInvalidSubjectSetString is an error that is returned if a malformed SubjectSet string is encountered.
var ErrNamespaceDoesntExist error = errors.New("the provided namespace doesn't exist, please add it first")
ErrNamespaceDoesntExist is an error that occurrs when attempting to fetch a namespace config for a namespace that doesn't exist.
var ErrNoLocalNamespacesDefined error = errors.New("no local namespace configs have been defined at this time")
ErrNoLocalNamespacesDefined is an error that occurrs when attempting to fetch a namespace config and no local namespaces have been defined.
Functions ¶
func ChecksumFromContext ¶
ChecksumFromContext extracts the hashring checksum from the provided ctx or returns false if none was found in the ctx.
func NamespaceConfigTimestampFromContext ¶
NamespaceConfigTimestampFromContext extracts the snapshot timestamp for a namespace configuration from the provided context. If none is present, a boolean false is returned.
func NewContextWithChecksum ¶
NewContextWithChecksum returns a new Context that carries the hashring checksum.
Types ¶
type AccessController ¶
type AccessController struct { aclpb.UnimplementedCheckServiceServer aclpb.UnimplementedWriteServiceServer aclpb.UnimplementedReadServiceServer aclpb.UnimplementedExpandServiceServer aclpb.UnimplementedNamespaceConfigServiceServer Memberlist *memberlist.Memberlist RPCRouter ClientRouter Hashring Hashring RelationTupleStore PeerNamespaceConfigStore NamespaceManager NodeConfigs // contains filtered or unexported fields }
func NewAccessController ¶
func NewAccessController(opts ...AccessControllerOption) (*AccessController, error)
NewAccessController constructs a new AccessController with the options provided.
func (*AccessController) Check ¶
func (a *AccessController) Check(ctx context.Context, req *aclpb.CheckRequest) (*aclpb.CheckResponse, error)
Check checks if a Subject has a relation to an object within a namespace.
func (*AccessController) Close ¶
func (a *AccessController) Close() error
Close terminates this access-controller's cluster membership and gracefully closes any remaining resources.
func (*AccessController) Expand ¶
func (a *AccessController) Expand(ctx context.Context, req *aclpb.ExpandRequest) (*aclpb.ExpandResponse, error)
Expand expands the provided SubjectSet by traversing all of the subject's (including indirect relations and those contributed through rewrites) that have the given relation to the (namespace, object) pair.
func (*AccessController) GetBroadcasts ¶
func (a *AccessController) GetBroadcasts(overhead, limit int) [][]byte
GetBroadcasts is called when user-data messages can be broadcast to peers. It should return a list of buffers to send. Each buffer should assume an overhead as provided with a limit on the total byte size allowed. The total byte size of the resulting data to send must not exceed the limit. Care should be taken that this method does not block, since doing so would block the entire UDP packet receive loop.
For more information see https://pkg.go.dev/github.com/hashicorp/memberlist#Delegate
func (*AccessController) HealthCheck ¶ added in v0.1.2
func (a *AccessController) HealthCheck(ctx context.Context, req *grpc_health_v1.HealthCheckRequest) (*grpc_health_v1.HealthCheckResponse, error)
HealthCheck returns a grpc.health.v1.HealthCheckResponse to indicate the healthiness of the access-controller.
func (*AccessController) ListRelationTuples ¶
func (a *AccessController) ListRelationTuples(ctx context.Context, req *aclpb.ListRelationTuplesRequest) (*aclpb.ListRelationTuplesResponse, error)
ListRelationTuples fetches relation tuples matching the request Query and filters the response fields by the provided ExpandMask. No indirect relations are followed, only the explicit relations are returned.
func (*AccessController) LocalState ¶
func (a *AccessController) LocalState(join bool) []byte
LocalState is used for a TCP Push/Pull between nodes in the cluster. The buffer returned here is broadcasted to the other peers in the cluster in addition to the membership information. Any data can be sent here.
For more information see https://pkg.go.dev/github.com/hashicorp/memberlist#Delegate
func (*AccessController) MergeRemoteState ¶
func (a *AccessController) MergeRemoteState(buf []byte, join bool)
MergeRemoteState is invoked after a TCP Push/Pull between nodes in the cluster. This is the state received from the remote node and is the result of the remote nodes's LocalState call.
For more information see https://pkg.go.dev/github.com/hashicorp/memberlist#Delegate
func (*AccessController) NodeMeta ¶
func (a *AccessController) NodeMeta(limit int) []byte
NodeMeta is used to retrieve meta-data about the current node when broadcasting an alive message to other peers. It's length is limited to the given byte size.
For more information see https://pkg.go.dev/github.com/hashicorp/memberlist#Delegate
func (*AccessController) NotifyJoin ¶
func (a *AccessController) NotifyJoin(member *memberlist.Node)
NotifyJoin is invoked when a new node has joined the cluster. The `member` argument must not be modified.
func (*AccessController) NotifyLeave ¶
func (a *AccessController) NotifyLeave(member *memberlist.Node)
NotifyLeave is invoked when a node leaves the cluster. The `member` argument must not be modified.
func (*AccessController) NotifyMsg ¶
func (a *AccessController) NotifyMsg(msg []byte)
NotifyMsg is called when a user-data message is received from a peer. Care should be taken that this method does not block, since doing so would block the entire UDP packet receive loop in the gossip. Additionally, the byte slice may be modified after the call returns, so it should be copied if needed.
For more information see https://pkg.go.dev/github.com/hashicorp/memberlist#Delegate
func (*AccessController) NotifyUpdate ¶
func (a *AccessController) NotifyUpdate(member *memberlist.Node)
NotifyUpdate is invoked when a node in the cluster is updated, usually involving the meta-data of the node. The `member` argument must not be modified.
func (*AccessController) ReadConfig ¶
func (a *AccessController) ReadConfig(ctx context.Context, req *aclpb.ReadConfigRequest) (*aclpb.ReadConfigResponse, error)
ReadConfig fetches the namespace configuration for the provided namespace. If the namespace does not exist, an error is returned.
func (*AccessController) WriteConfig ¶
func (a *AccessController) WriteConfig(ctx context.Context, req *aclpb.WriteConfigRequest) (*aclpb.WriteConfigResponse, error)
WriteConfig upserts the provided namespace configuration. Removing an existing relation that has one or more relation tuples referencing it will lead to an error.
func (*AccessController) WriteRelationTuplesTxn ¶
func (a *AccessController) WriteRelationTuplesTxn(ctx context.Context, req *aclpb.WriteRelationTuplesTxnRequest) (*aclpb.WriteRelationTuplesTxnResponse, error)
WriteRelationTuplesTxn inserts, deletes, or both, within an atomic transaction, one or more relation tuples.
type AccessControllerOption ¶
type AccessControllerOption func(*AccessController)
func WithNamespaceManager ¶
func WithNamespaceManager(m NamespaceManager) AccessControllerOption
WithNamespaceManager sets the AccessController's NamespaceManager.
func WithNodeConfigs ¶
func WithNodeConfigs(cfg NodeConfigs) AccessControllerOption
WithNodeConfigs sets the AccessController's NodeConfigs.
func WithStore ¶
func WithStore(store RelationTupleStore) AccessControllerOption
WithStore sets the AccessController's RelationTupleStore.
type ChangelogIterator ¶
type ChangelogIterator interface { // Next prepares the next changelog entry for reading. It returns true // if there is another entry and false if no more entries are available. Next() bool // Value returns the current most changelog entry that the iterator is // iterating over. Value() (*NamespaceChangelogEntry, error) // Close closes the iterator. Close(ctx context.Context) error }
ChangelogIterator is used to iterate over namespace changelog entries as they are yielded.
type ClientRouter ¶
type ClientRouter interface { AddClient(nodeID string, client interface{}) GetClient(nodeID string) (interface{}, error) RemoveClient(nodeID string) }
ClientRouter defines an interface to manage RPC clients for nodes/peers within a cluster.
func NewMapClientRouter ¶
func NewMapClientRouter() ClientRouter
NewMapClientRouter creates an in-memory, map based, ClientRouter. It is safe for concurrent use.
type ConsistentHashring ¶
type ConsistentHashring struct {
// contains filtered or unexported fields
}
ConsistentHashring implements a Hashring using consistent hashing with bounded loads.
func (*ConsistentHashring) Add ¶
func (ch *ConsistentHashring) Add(member HashringMember)
Add adds the provided hashring member to the hashring memberlist.
func (*ConsistentHashring) Checksum ¶
func (ch *ConsistentHashring) Checksum() uint32
Checksum computes a consistent CRC32 checksum of the hashring members using the IEEE polynomial.
func (*ConsistentHashring) LocateKey ¶
func (ch *ConsistentHashring) LocateKey(key []byte) HashringMember
LocateKey locates the nearest hashring member to the given key.
func (*ConsistentHashring) Remove ¶
func (ch *ConsistentHashring) Remove(member HashringMember)
Remove removes the provided hashring member from the hashring memberlist.
type Hashring ¶
type Hashring interface { // Add adds a new member to the hashring. Add(member HashringMember) // Remove removes a member from the hashring. Remove(member HashringMember) // LocateKey finds the nearest hashring member for a given key. LocateKey(key []byte) HashringMember // Checksum computes the CRC32 checksum of the Hashring. // // This can be used to compare the relative state of two // hash rings on remote servers. If the checksum is the // same, then the two members can trust their memberlist // is identical. If not, then at some point in the future // the hashring memberlist should converge and then the // checksums will be identical. Checksum() uint32 }
Hashring defines an interface to manage a consistent hashring.
func NewConsistentHashring ¶
func NewConsistentHashring(cfg *consistent.Config) Hashring
NewConsistentHashring returns a Hashring using consistent hashing with bounded loads. The distribution of the load in the hashring is specified via the config provided. If the cfg is nil, defaults are used.
type HashringMember ¶
type HashringMember interface {
String() string
}
HashringMember represents an interface that types must implement to be a member of a Hashring.
type HealthChecker ¶ added in v0.1.2
type HealthChecker struct { grpc_health_v1.UnimplementedHealthServer // contains filtered or unexported fields }
HealthChecker implements the gRPC Health Checking Protocol.
The health check behavior is injected into the HealthChecker by passing a healthCheckHandler.
For more information about the gRPC Health Checking Protocol see: https://github.com/grpc/grpc/blob/master/doc/health-checking.md
func NewHealthChecker ¶ added in v0.1.2
func NewHealthChecker(handler healthCheckHandler) *HealthChecker
NewHealthChecker returns a new HealthChecker instance
func (*HealthChecker) Check ¶ added in v0.1.2
func (s *HealthChecker) Check(ctx context.Context, req *grpc_health_v1.HealthCheckRequest) (*grpc_health_v1.HealthCheckResponse, error)
Check returns the server's current health status.
func (*HealthChecker) Watch ¶ added in v0.1.2
func (s *HealthChecker) Watch(req *grpc_health_v1.HealthCheckRequest, srv grpc_health_v1.Health_WatchServer) error
Watch is left unimplemented. Please use the HealthChecker.Check RPC instead. If this RPC is needed in the future, an implementation will be provided at that time.
type InternalRelationTuple ¶
type InternalRelationTuple struct { Namespace string `json:"namespace"` Object string `json:"object"` Relation string `json:"relation"` Subject Subject `json:"subject"` }
func (InternalRelationTuple) String ¶
func (r InternalRelationTuple) String() string
String returns r as a relation tuple in string format.
func (*InternalRelationTuple) ToProto ¶
func (r *InternalRelationTuple) ToProto() *pb.RelationTuple
ToProto serializes r in it's equivalent protobuf format.
type NamespaceChangelogEntry ¶
type NamespaceChangelogEntry struct { Namespace string Operation NamespaceOperation Config *aclpb.NamespaceConfig Timestamp time.Time }
NamespaceChangelogEntry represents an entry in the namespace configurations changelog.
type NamespaceConfigError ¶
type NamespaceConfigError struct { Message string Type NamespaceConfigErrorType }
NamespaceConfigError represents an error type that is surfaced when Namespace Config errors are encountered.
func (NamespaceConfigError) Error ¶
func (e NamespaceConfigError) Error() string
Error returns the NamespaceConfigError as an error string.
func (NamespaceConfigError) ToStatus ¶
func (e NamespaceConfigError) ToStatus() *status.Status
ToStatus returns the namespace config error as a grpc status.
type NamespaceConfigErrorType ¶
type NamespaceConfigErrorType int
NamespaceConfigErrorType defines an enumeration over various types of Namespace Config errors that can occur.
const ( // NamespaceAlreadyExists is an error that occurrs when attempting to add a namespace config // for a namespace that has been previously added. NamespaceAlreadyExists NamespaceConfigErrorType = iota // NamespaceDoesntExist is an error that occurrs when attempting to fetch a namespace config // for a namespace that doesn't exist. NamespaceDoesntExist // NamespaceRelationUndefined is an error that occurrs when referencing an undefined relation // in a namespace config. NamespaceRelationUndefined // NamespaceUpdateFailedPrecondition is an error that occurrs when an update to a namespace config // fails precondition checks. NamespaceUpdateFailedPrecondition )
type NamespaceConfigSnapshot ¶
type NamespaceConfigSnapshot struct { Config *aclpb.NamespaceConfig `json:"config"` Timestamp time.Time `json:"timestamp"` }
NamespaceConfigSnapshot represents a namespace configuration at a specific point in time.
type NamespaceManager ¶
type NamespaceManager interface { // UpsertConfig upserts the provided namespace configuration along with a timestamp // capturing the time at which the txn was committed. UpsertConfig(ctx context.Context, cfg *aclpb.NamespaceConfig) error // GetConfig fetches the latest namespace config. GetConfig(ctx context.Context, namespace string) (*aclpb.NamespaceConfig, error) // GetRewrite fetches the rewrite rule for the given (namespace, relation) tuple using // the latest namespace config available. GetRewrite(ctx context.Context, namespace, relation string) (*aclpb.Rewrite, error) // TopChanges returns the top n most recent changes for each namespace configuration(s). // // For example, suppose you have M number of namespace configs and each config has X // number of snapshots. This yields an iterator that will iterate over at most M * n // values. If n >= X, then the iterator will iterate over at most M * X values. TopChanges(ctx context.Context, n uint) (ChangelogIterator, error) // LookupRelationReferencesByCount does a reverse lookup by the (namespace, relation...) pairs // and returns a map whose keys are the relations and whose values indicate the number of relation // tuples that reference the (namespace, relation) pair. If a (namespace, relation) pair is not // referenced at all, it's key is omitted in the output map. LookupRelationReferencesByCount(ctx context.Context, namespace string, relations ...string) (map[string]int, error) // WrapTransaction wraps the provided fn in a single transaction using the context. // If fn returns an error the transaction is rolled back and aborted. Otherwise it // is committed. WrapTransaction(ctx context.Context, fn func(ctx context.Context) error) error }
NamespaceManager defines an interface to manage/administer namespace configs.
type NamespaceOperation ¶
type NamespaceOperation string
NamespaceOperation represents the operations that can be taken on namespace configs.
const ( // AddNamespace is the operation when a new namespace config is added. AddNamespace NamespaceOperation = "ADD" // UpdateNamespace is the operation when a namespace config is updated. UpdateNamespace NamespaceOperation = "UPDATE" )
type NodeConfigs ¶
type NodeConfigs struct { // A unique identifier for this node in the cluster. ServerID string // The address used to advertise to other cluster members. Used // for nat traversal. Advertise string // A comma-separated list of existing nodes in the cluster to // join this node to. Join string // The port that cluster membership gossip is occurring on. NodePort int // The port serving the access-controller RPCs. ServerPort int }
NodeConfigs represent the configurations for an individual node withn a gossip cluster.
type NodeMetadata ¶
type NodeMetadata struct { NodeID string `json:"node-id"` ServerPort int `json:"port"` // A map of namespace config snapshots in their JSON serialized form. NamespaceConfigSnapshots map[string]map[time.Time][]byte `json:"namespace-snapshots"` }
NodeMetadata is local data specific to this node within the cluster. The node's metadata is broadcasted periodically to all peers/nodes in the cluster.
type NodeType ¶
type NodeType string
NodeType represents a specific type of node within a SubjectTree structure.
const ( // UnionNode represents a SubjectTree node that joins it's children via a union. UnionNode NodeType = "union" // IntersectionNode represents a SubjectTree node that joins it's children via an intersection. IntersectionNode NodeType = "intersection" // LeafNode represents a SubjectTree node with no children. LeafNode NodeType = "leaf" )
type PeerNamespaceConfigStore ¶
type PeerNamespaceConfigStore interface { // SetNamespaceConfigSnapshot stores the namespace config snapshot for the given peer. SetNamespaceConfigSnapshot(peerID string, namespace string, config *aclpb.NamespaceConfig, ts time.Time) error // ListNamespaceConfigSnapshots returns a map whose keys are the peers and whose values are another // map storing the timestamps of the snapshots for each namespace config. ListNamespaceConfigSnapshots(namespace string) (map[string]map[time.Time]*aclpb.NamespaceConfig, error) // GetNamespaceConfigSnapshots returns a map of namespaces and that namespace's snapshot configs for // a given peer. GetNamespaceConfigSnapshots(peerID string) (map[string]map[time.Time]*aclpb.NamespaceConfig, error) // GetNamespaceConfigSnapshot returns the specific namespace config for a peer from the snapshot timestamp // provided, or nil if one didn't exist at that point in time. GetNamespaceConfigSnapshot(peerID, namespace string, timestamp time.Time) (*aclpb.NamespaceConfig, error) // DeleteNamespaceConfigSnapshots deletes all of the namespaces configs for the given peer. DeleteNamespaceConfigSnapshots(peerID string) error }
PeerNamespaceConfigStore defines the interface to store the namespace config snapshots for each peer within a cluster.
type RelationTupleQuery ¶
type RelationTupleStore ¶
type RelationTupleStore interface { SubjectSets(ctx context.Context, object Object, relations ...string) ([]SubjectSet, error) ListRelationTuples(ctx context.Context, query *aclpb.ListRelationTuplesRequest_Query) ([]InternalRelationTuple, error) RowCount(ctx context.Context, query RelationTupleQuery) (int64, error) TransactRelationTuples(ctx context.Context, insert []*InternalRelationTuple, delete []*InternalRelationTuple) error }
RelationTupleStore defines an interface to manage the storage of relation tuples.
type Subject ¶
type Subject interface { json.Marshaler String() string FromString(string) (Subject, error) Equals(interface{}) bool ToProto() *pb.Subject }
func SubjectFromProto ¶
SubjectFromProto deserializes the protobuf subject `sub` into it's equivalent Subject structure.
func SubjectFromString ¶
SubjectFromString parses the string s and returns a Subject - either a SubjectSet or an explicit SubjectID.
type SubjectID ¶
type SubjectID struct {
ID string `json:"id"`
}
SubjectID is a unique identifier of some subject.
func (*SubjectID) Equals ¶
Equals returns a bool indicating if the provided interface and the SubjectID are equivalent. Two SubjectIDs are equivalent if they have the same ID.
func (*SubjectID) FromString ¶
FromString parses str and returns the Subject (SubjectID specifically).
func (SubjectID) MarshalJSON ¶
MarshalJSON returns the SubjectID as a json byte slice.
type SubjectSet ¶
type SubjectSet struct { Namespace string `json:"namespace"` Object string `json:"object"` Relation string `json:"relation"` }
SubjectSet defines the set of all subjects that have a specific relation to an object within some namespace.
func SubjectSetFromString ¶
func SubjectSetFromString(s string) (SubjectSet, error)
SubjectSetFromString takes a string `s` and attempts to decode it into a SubjectSet (namespace:object#relation). If the string is not formatted as a SubjectSet then an error is returned.
func (*SubjectSet) Equals ¶
func (s *SubjectSet) Equals(v interface{}) bool
Equals returns a bool indicating if the provided interface and the SubjectSet are equivalent. Two SubjectSets are equivalent if they define the same (namespace, object, relation) tuple.
func (*SubjectSet) FromString ¶
func (s *SubjectSet) FromString(str string) (Subject, error)
FromString parses str and returns the Subject (SubjectSet specifically) or an error if the string was malformed in some way.
func (SubjectSet) MarshalJSON ¶
func (s SubjectSet) MarshalJSON() ([]byte, error)
MarshalJSON returns the SubjectSet as a json byte slice.
func (*SubjectSet) String ¶
func (s *SubjectSet) String() string
String returns the string representation of the SubjectSet.
func (*SubjectSet) ToProto ¶
func (s *SubjectSet) ToProto() *pb.Subject
ToProto returns the protobuf Subject representation of the given SubjectSet.
type SubjectTree ¶
type SubjectTree struct { Type NodeType `json:"type"` Subject Subject `json:"subject"` Children []*SubjectTree `json:"children,omitempty"` }
SubjectTree represents a tree datastructure that stores relationships between Subjects.
func (*SubjectTree) ToProto ¶
func (t *SubjectTree) ToProto() *aclpb.SubjectTree
ToProto returns the protobuf representation of the SubjectTree.