registry

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 3, 2019 License: MIT Imports: 9 Imported by: 0

README

Registry

Qri GoDoc License Codecov CI

Registry defines primitives for keeping centralized repositories of qri types (peers, datasets, etc). It uses classical client/server patterns, arranging types into cannonical stores.

At first glance, this seems to run against the grain of "decentralize or die" principles espoused by those of us interested in reducing points of failure in a network. Consider this package testiment that nothing is absolute.

It is a long term goal at qri that it be possible to fully decentralize all aspects, of qri this isn't practical short-term, and isn't always a desired property.

As an example, associating human-readable usernames with crypto keypairs is an order of magnitude easier if you just put the damn thing in a list. So that's what this registry does.

Long term, we intended to implement a distributed hash table (DHT) to make it possible to operate fully-decentralized, and provide registry support as a configurable detail.

This base package provides common primitives that other packages can import to work with a registry, and subpackages for turning these primitives into usable tools like servers & (eventually) command-line clients

Documentation

Overview

Package registry defines primitives for keeping centralized repositories of qri types (peers, datasets, etc). It uses classical client/server patterns, arranging types into cannonical stores.

At first glance, this seems to run against the grain of "decentralize or die" principles espoused by those of us interested in reducing points of failure in a network. Registries offer a way to operate as a federated model, with peers opting-in to a set of norms set forth by a registry.

It is a long term goal at qri that it be *possible* to fully decentralize all aspects, of qri this isn't practical short-term, and isn't always a desired property.

As an example, associating human-readable usernames with crypto keypairs is an order of magnitude easier if you just put the damn thing in a list. So that's what this registry does.

This base package provides common primitives that other packages can import to work with a registry, and subpackages for turning these primitives into usable tools like servers & (eventually) command-line clients

Index

Constants

This section is empty.

Variables

View Source
var ErrPinsetNotSupported = fmt.Errorf("pinset is not supported")

ErrPinsetNotSupported is a cannonical error for a repository that does not support pinning

View Source
var ErrSearchNotSupported = fmt.Errorf("search not supported")

ErrSearchNotSupported is the canonical error to indicate search isn't implemented

Functions

func DeregisterDataset

func DeregisterDataset(store Datasets, d *Dataset) error

DeregisterDataset removes a dataset from a given store if it exists & is valid

func DeregisterProfile

func DeregisterProfile(store Profiles, p *Profile) error

DeregisterProfile removes a profile from the registry if it exists confirming the user has the authority to do so

func RegisterDataset

func RegisterDataset(store Datasets, d *Dataset) error

RegisterDataset adds a dataset to the store if it's valid

func RegisterProfile

func RegisterProfile(store Profiles, p *Profile) error

RegisterProfile adds a profile to the list if it's valid and the desired handle isn't taken

Types

type Dataset

type Dataset struct {
	// Dataset   dataset.Dataset
	Commit    *dataset.Commit    `json:"commit,omitempty"`
	Meta      *dataset.Meta      `json:"meta,omitempty"`
	Path      string             `json:"path,omitempty"`
	Structure *dataset.Structure `json:"structure,omitempty"`
	ProfileID string             `json:"profileID,omitempty"`

	Handle    string `json:",omitempty"`
	Name      string `json:",omitempty"`
	PublicKey string `json:",omitempty"`
}

Dataset is a registry's version of a dataset

func NewDataset

func NewDataset(handle, name string, ds *dataset.Dataset, pubkey crypto.PubKey) (*Dataset, error)

NewDataset creates a new dataset instance

func NewDatasetRef

func NewDatasetRef(peername, name, profileID, path string) *Dataset

NewDatasetRef creates a dataset with any known reference detail strings

func (*Dataset) Key

func (d *Dataset) Key() string

Key gives the string this dataset value should be keyed to

func (*Dataset) Validate

func (d *Dataset) Validate() error

Validate is a sanity check that all required values are present

func (*Dataset) Verify

func (d *Dataset) Verify() error

Verify checks a profile's proof of key ownership Registree's must prove they have control of the private key by signing the desired handle, which is validated with a provided public key. Public key, handle, and date of

type Datasets

type Datasets interface {
	// Len returns the number of records in the set
	Len() int
	// Load fetches a dataset from the list by key
	Load(key string) (value *Dataset, ok bool)
	// Range calls an iteration fuction on each element in the map until
	// the end of the list is reached or iter returns true
	Range(iter func(key string, p *Dataset) (brk bool))
	// SortedRange is like range but with deterministic key ordering
	SortedRange(iter func(key string, p *Dataset) (brk bool))

	// Store adds an entry, bypassing the register process
	// store is only exported for administrative use cases.
	// most of the time callers should use Register instead
	Store(key string, value *Dataset)
	// Delete removes a record stored at key
	// Delete is only exported for administrative use cases.
	// most of the time callers should use Deregister instead
	Delete(key string)
}

Datasets is the interface for working with a set of *Dataset's Register, Deregister, Load, Len, Range, and SortedRange should be considered safe to hook up to public http endpoints, whereas Delete & Store should only be exposed in administrative contexts, users should prefer using RegisterDataset & DegristerDataset for dataset manipulation operations

type Indexer

type Indexer interface {
	// IndexDatasets adds one or more datasets to a search index
	IndexDatasets([]*Dataset) error
	// UnindexDatasets removes one or more datasets from a search index
	UnindexDatasets([]*Dataset) error
}

Indexer is an interface for adding registry values to a search index

type MemDatasets

type MemDatasets struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

MemDatasets is a map of datasets data safe for concurrent use heavily inspired by sync.Map

func NewMemDatasets

func NewMemDatasets() *MemDatasets

NewMemDatasets allocates a new *MemDatasets map

func (*MemDatasets) Delete

func (ds *MemDatasets) Delete(key string)

Delete removes a record from MemDatasets at key

func (*MemDatasets) Len

func (ds *MemDatasets) Len() int

Len returns the number of records in the map

func (*MemDatasets) Load

func (ds *MemDatasets) Load(key string) (value *Dataset, ok bool)

Load fetches a dataset from the list by key

func (*MemDatasets) Range

func (ds *MemDatasets) Range(iter func(key string, p *Dataset) (brk bool))

Range calls an iteration fuction on each element in the map until the end of the list is reached or iter returns true

func (*MemDatasets) SortedRange

func (ds *MemDatasets) SortedRange(iter func(key string, p *Dataset) (brk bool))

SortedRange is like range but with deterministic key ordering

func (*MemDatasets) Store

func (ds *MemDatasets) Store(key string, value *Dataset)

Store adds an entry

type MemProfiles

type MemProfiles struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

MemProfiles is a map of profile data safe for concurrent use heavily inspired by sync.Map

func NewMemProfiles

func NewMemProfiles() *MemProfiles

NewMemProfiles allocates a new *MemProfiles map

func (*MemProfiles) Delete

func (ps *MemProfiles) Delete(key string)

Delete removes a record from MemProfiles at key

func (*MemProfiles) Len

func (ps *MemProfiles) Len() int

Len returns the number of records in the map

func (*MemProfiles) Load

func (ps *MemProfiles) Load(key string) (value *Profile, ok bool)

Load fetches a profile from the list by key

func (*MemProfiles) Range

func (ps *MemProfiles) Range(iter func(key string, p *Profile) (brk bool))

Range calls an iteration fuction on each element in the map until the end of the list is reached or iter returns true

func (*MemProfiles) SortedRange

func (ps *MemProfiles) SortedRange(iter func(key string, p *Profile) (brk bool))

SortedRange is like range but with deterministic key ordering

func (*MemProfiles) Store

func (ps *MemProfiles) Store(key string, value *Profile)

Store adds an entry

type MemReputations

type MemReputations struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

MemReputations is a map of reputation data safe for concurrent use heavily inspired by sync.Map

func NewMemReputations

func NewMemReputations() *MemReputations

NewMemReputations allocates a new *MemReputations map

func (*MemReputations) Add

func (rs *MemReputations) Add(r *Reputation) error

Add adds the reputation to the map of reputations it Validates the reputation before adding it

func (*MemReputations) Delete

func (rs *MemReputations) Delete(key string)

Delete removes a record from MemReputations at key

func (*MemReputations) Len

func (rs *MemReputations) Len() int

Len returns the number of records in the map

func (*MemReputations) Load

func (rs *MemReputations) Load(key string) (value *Reputation, ok bool)

Load fetches a reputation from the list by key

func (*MemReputations) Range

func (rs *MemReputations) Range(iter func(key string, r *Reputation) (brk bool))

Range calls an iteration fuction on each element in the map until the end of the list is reached or iter returns true

func (*MemReputations) SortedRange

func (rs *MemReputations) SortedRange(iter func(key string, r *Reputation) (brk bool))

SortedRange is like range but with deterministic key ordering

func (*MemReputations) Store

func (rs *MemReputations) Store(key string, value *Reputation)

Store adds an entry

type MockSearch

type MockSearch struct {
	Datasets Datasets
}

MockSearch is a very naive implementation of search that wraps registry.Datasets and only checks for exact substring matches of dataset's meta.title property. It's mainly intended for testing purposes.

func (MockSearch) Search

func (ms MockSearch) Search(p SearchParams) (results []Result, err error)

Search is a trivial search implementation used for testing

type NilSearch

type NilSearch bool

NilSearch is a basic implementation of Searchable which returns an error to indicate that search is not supported

func (NilSearch) Search

func (ns NilSearch) Search(p SearchParams) ([]Result, error)

Search returns an error indicating that search is not supported

type Profile

type Profile struct {
	ProfileID string
	Handle    string
	Signature string `json:",omitempty"`
	PublicKey string `json:",omitempty"`
	Created   time.Time
}

Profile is a shorthand version of qri-io/qri/repo/profile.Profile I'm toying with the idea of using "handle" instead of "peername", so it's "handle" here for now

func ProfileFromPrivateKey

func ProfileFromPrivateKey(handle string, privKey crypto.PrivKey) (*Profile, error)

ProfileFromPrivateKey generates a profile struct from a private key & desired profile handle It adds all the necessary components to pass profiles.Register, creating base64-encoded PublicKey & Signature, and base58-encoded ProfileID

func (*Profile) Validate

func (p *Profile) Validate() error

Validate is a sanity check that all required values are present

func (*Profile) Verify

func (p *Profile) Verify() error

Verify checks a profile's proof of key ownership Registree's must prove they have control of the private key by signing the desired handle, which is validated with a provided public key. Public key, handle, and date of

type Profiles

type Profiles interface {
	// Len returns the number of records in the set
	Len() int
	// Load fetches a profile from the list by key
	Load(key string) (value *Profile, ok bool)
	// Range calls an iteration fuction on each element in the map until
	// the end of the list is reached or iter returns true
	Range(iter func(key string, p *Profile) (brk bool))
	// SortedRange is like range but with deterministic key ordering
	SortedRange(iter func(key string, p *Profile) (brk bool))

	// Store adds an entry, bypassing the register process
	// store is only exported for administrative use cases.
	// most of the time callers should use Register instead
	Store(key string, value *Profile)
	// Delete removes a record from the set at key
	// Delete is only exported for administrative use cases.
	// most of the time callers should use Deregister instead
	Delete(key string)
}

Profiles is the interface for working with a set of *Profile's Register, Deregister, Load, Len, Range, and SortedRange should be considered safe to hook up to public http endpoints, whereas Delete & Store should only be exposed in administrative contexts users should prefer using RegisterProfile & DegristerProfile for dataset manipulation operations

type Registry

type Registry struct {
	Profiles    Profiles
	Datasets    Datasets
	Reputations Reputations
	Search      Searchable
	Indexer     Indexer
}

Registry a collection of interfaces that together form a registry service

type Reputation

type Reputation struct {
	ProfileID string
	Rep       int
}

Reputation is record of the peers reputation on the network TODO: this is a stub that can and should be expanded

func NewReputation

func NewReputation(id string) *Reputation

NewReputation creates a new reputation. Reputations start at 1 for now REPUTATIONS MUST BE NON-ZERO NUMBERS

func (*Reputation) Reputation

func (r *Reputation) Reputation() int

Reputation gets the rep of a given Reputation

func (*Reputation) SetReputation

func (r *Reputation) SetReputation(reputation int)

SetReputation sets the reputation of a given Reputation

func (*Reputation) Validate

func (r *Reputation) Validate() error

Validate is a sanity check that all required values are present

type ReputationResponse

type ReputationResponse struct {
	Reputation *Reputation
	Expiration time.Duration
}

ReputationResponse is the result of a request for a reputation

type Reputations

type Reputations interface {
	// Len returns the number of records in the set
	Len() int
	// Load fetches a profile from the list by key
	Load(key string) (value *Reputation, ok bool)
	// Range calls an iteration fuction on each element in the map until
	// the end of the list is reached or iter returns true
	Range(iter func(key string, r *Reputation) (brk bool))
	// SortedRange is like range but with deterministic key ordering
	SortedRange(iter func(key string, r *Reputation) (brk bool))
	// Add adds the Reputation to the list of reputations
	Add(r *Reputation) error

	// Store adds an entry, bypassing the register process
	// store is only exported for administrative use cases.
	// most of the time callers should use Register instead
	Store(key string, value *Reputation)
	// Delete removes a record from the set at key
	// Delete is only exported for administrative use cases.
	// most of the time callers should use Deregister instead
	Delete(key string)
}

Reputations is the interface for working with a set of *Reputation's Add, Load, Len, Range, and SortedRange should be considered safe to hook up to public http endpoints, whereas Delete & Store should only be exposed in administrative contexts

type Result

type Result struct {
	Type  string      // one of ["dataset", "profile"] for now
	ID    string      // identifier to lookup
	Value interface{} // Value returned
}

Result is the interface that a search result implements

type SearchParams

type SearchParams struct {
	Q             string
	Limit, Offset int
}

SearchParams encapsulates parameters provided to Searchable.Search

type Searchable

type Searchable interface {
	Search(p SearchParams) ([]Result, error)
}

Searchable is an opt-in interface for registries that wish to support search

Directories

Path Synopsis
Package ns defines the qri dataset naming system This package is currently an experiment while we try to settle the distinction between a dataset.datasetPod and a reference.
Package ns defines the qri dataset naming system This package is currently an experiment while we try to settle the distinction between a dataset.datasetPod and a reference.
Package regclient defines a client for interacting with a registry server
Package regclient defines a client for interacting with a registry server
Package regserver is a wrapper around the handlers package, turning it into a proper http server
Package regserver is a wrapper around the handlers package, turning it into a proper http server
handlers
Package handlers creates HTTP handler functions for registry interface implementations
Package handlers creates HTTP handler functions for registry interface implementations
mock
Package mock provides a mock registry server for testing purposes it mocks the behaviour of a registry server with in-memory storage
Package mock provides a mock registry server for testing purposes it mocks the behaviour of a registry server with in-memory storage

Jump to

Keyboard shortcuts

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