vip

package
v0.0.1-dev.137 Latest Latest
Warning

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

Go to latest
Published: Jul 11, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package vip implements the cluster VIP allocator.

Every Service in Rune gets a stable virtual IP for its lifetime. The allocator owns the cluster's CIDR, allocates IPs out of a free list, and returns IPs to the free list after a 60-second cooldown to drain stale clients.

The allocator is the single writer of the ClusterNetwork resource. All state changes flow through orderedlog.Propose, so a Raft-backed control plane will see the same state changes in the same order without code changes here. The allocator never touches Badger directly; the orderedlog seam lint enforces this.

Index

Constants

View Source
const (
	OpTypeBootstrapClusterNetwork = "vip.bootstrap"
	OpTypeAllocateVIP             = "vip.allocate"
	OpTypeReleaseVIP              = "vip.release"
)

Op type constants. Wire-stable: changing the string breaks replay of old persisted events.

Variables

View Source
var (
	// ErrCIDRExhausted is returned by Allocate when no IPs are free.
	ErrCIDRExhausted = errors.New("vip: cluster CIDR exhausted; expand --cluster-cidr or release unused services")

	// ErrAlreadyBootstrapped is returned by Bootstrap if the cluster
	// network already exists with a different CIDR.
	ErrAlreadyBootstrapped = errors.New("vip: cluster network already bootstrapped with a different CIDR; reset cluster to change")

	// ErrInvalidCIDR is returned for unparseable, non-IPv4, or
	// public-range CIDRs.
	ErrInvalidCIDR = errors.New("vip: invalid CIDR (must be a private IPv4 range)")

	// ErrCIDRCollision is returned by Bootstrap when the configured
	// CIDR overlaps an existing host route.
	ErrCIDRCollision = errors.New("vip: cluster CIDR overlaps an existing host route")

	// ErrServiceNotAllocated is returned by Release for a serviceID
	// with no current allocation.
	ErrServiceNotAllocated = errors.New("vip: service has no VIP allocation")
)

Sentinel errors.

View Source
var ReleaseCooldown = 60 * time.Second

ReleaseCooldown is how long an IP waits in the pending-release queue before returning to the free list. Exposed for tests.

Functions

This section is empty.

Types

type Allocator

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

Allocator owns the ClusterNetwork resource and the in-memory pending-release queue. Safe for concurrent use.

func New

func New(olog orderedlog.OrderedLog, opts Options) (*Allocator, error)

New constructs an Allocator backed by the given OrderedLog. It registers the allocator's Op types so subsequent Propose / Watch replay works. Call Bootstrap() exactly once at startup.

func (*Allocator) Allocate

func (a *Allocator) Allocate(ctx context.Context, serviceID string) (net.IP, error)

Allocate returns the (possibly already-allocated) VIP for serviceID. Calls are idempotent: a second Allocate for the same serviceID returns the existing IP without touching the free list.

func (*Allocator) Bootstrap

func (a *Allocator) Bootstrap(ctx context.Context) error

Bootstrap ensures the cluster network exists. If it does not, the allocator validates the configured CIDR (private range + no host route collision unless SkipRouteCheck) and Proposes a BootstrapClusterNetwork op. Idempotent: re-running with the same CIDR is a no-op; running with a different CIDR returns ErrAlreadyBootstrapped.

Bootstrap also starts the background release-cooldown worker.

func (*Allocator) Close

func (a *Allocator) Close() error

Close stops the background worker. The OrderedLog is owned by the caller and is NOT closed here.

func (*Allocator) Release

func (a *Allocator) Release(serviceID string) error

Release schedules the VIP for serviceID to return to the free list after the ReleaseCooldown elapses. Returns immediately; ErrServiceNotAllocated if the service has no allocation.

The actual free-list update is performed by the background worker which Proposes a ReleaseVIP op once the cooldown window passes. This keeps Release synchronous-feeling for callers without blocking shutdown.

func (*Allocator) Status

func (a *Allocator) Status() (types.ClusterNetwork, int)

Status returns a copy of the current ClusterNetwork plus the count of pending-release IPs (not yet returned to the free list).

type Options

type Options struct {
	// CIDR is the desired service CIDR at bootstrap. Ignored once the
	// cluster is bootstrapped (the persisted CIDR wins).
	CIDR string

	// SkipRouteCheck disables the netlink CIDR-collision check at
	// Bootstrap. Used in tests and on platforms without netlink.
	SkipRouteCheck bool

	Logger log.Logger
}

Options configure an Allocator.

Jump to

Keyboard shortcuts

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