db

package
v0.25.0-beta.1 Latest Latest
Warning

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

Go to latest
Published: Feb 5, 2025 License: BSD-3-Clause Imports: 37 Imported by: 0

Documentation

Index

Constants

View Source
const (
	NodeGivenNameHashLength = 8
	NodeGivenNameTrimSize   = 2
)

Variables

View Source
var (
	ErrNodeNotFound                  = errors.New("node not found")
	ErrNodeRouteIsNotAvailable       = errors.New("route is not available on node")
	ErrNodeNotFoundRegistrationCache = errors.New(
		"node not found in registration cache",
	)
	ErrCouldNotConvertNodeInterface = errors.New("failed to convert node interface")
	ErrDifferentRegisteredUser      = errors.New(
		"node was previously registered with a different user",
	)
)
View Source
var (
	ErrPreAuthKeyNotFound          = errors.New("AuthKey not found")
	ErrPreAuthKeyExpired           = errors.New("AuthKey expired")
	ErrSingleUseAuthKeyHasBeenUsed = errors.New("AuthKey has already been used")
	ErrUserMismatch                = errors.New("user mismatch")
	ErrPreAuthKeyACLTagInvalid     = errors.New("AuthKey tag is invalid")
)
View Source
var (
	ErrUserExists        = errors.New("user already exists")
	ErrUserNotFound      = errors.New("user not found")
	ErrUserStillHasNodes = errors.New("user not empty: node(s) found")
)
View Source
var ErrAPIKeyFailedToParse = errors.New("failed to parse ApiKey")
View Source
var ErrCannotChangeOIDCUser = errors.New("cannot edit OIDC user")
View Source
var ErrCouldNotAllocateIP = errors.New("failed to allocate IP")
View Source
var ErrRouteIsNotAvailable = errors.New("route is not available")

Functions

func AssignNodeToUser

func AssignNodeToUser(tx *gorm.DB, node *types.Node, uid types.UserID) error

AssignNodeToUser assigns a Node to a user.

func CreatePreAuthKey

func CreatePreAuthKey(
	tx *gorm.DB,
	uid types.UserID,
	reusable bool,
	ephemeral bool,
	expiration *time.Time,
	aclTags []string,
) (*types.PreAuthKey, error)

CreatePreAuthKey creates a new PreAuthKey in a user, and returns it.

func CreateUser

func CreateUser(tx *gorm.DB, user types.User) (*types.User, error)

CreateUser creates a new User. Returns error if could not be created or another user already exists.

func DeleteNode

func DeleteNode(tx *gorm.DB,
	node *types.Node,
	isLikelyConnected *xsync.MapOf[types.NodeID, bool],
) ([]types.NodeID, error)

DeleteNode deletes a Node from the database. Caller is responsible for notifying all of change.

func DeleteRoute

func DeleteRoute(
	tx *gorm.DB,
	id uint64,
	isLikelyConnected *xsync.MapOf[types.NodeID, bool],
) ([]types.NodeID, error)

func DestroyPreAuthKey

func DestroyPreAuthKey(tx *gorm.DB, pak types.PreAuthKey) error

DestroyPreAuthKey destroys a preauthkey. Returns error if the PreAuthKey does not exist.

func DestroyUser

func DestroyUser(tx *gorm.DB, uid types.UserID) error

DestroyUser destroys a User. Returns error if the User does not exist or if there are nodes associated with it.

func DisableRoute

func DisableRoute(tx *gorm.DB,
	id uint64,
	isLikelyConnected *xsync.MapOf[types.NodeID, bool],
) ([]types.NodeID, error)

func EnableAutoApprovedRoutes

func EnableAutoApprovedRoutes(
	tx *gorm.DB,
	polMan policy.PolicyManager,
	node *types.Node,
) error

EnableAutoApprovedRoutes enables any routes advertised by a node that match the ACL autoApprovers policy.

func EnableRoute

func EnableRoute(tx *gorm.DB, id uint64) (*types.StateUpdate, error)

func ExpireExpiredNodes

func ExpireExpiredNodes(tx *gorm.DB,
	lastCheck time.Time,
) (time.Time, types.StateUpdate, bool)

func ExpirePreAuthKey

func ExpirePreAuthKey(tx *gorm.DB, k *types.PreAuthKey) error

MarkExpirePreAuthKey marks a PreAuthKey as expired.

func FailoverNodeRoutesIfNecessary added in v0.24.0

func FailoverNodeRoutesIfNecessary(
	tx *gorm.DB,
	isLikelyConnected *xsync.MapOf[types.NodeID, bool],
	node *types.Node,
) (*types.StateUpdate, error)

FailoverNodeRoutesIfNecessary takes a node and checks if the node's route need to be failed over to another host. If needed, the failover will be attempted.

func GetAdvertisedRoutes

func GetAdvertisedRoutes(tx *gorm.DB, node *types.Node) ([]netip.Prefix, error)

GetAdvertisedRoutes returns the routes that are be advertised by the given node.

func GetEnabledRoutes

func GetEnabledRoutes(tx *gorm.DB, node *types.Node) ([]netip.Prefix, error)

GetEnabledRoutes returns the routes that are enabled for the node.

func GetNodeAdvertisedRoutes

func GetNodeAdvertisedRoutes(tx *gorm.DB, node *types.Node) (types.Routes, error)

func GetNodeByID

func GetNodeByID(tx *gorm.DB, id types.NodeID) (*types.Node, error)

GetNodeByID finds a Node by ID and returns the Node struct.

func GetNodeByMachineKey

func GetNodeByMachineKey(
	tx *gorm.DB,
	machineKey key.MachinePublic,
) (*types.Node, error)

GetNodeByMachineKey finds a Node by its MachineKey and returns the Node struct.

func GetNodeByNodeKey added in v0.25.0

func GetNodeByNodeKey(
	tx *gorm.DB,
	nodeKey key.NodePublic,
) (*types.Node, error)

GetNodeByNodeKey finds a Node by its NodeKey and returns the Node struct.

func GetNodePrimaryRoutes

func GetNodePrimaryRoutes(tx *gorm.DB, node *types.Node) (types.Routes, error)

getNodePrimaryRoutes returns the routes that are enabled and marked as primary (for subnet failover) Exit nodes are not considered for this, as they are never marked as Primary.

func GetNodeRoutes

func GetNodeRoutes(tx *gorm.DB, node *types.Node) (types.Routes, error)

func GetPreAuthKey

func GetPreAuthKey(tx *gorm.DB, key string) (*types.PreAuthKey, error)

GetPreAuthKey returns a PreAuthKey for a given key. The caller is responsible for checking if the key is usable (expired or used).

func GetRoute

func GetRoute(tx *gorm.DB, id uint64) (*types.Route, error)

func GetRoutes

func GetRoutes(tx *gorm.DB) (types.Routes, error)

func GetUserByID added in v0.24.0

func GetUserByID(tx *gorm.DB, uid types.UserID) (*types.User, error)

func GetUserByOIDCIdentifier added in v0.24.0

func GetUserByOIDCIdentifier(tx *gorm.DB, id string) (*types.User, error)

func IsRoutesEnabled

func IsRoutesEnabled(tx *gorm.DB, node *types.Node, routeStr string) bool

func ListNodes

func ListNodes(tx *gorm.DB) (types.Nodes, error)

func ListNodesByUser

func ListNodesByUser(tx *gorm.DB, uid types.UserID) (types.Nodes, error)

ListNodesByUser gets all the nodes in a given user.

func ListPeers

func ListPeers(tx *gorm.DB, nodeID types.NodeID) (types.Nodes, error)

ListPeers returns all peers of node, regardless of any Policy or if the node is expired.

func ListPreAuthKeysByUser added in v0.24.0

func ListPreAuthKeysByUser(tx *gorm.DB, uid types.UserID) ([]types.PreAuthKey, error)

ListPreAuthKeysByUser returns the list of PreAuthKeys for a user.

func ListUsers

func ListUsers(tx *gorm.DB, where ...*types.User) ([]types.User, error)

ListUsers gets all the existing users.

func NodeSave

func NodeSave(tx *gorm.DB, node *types.Node) error

NodeSave saves a node object to the database, prefer to use a specific save method rather than this. It is intended to be used when we are changing or. TODO(kradalby): Remove this func, just use Save.

func NodeSetExpiry

func NodeSetExpiry(tx *gorm.DB,
	nodeID types.NodeID, expiry time.Time,
) error

NodeSetExpiry takes a Node struct and a new expiry time.

func NodeSetMachineKey

func NodeSetMachineKey(
	tx *gorm.DB,
	node *types.Node,
	machineKey key.MachinePublic,
) error

NodeSetMachineKey sets the node key of a node and saves it to the database.

func NodeSetNodeKey

func NodeSetNodeKey(tx *gorm.DB, node *types.Node, nodeKey key.NodePublic) error

NodeSetNodeKey sets the node key of a node and saves it to the database.

func Read

func Read[T any](db *gorm.DB, fn func(rx *gorm.DB) (T, error)) (T, error)

func RegisterNode

func RegisterNode(tx *gorm.DB, node types.Node, ipv4 *netip.Addr, ipv6 *netip.Addr) (*types.Node, error)

RegisterNode is executed from the CLI to register a new Node using its MachineKey.

func RenameNode

func RenameNode(tx *gorm.DB,
	nodeID types.NodeID, newName string,
) error

RenameNode takes a Node struct and a new GivenName for the nodes and renames it. If the name is not unique, it will return an error.

func RenameUser

func RenameUser(tx *gorm.DB, uid types.UserID, newName string) error

RenameUser renames a User. Returns error if the User does not exist or if another User exists with the new name.

func SaveNodeRoutes

func SaveNodeRoutes(tx *gorm.DB, node *types.Node) (bool, error)

SaveNodeRoutes takes a node and updates the database with the new routes. It returns a bool whether an update should be sent as the saved route impacts nodes.

func SetLastSeen

func SetLastSeen(tx *gorm.DB, nodeID types.NodeID, lastSeen time.Time) error

SetLastSeen sets a node's last seen field indicating that we have recently communicating with this node.

func SetTags

func SetTags(
	tx *gorm.DB,
	nodeID types.NodeID,
	tags []string,
) error

SetTags takes a Node struct pointer and update the forced tags.

func UsePreAuthKey

func UsePreAuthKey(tx *gorm.DB, k *types.PreAuthKey) error

UsePreAuthKey marks a PreAuthKey as used.

func Write

func Write[T any](db *gorm.DB, fn func(tx *gorm.DB) (T, error)) (T, error)

Types

type EphemeralGarbageCollector

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

EphemeralGarbageCollector is a garbage collector that will delete nodes after a certain amount of time. It is used to delete ephemeral nodes that have disconnected and should be cleaned up.

func NewEphemeralGarbageCollector

func NewEphemeralGarbageCollector(deleteFunc func(types.NodeID)) *EphemeralGarbageCollector

NewEphemeralGarbageCollector creates a new EphemeralGarbageCollector, it takes a deleteFunc that will be called when a node is scheduled for deletion.

func (*EphemeralGarbageCollector) Cancel

func (e *EphemeralGarbageCollector) Cancel(nodeID types.NodeID)

Cancel cancels the deletion of a node.

func (*EphemeralGarbageCollector) Close

func (e *EphemeralGarbageCollector) Close()

Close stops the garbage collector.

func (*EphemeralGarbageCollector) Schedule

func (e *EphemeralGarbageCollector) Schedule(nodeID types.NodeID, expiry time.Duration)

Schedule schedules a node for deletion after the expiry duration.

func (*EphemeralGarbageCollector) Start

func (e *EphemeralGarbageCollector) Start()

Start starts the garbage collector.

type HSDatabase

type HSDatabase struct {
	DB *gorm.DB
	// contains filtered or unexported fields
}

func NewHeadscaleDatabase

func NewHeadscaleDatabase(
	cfg types.DatabaseConfig,
	baseDomain string,
	regCache *zcache.Cache[types.RegistrationID, types.RegisterNode],
) (*HSDatabase, error)

TODO(kradalby): assemble this struct from toptions or something typed rather than arguments.

func (*HSDatabase) AssignNodeToUser

func (hsdb *HSDatabase) AssignNodeToUser(node *types.Node, uid types.UserID) error

func (*HSDatabase) BackfillNodeIPs

func (db *HSDatabase) BackfillNodeIPs(i *IPAllocator) ([]string, error)

BackfillNodeIPs will take a database transaction, and iterate through all of the current nodes in headscale and ensure it has IP addresses according to the current configuration. This means that if both IPv4 and IPv6 is set in the config, and some nodes are missing that type of IP, it will be added. If a prefix type has been removed (IPv4 or IPv6), it will remove the IPs in that family from the node.

func (*HSDatabase) Close

func (hsdb *HSDatabase) Close() error

func (*HSDatabase) CreateAPIKey

func (hsdb *HSDatabase) CreateAPIKey(
	expiration *time.Time,
) (string, *types.APIKey, error)

CreateAPIKey creates a new ApiKey in a user, and returns it.

func (*HSDatabase) CreatePreAuthKey

func (hsdb *HSDatabase) CreatePreAuthKey(
	uid types.UserID,
	reusable bool,
	ephemeral bool,
	expiration *time.Time,
	aclTags []string,
) (*types.PreAuthKey, error)

func (*HSDatabase) CreateUser

func (hsdb *HSDatabase) CreateUser(user types.User) (*types.User, error)

func (*HSDatabase) DeleteEphemeralNode

func (hsdb *HSDatabase) DeleteEphemeralNode(
	nodeID types.NodeID,
) error

DeleteEphemeralNode deletes a Node from the database, note that this method will remove it straight, and not notify any changes or consider any routes. It is intended for Ephemeral nodes.

func (*HSDatabase) DeleteNode

func (hsdb *HSDatabase) DeleteNode(node *types.Node, isLikelyConnected *xsync.MapOf[types.NodeID, bool]) ([]types.NodeID, error)

func (*HSDatabase) DeleteRoute

func (hsdb *HSDatabase) DeleteRoute(
	id uint64,
	isLikelyConnected *xsync.MapOf[types.NodeID, bool],
) ([]types.NodeID, error)

func (*HSDatabase) DestroyAPIKey

func (hsdb *HSDatabase) DestroyAPIKey(key types.APIKey) error

DestroyAPIKey destroys a ApiKey. Returns error if the ApiKey does not exist.

func (*HSDatabase) DestroyUser

func (hsdb *HSDatabase) DestroyUser(uid types.UserID) error

func (*HSDatabase) EnableAutoApprovedRoutes

func (hsdb *HSDatabase) EnableAutoApprovedRoutes(
	polMan policy.PolicyManager,
	node *types.Node,
) error

func (*HSDatabase) ExpireAPIKey

func (hsdb *HSDatabase) ExpireAPIKey(key *types.APIKey) error

ExpireAPIKey marks a ApiKey as expired.

func (*HSDatabase) ExpirePreAuthKey

func (hsdb *HSDatabase) ExpirePreAuthKey(k *types.PreAuthKey) error

func (*HSDatabase) GetAPIKey

func (hsdb *HSDatabase) GetAPIKey(prefix string) (*types.APIKey, error)

GetAPIKey returns a ApiKey for a given key.

func (*HSDatabase) GetAPIKeyByID

func (hsdb *HSDatabase) GetAPIKeyByID(id uint64) (*types.APIKey, error)

GetAPIKeyByID returns a ApiKey for a given id.

func (*HSDatabase) GetAdvertisedRoutes

func (hsdb *HSDatabase) GetAdvertisedRoutes(node *types.Node) ([]netip.Prefix, error)

func (*HSDatabase) GetEnabledRoutes

func (hsdb *HSDatabase) GetEnabledRoutes(node *types.Node) ([]netip.Prefix, error)

func (*HSDatabase) GetNodeByID

func (hsdb *HSDatabase) GetNodeByID(id types.NodeID) (*types.Node, error)

func (*HSDatabase) GetNodeByMachineKey

func (hsdb *HSDatabase) GetNodeByMachineKey(machineKey key.MachinePublic) (*types.Node, error)

func (*HSDatabase) GetNodeByNodeKey added in v0.25.0

func (hsdb *HSDatabase) GetNodeByNodeKey(nodeKey key.NodePublic) (*types.Node, error)

func (*HSDatabase) GetNodePrimaryRoutes

func (hsdb *HSDatabase) GetNodePrimaryRoutes(node *types.Node) (types.Routes, error)

func (*HSDatabase) GetNodeRoutes

func (hsdb *HSDatabase) GetNodeRoutes(node *types.Node) (types.Routes, error)

func (*HSDatabase) GetPolicy

func (hsdb *HSDatabase) GetPolicy() (*types.Policy, error)

GetPolicy returns the latest policy in the database.

func (*HSDatabase) GetPreAuthKey added in v0.25.0

func (hsdb *HSDatabase) GetPreAuthKey(key string) (*types.PreAuthKey, error)

func (*HSDatabase) GetUserByID added in v0.24.0

func (hsdb *HSDatabase) GetUserByID(uid types.UserID) (*types.User, error)

func (*HSDatabase) GetUserByName added in v0.24.0

func (hsdb *HSDatabase) GetUserByName(name string) (*types.User, error)

GetUserByName returns a user if the provided username is unique, and otherwise an error.

func (*HSDatabase) GetUserByOIDCIdentifier added in v0.24.0

func (hsdb *HSDatabase) GetUserByOIDCIdentifier(id string) (*types.User, error)

func (*HSDatabase) HandleNodeFromAuthPath added in v0.25.0

func (hsdb *HSDatabase) HandleNodeFromAuthPath(
	registrationID types.RegistrationID,
	userID types.UserID,
	nodeExpiry *time.Time,
	registrationMethod string,
	ipv4 *netip.Addr,
	ipv6 *netip.Addr,
) (*types.Node, bool, error)

HandleNodeFromAuthPath is called from the OIDC or CLI auth path with a registrationID to register or reauthenticate a node. If the node found in the registration cache is not already registered, it will be registered with the user and the node will be removed from the cache. If the node is already registered, the expiry will be updated. The node, and a boolean indicating if it was a new node or not, will be returned.

func (*HSDatabase) ListAPIKeys

func (hsdb *HSDatabase) ListAPIKeys() ([]types.APIKey, error)

ListAPIKeys returns the list of ApiKeys for a user.

func (*HSDatabase) ListEphemeralNodes

func (hsdb *HSDatabase) ListEphemeralNodes() (types.Nodes, error)

func (*HSDatabase) ListNodes

func (hsdb *HSDatabase) ListNodes() (types.Nodes, error)

func (*HSDatabase) ListPeers

func (hsdb *HSDatabase) ListPeers(nodeID types.NodeID) (types.Nodes, error)

func (*HSDatabase) ListPreAuthKeys

func (hsdb *HSDatabase) ListPreAuthKeys(uid types.UserID) ([]types.PreAuthKey, error)

func (*HSDatabase) ListUsers

func (hsdb *HSDatabase) ListUsers(where ...*types.User) ([]types.User, error)

func (*HSDatabase) NodeSetExpiry

func (hsdb *HSDatabase) NodeSetExpiry(nodeID types.NodeID, expiry time.Time) error

func (*HSDatabase) NodeSetMachineKey

func (hsdb *HSDatabase) NodeSetMachineKey(
	node *types.Node,
	machineKey key.MachinePublic,
) error

func (*HSDatabase) PingDB

func (hsdb *HSDatabase) PingDB(ctx context.Context) error

func (*HSDatabase) Read

func (hsdb *HSDatabase) Read(fn func(rx *gorm.DB) error) error

func (*HSDatabase) RegisterNode

func (hsdb *HSDatabase) RegisterNode(node types.Node, ipv4 *netip.Addr, ipv6 *netip.Addr) (*types.Node, error)

func (*HSDatabase) RenameUser

func (hsdb *HSDatabase) RenameUser(uid types.UserID, newName string) error

func (*HSDatabase) SaveNodeRoutes

func (hsdb *HSDatabase) SaveNodeRoutes(node *types.Node) (bool, error)

func (*HSDatabase) SetPolicy

func (hsdb *HSDatabase) SetPolicy(policy string) (*types.Policy, error)

SetPolicy sets the policy in the database.

func (*HSDatabase) SetTags

func (hsdb *HSDatabase) SetTags(
	nodeID types.NodeID,
	tags []string,
) error

func (*HSDatabase) ValidateAPIKey

func (hsdb *HSDatabase) ValidateAPIKey(keyStr string) (bool, error)

func (*HSDatabase) Write

func (hsdb *HSDatabase) Write(fn func(tx *gorm.DB) error) error

type IPAllocator

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

IPAllocator is a singleton responsible for allocating IP addresses for nodes and making sure the same address is not handed out twice. There can only be one and it needs to be created before any other database writes occur.

func NewIPAllocator

func NewIPAllocator(
	db *HSDatabase,
	prefix4, prefix6 *netip.Prefix,
	strategy types.IPAllocationStrategy,
) (*IPAllocator, error)

NewIPAllocator returns a new IPAllocator singleton which can be used to hand out unique IP addresses within the provided IPv4 and IPv6 prefix. It needs to be created when headscale starts and needs to finish its read transaction before any writes to the database occur.

func (*IPAllocator) Next

func (i *IPAllocator) Next() (*netip.Addr, *netip.Addr, error)

type KV

type KV struct {
	Key   string
	Value string
}

KV is a key-value store in a psql table. For future use... TODO(kradalby): Is this used for anything?

type TextSerialiser added in v0.24.0

type TextSerialiser struct{}

TextSerialiser implements the Serialiser interface for fields that have a type that implements encoding.TextUnmarshaler.

func (TextSerialiser) Scan added in v0.24.0

func (TextSerialiser) Scan(ctx context.Context, field *schema.Field, dst reflect.Value, dbValue interface{}) (err error)

func (TextSerialiser) Value added in v0.24.0

func (TextSerialiser) Value(ctx context.Context, field *schema.Field, dst reflect.Value, fieldValue interface{}) (interface{}, error)

Jump to

Keyboard shortcuts

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