profiledb

package
v0.0.0-...-ba93f90 Latest Latest
Warning

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

Go to latest
Published: Dec 22, 2025 License: AGPL-3.0 Imports: 20 Imported by: 0

Documentation

Overview

Package profiledb defines interfaces for databases of user profiles.

Index

Constants

View Source
const ErrDeviceNotFound errors.Error = "device not found"

ErrDeviceNotFound is an error returned by lookup methods when a device couldn't be found.

View Source
const ErrProfileNotFound errors.Error = "profile not found"

ErrProfileNotFound is an error returned by lookup methods when a profile couldn't be found.

Variables

This section is empty.

Functions

This section is empty.

Types

type AuthenticationFailedError

type AuthenticationFailedError struct {
	Message string
}

AuthenticationFailedError is returned by methods of Storage when the authentication to the storage fails.

func (*AuthenticationFailedError) Error

func (err *AuthenticationFailedError) Error() (msg string)

Error implements the [error] interface for *AuthenticationFailedError.

type BadRequestError

type BadRequestError struct {
	Message string
}

BadRequestError is returned by methods of Storage when the request is malformed.

func (*BadRequestError) Error

func (err *BadRequestError) Error() (msg string)

Error implements the [error] interface for *BadRequestError.

type Config

type Config struct {
	// Logger is used for logging the operation of profile database.  It must
	// not be nil.
	Logger *slog.Logger

	// BaseCustomLogger is the base logger used for the custom filters.  It must
	// not be nil.
	BaseCustomLogger *slog.Logger

	// ProfileAccessConstructor is used to create access managers for profiles.
	// It must not be nil.
	ProfileAccessConstructor *access.ProfileConstructor

	// Clock is used to get current time during refreshes.  It must not be nil.
	Clock timeutil.Clock

	// CustomDomainDB is used to keep track of the data about custom domains and
	// their certificates.  It must not be nil.
	CustomDomainDB CustomDomainDB

	// ErrColl is used to collect errors during refreshes.  It must not be nil.
	ErrColl errcoll.Interface

	// ProfileMetrics is used for the collection of the profile access engine
	// statistics.  It must not be nil.
	ProfileMetrics access.ProfileMetrics

	// Metrics is used for the collection of the user profiles statistics.  It
	// must not be nil.
	Metrics Metrics

	// Storage returns the data for this profile DB.  It must not be nil.
	Storage Storage

	// CacheFilePath is the path to the profile cache file.  If cacheFilePath is
	// the string "none", filesystem cache is disabled.  It must not be empty.
	CacheFilePath string

	// CacheFileIvl is the interval between updates of the profile cache file.
	// It must be positive if filesystem cache is enabled, see CacheFilePath.
	CacheFileIvl time.Duration

	// FullSyncIvl is the interval between two full synchronizations with the
	// storage.  It must be positive.
	FullSyncIvl time.Duration

	// FullSyncRetryIvl is the interval between two retries of full
	// synchronizations with the storage.  It must be positive.
	FullSyncRetryIvl time.Duration

	// ResponseSizeEstimate is the estimate of the size of one DNS response for
	// the purposes of custom ratelimiting.  Responses over this estimate are
	// counted as several responses.  It must be positive.
	ResponseSizeEstimate datasize.ByteSize

	// Opaque determines whether the profile cache will use the protobuf opaque
	// API.
	Opaque bool
}

Config is the default profile database configuration.

type CustomDomainDB

type CustomDomainDB interface {
	// AddCertificate adds information about a current certificate.  domains
	// must contain only valid domain names and wildcards like
	// "*.domain.example".  s must not be nil and must be valid.
	AddCertificate(
		ctx context.Context,
		profID agd.ProfileID,
		domains []string,
		state *agd.CustomDomainStateCurrent,
	)

	// DeleteAllWellKnownPaths removes all data about well-known paths for
	// certificate validation.
	DeleteAllWellKnownPaths(ctx context.Context)

	// SetWellKnownPath adds a well-known path for certificate validation to the
	// database and sets the expiration time.  s must not be nil and must be
	// valid.
	SetWellKnownPath(ctx context.Context, s *agd.CustomDomainStatePending)
}

CustomDomainDB is a database of custom-domain data. All methods must be safe for concurrent use.

type Default

type Default struct {
	// contains filtered or unexported fields
}

Default is the default in-memory implementation of the Interface interface that can refresh itself from the provided storage. It should be initially refreshed before use.

func New

func New(c *Config) (db *Default, err error)

New returns a new default in-memory profile database with a filesystem cache. db is not nil if the error is from getting the file cache. c must not be nil and must be valid.

func (*Default) CreateAutoDevice

func (db *Default) CreateAutoDevice(
	ctx context.Context,
	id agd.ProfileID,
	humanID agd.HumanID,
	devType agd.DeviceType,
) (p *agd.Profile, d *agd.Device, err error)

CreateAutoDevice implements the Interface interface for *Default.

func (*Default) ProfileByDedicatedIP

func (db *Default) ProfileByDedicatedIP(
	ctx context.Context,
	ip netip.Addr,
) (p *agd.Profile, d *agd.Device, err error)

ProfileByDedicatedIP implements the Interface interface for *Default. ip must be valid.

func (*Default) ProfileByDeviceID

func (db *Default) ProfileByDeviceID(
	ctx context.Context,
	id agd.DeviceID,
) (p *agd.Profile, d *agd.Device, err error)

ProfileByDeviceID implements the Interface interface for *Default.

func (*Default) ProfileByHumanID

func (db *Default) ProfileByHumanID(
	ctx context.Context,
	id agd.ProfileID,
	humanID agd.HumanIDLower,
) (p *agd.Profile, d *agd.Device, err error)

ProfileByHumanID implements the Interface interface for *Default.

func (*Default) ProfileByLinkedIP

func (db *Default) ProfileByLinkedIP(
	ctx context.Context,
	ip netip.Addr,
) (p *agd.Profile, d *agd.Device, err error)

ProfileByLinkedIP implements the Interface interface for *Default. ip must be valid.

func (*Default) Refresh

func (db *Default) Refresh(ctx context.Context) (err error)

Refresh implements the service.Refresher interface for *Default. It updates the internal maps and the synchronization time using the data it receives from the storage.

func (*Default) RefreshFull

func (db *Default) RefreshFull(ctx context.Context) (err error)

RefreshFull is a service.RefresherFunc that updates the internal maps and the synchronization time using the data it receives from the storage.

type DeviceQuotaExceededError

type DeviceQuotaExceededError struct {
	Message string
}

DeviceQuotaExceededError is returned by [Storage.CreateAutoDevice] when the profile has exceeded the number of devices it can create.

func (*DeviceQuotaExceededError) Error

func (err *DeviceQuotaExceededError) Error() (msg string)

Error implements the [error] interface for *DeviceQuotaExceededError.

func (*DeviceQuotaExceededError) IsSentryReportable

func (err *DeviceQuotaExceededError) IsSentryReportable() (ok bool)

IsSentryReportable implements the errcoll.SentryReportableError interface for *DeviceQuotaExceededError.

type Disabled

type Disabled struct{}

Disabled is a profile database that panics on any call.

func (*Disabled) CreateAutoDevice

func (d *Disabled) CreateAutoDevice(
	_ context.Context,
	_ agd.ProfileID,
	_ agd.HumanID,
	_ agd.DeviceType,
) (_ *agd.Profile, _ *agd.Device, _ error)

CreateAutoDevice implements the Interface interface for *Disabled.

func (*Disabled) ProfileByDedicatedIP

func (d *Disabled) ProfileByDedicatedIP(
	_ context.Context,
	_ netip.Addr,
) (_ *agd.Profile, _ *agd.Device, _ error)

ProfileByDedicatedIP implements the Interface interface for *Disabled.

func (*Disabled) ProfileByDeviceID

func (d *Disabled) ProfileByDeviceID(
	_ context.Context,
	_ agd.DeviceID,
) (_ *agd.Profile, _ *agd.Device, _ error)

ProfileByDeviceID implements the Interface interface for *Disabled.

func (*Disabled) ProfileByHumanID

func (d *Disabled) ProfileByHumanID(
	_ context.Context,
	_ agd.ProfileID,
	_ agd.HumanIDLower,
) (_ *agd.Profile, _ *agd.Device, _ error)

ProfileByHumanID implements the Interface interface for *Disabled.

func (*Disabled) ProfileByLinkedIP

func (d *Disabled) ProfileByLinkedIP(
	_ context.Context,
	_ netip.Addr,
) (_ *agd.Profile, _ *agd.Device, _ error)

ProfileByLinkedIP implements the Interface interface for *Disabled.

type EmptyCustomDomainDB

type EmptyCustomDomainDB struct{}

EmptyCustomDomainDB is the implementation of the CustomDomainDB interface that does nothing.

func (EmptyCustomDomainDB) AddCertificate

AddCertificate implements the CustomDomainDB interface for EmptyCustomDomainDB

func (EmptyCustomDomainDB) DeleteAllWellKnownPaths

func (EmptyCustomDomainDB) DeleteAllWellKnownPaths(_ context.Context)

DeleteAllWellKnownPaths implements the CustomDomainDB interface for EmptyCustomDomainDB.

func (EmptyCustomDomainDB) SetWellKnownPath

SetWellKnownPath implements the CustomDomainDB interface for EmptyCustomDomainDB.

type EmptyMetrics

type EmptyMetrics struct{}

EmptyMetrics is the implementation of the Metrics interface that does nothing.

func (EmptyMetrics) HandleProfilesUpdate

func (EmptyMetrics) HandleProfilesUpdate(_ context.Context, _ *UpdateMetrics)

HandleProfilesUpdate implements the Metrics interface for EmptyMetrics.

func (EmptyMetrics) IncrementDeleted

func (EmptyMetrics) IncrementDeleted(_ context.Context)

IncrementDeleted implements the Metrics interface for EmptyMetrics.

func (EmptyMetrics) IncrementSyncTimeouts

func (EmptyMetrics) IncrementSyncTimeouts(_ context.Context, _ bool)

IncrementSyncTimeouts implements the Metrics interface for EmptyMetrics.

func (EmptyMetrics) ObserveFileCacheStoreDuration

func (EmptyMetrics) ObserveFileCacheStoreDuration(_ context.Context, _ time.Duration)

ObserveFileCacheStoreDuration implements the Metrics interface for EmptyMetrics.

func (EmptyMetrics) SetFileCacheSize

func (EmptyMetrics) SetFileCacheSize(_ context.Context, _ datasize.ByteSize)

SetFileCacheSize implements the Metrics interface for EmptyMetrics.

func (EmptyMetrics) SetLastFileCacheSyncTime

func (EmptyMetrics) SetLastFileCacheSyncTime(_ context.Context, _ time.Time)

SetLastFileCacheSyncTime implements the Metrics interface for EmptyMetrics.

func (EmptyMetrics) SetProfilesAndDevicesNum

func (EmptyMetrics) SetProfilesAndDevicesNum(_ context.Context, _, _ uint)

SetProfilesAndDevicesNum implements the Metrics interface for EmptyMetrics.

type Interface

type Interface interface {
	// CreateAutoDevice creates a new automatic device for the given profile
	// with the given human-readable device ID and device type.  All arguments
	// must be valid.
	CreateAutoDevice(
		ctx context.Context,
		id agd.ProfileID,
		humanID agd.HumanID,
		devType agd.DeviceType,
	) (p *agd.Profile, d *agd.Device, err error)

	// ProfileByDedicatedIP returns the profile and the device identified by its
	// dedicated DNS server IP address.  ip must be valid.
	ProfileByDedicatedIP(
		ctx context.Context,
		ip netip.Addr,
	) (p *agd.Profile, d *agd.Device, err error)

	// ProfileByDeviceID returns the profile and the device identified by id.
	// id must be valid.
	ProfileByDeviceID(
		ctx context.Context,
		id agd.DeviceID,
	) (p *agd.Profile, d *agd.Device, err error)

	// ProfileByHumanID returns the profile and the device identified by the
	// profile ID and the lowercase version of the human-readable device ID.
	// id and humanIDLower must be valid.
	ProfileByHumanID(
		ctx context.Context,
		id agd.ProfileID,
		humanIDLower agd.HumanIDLower,
	) (p *agd.Profile, d *agd.Device, err error)

	// ProfileByLinkedIP returns the profile and the device identified by its
	// linked IP address.  ip must be valid.
	ProfileByLinkedIP(ctx context.Context, ip netip.Addr) (p *agd.Profile, d *agd.Device, err error)
}

Interface is the local database of user profiles and devices.

NOTE: All returned values must not be modified.

type Metrics

type Metrics interface {
	// HandleProfilesUpdate handles the user profile update.  m must not be nil.
	HandleProfilesUpdate(ctx context.Context, m *UpdateMetrics)

	// SetProfilesAndDevicesNum sets the total number of user profiles and the
	// total number of devices.
	SetProfilesAndDevicesNum(ctx context.Context, profNum, devNum uint)

	// IncrementSyncTimeouts increments the total number of timeout errors
	// during user profile update.
	IncrementSyncTimeouts(ctx context.Context, isFullSync bool)

	// IncrementDeleted increments the total number of deleted user profiles.
	IncrementDeleted(ctx context.Context)

	// SetLastFileCacheSyncTime sets the time of the last successful cache file
	// synchronization.
	SetLastFileCacheSyncTime(ctx context.Context, t time.Time)

	// SetFileCacheSize sets the size of the cache file.
	SetFileCacheSize(ctx context.Context, size datasize.ByteSize)

	// ObserveFileCacheStoreDuration observes the duration of storing file cache
	// to disk.
	ObserveFileCacheStoreDuration(ctx context.Context, d time.Duration)
}

Metrics is an interface that is used for the collection of the user profiles statistics.

type RateLimitedError

type RateLimitedError struct {
	// Message is the error message from the storage.
	Message string

	// RetryDelay is the hint to use for when to retry the request.
	//
	// TODO(a.garipov):  Use in [Default.Refresh].
	RetryDelay time.Duration
}

RateLimitedError is returned by methods of Storage when the requests are made too often.

func (*RateLimitedError) Error

func (err *RateLimitedError) Error() (msg string)

Error implements the [error] interface for *RateLimitedError.

type Storage

type Storage interface {
	// CreateAutoDevice creates an auto device based on the given data.
	// req must not be nil.
	CreateAutoDevice(
		ctx context.Context,
		req *StorageCreateAutoDeviceRequest,
	) (resp *StorageCreateAutoDeviceResponse, err error)

	// Profiles returns profile and device data that has changed since
	// req.SyncTime.  req must not be nil.
	Profiles(
		ctx context.Context,
		req *StorageProfilesRequest,
	) (resp *StorageProfilesResponse, err error)
}

Storage is a storage from which an Default receives data about profiles and devices. All methods must be safe for concurrent use.

TODO(a.garipov): Consider separating into a new package along with its errors.

type StorageCreateAutoDeviceRequest

type StorageCreateAutoDeviceRequest struct {
	ProfileID  agd.ProfileID
	HumanID    agd.HumanID
	DeviceType agd.DeviceType
}

StorageCreateAutoDeviceRequest contains the data for a call to the [Storage.CreateAutoDevice] method. All fields should be valid.

type StorageCreateAutoDeviceResponse

type StorageCreateAutoDeviceResponse struct {
	// Device is the resulting device.  If the error returned with this response
	// is nil, Device is never nil.
	Device *agd.Device
}

StorageCreateAutoDeviceResponse is the response from the [Storage.CreateAutoDevice] method.

type StorageDeviceChange

type StorageDeviceChange struct {
	// DeletedDeviceIDs are the IDs of devices deleted during a partial update
	// of a profile.
	DeletedDeviceIDs []agd.DeviceID

	// IsPartial is true when the profile has been updated partially.
	IsPartial bool
}

StorageDeviceChange describes changes in the devices of a profile.

type StorageProfilesRequest

type StorageProfilesRequest struct {
	// SyncTime is the last time profiles were synced.
	SyncTime time.Time
}

StorageProfilesRequest contains the data for a call to the [Storage.Profiles] method.

type StorageProfilesResponse

type StorageProfilesResponse struct {
	// SyncTime is the time that should be saved and used as the next
	// [ProfilesRequest.SyncTime].
	SyncTime time.Time

	// DeviceChanges defines the device changes committed in this response.
	//
	// TODO(a.garipov):  This is currently rather badly designed.  Find ways of
	// making this less awkward.
	DeviceChanges map[agd.ProfileID]*StorageDeviceChange

	// Profiles are the profiles data from the [Storage].
	Profiles []*agd.Profile

	// Devices are the device data from the [Storage].
	Devices []*agd.Device
}

StorageProfilesResponse is the response from the [Storage.Profiles] method.

type UpdateMetrics

type UpdateMetrics = struct {
	// Duration is the duration of the user profiles update operation.
	Duration time.Duration

	// ProfilesNum is the total number of updated profiles.
	ProfilesNum uint

	// DevicesNum is the total number of updated devices.
	DevicesNum uint

	// IsSuccess indicates whether the update was successful.
	IsSuccess bool

	// IsFullSync indicates whether the update was full or partial.
	IsFullSync bool
}

UpdateMetrics is an alias for a structure that contains the information about a user profiles update operation.

NOTE: This is an alias to reduce the amount of dependencies required of implementations. This is also the reason why only built-in or stdlib types are used.

Directories

Path Synopsis
Package internal contains common constants and types that all implementations of the default profile-cache use.
Package internal contains common constants and types that all implementations of the default profile-cache use.
fcpb
Package fcpb contains the new opaque api protobuf structures for the profile cache.
Package fcpb contains the new opaque api protobuf structures for the profile cache.
filecacheopb
Package filecacheopb contains encoding and decoding logic for opaque file cache.
Package filecacheopb contains encoding and decoding logic for opaque file cache.
filecachepb
Package filecachepb contains the protobuf structures for the profile cache.
Package filecachepb contains the protobuf structures for the profile cache.
profiledbtest
Package profiledbtest contains common helpers for profile-database tests.
Package profiledbtest contains common helpers for profile-database tests.

Jump to

Keyboard shortcuts

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