accesscontroller

package
v0.1.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 31, 2021 License: Apache-2.0 Imports: 22 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
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.

View Source
var ErrInvalidSubjectSetString = fmt.Errorf("the provided SubjectSet string is malformed")

ErrInvalidSubjectSetString is an error that is returned if a malformed SubjectSet string is encountered.

View Source
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.

View Source
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

func ChecksumFromContext(ctx context.Context) (uint32, bool)

ChecksumFromContext extracts the hashring checksum from the provided ctx or returns false if none was found in the ctx.

func NamespaceConfigTimestampFromContext

func NamespaceConfigTimestampFromContext(ctx context.Context, namespace string) (time.Time, bool)

NamespaceConfigTimestampFromContext extracts the snapshot timestamp for a namespace configuration from the provided context. If none is present, a boolean false is returned.

func NewContextWithChecksum

func NewContextWithChecksum(ctx context.Context, hashringChecksum uint32) context.Context

NewContextWithChecksum returns a new Context that carries the hashring checksum.

func NewContextWithNamespaceConfigTimestamp

func NewContextWithNamespaceConfigTimestamp(ctx context.Context, namespace string, timestamp time.Time) context.Context

NewContextWithNamespaceConfigTimestamp returns a new Context that carries the namespace config name and timestamp.

Types

type AccessController

func NewAccessController

func NewAccessController(opts ...AccessControllerOption) (*AccessController, error)

NewAccessController constructs a new AccessController with the options provided.

func (*AccessController) Check

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

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

HealthCheck returns a grpc.health.v1.HealthCheckResponse to indicate the healthiness of the access-controller.

func (*AccessController) ListRelationTuples

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

ReadConfig fetches the namespace configuration for the provided namespace. If the namespace does not exist, an error is returned.

func (*AccessController) WriteConfig

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

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

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

Check returns the server's current health status.

func (*HealthChecker) Watch added in v0.1.2

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"
)

func (NodeType) ToProto

func (t NodeType) ToProto() aclpb.NodeType

ToProto returns the protobuf representation of the NodeType.

type Object

type Object struct {
	Namespace string
	ID        string
}

Object represents a namespace and object id.

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 RelationTupleQuery struct {
	Object    Object
	Relations []string
	Subject   Subject
}

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

func SubjectFromProto(sub *pb.Subject) Subject

SubjectFromProto deserializes the protobuf subject `sub` into it's equivalent Subject structure.

func SubjectFromString

func SubjectFromString(s string) (Subject, error)

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

func (s *SubjectID) Equals(v interface{}) bool

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

func (s *SubjectID) FromString(str string) (Subject, error)

FromString parses str and returns the Subject (SubjectID specifically).

func (SubjectID) MarshalJSON

func (s SubjectID) MarshalJSON() ([]byte, error)

MarshalJSON returns the SubjectID as a json byte slice.

func (*SubjectID) String

func (s *SubjectID) String() string

String returns the string representation of the SubjectID.

func (*SubjectID) ToProto

func (s *SubjectID) ToProto() *pb.Subject

ToProto returns the protobuf Subject representation of the given SubjectID.

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.

Directories

Path Synopsis
namespace-manager

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL