Help us shape the future of Go! Take the 2026 Go Developer Survey

config

package
v0.15.0 Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2026 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ChecksPolicyAll = "all" // every check healthy (AND)
	ChecksPolicyAny = "any" // at least one check healthy (OR)
)

Checks policies: how several checks combine into the VIP health. Any other value is a boolean expression over the check names (see CompileChecksPolicy).

View Source
const (
	CheckTypeHTTP = "http"
	CheckTypeDNS  = "dns"
	CheckTypePing = "ping"
	CheckTypeUDP  = "udp"
	CheckTypeTCP  = "tcp"
	CheckTypeGRPC = "grpc"
	// CheckTypeListen passes when a local socket is bound to a port, without
	// sending anything.
	CheckTypeListen = "listen"
	// CheckTypeSQL runs queries against MySQL/MariaDB or PostgreSQL.
	CheckTypeSQL = "sql"
	// CheckTypeKafka asks a Kafka broker for cluster metadata.
	CheckTypeKafka = "kafka"
)

Check type constants.

View Source
const (
	KafkaSASLPlain       = "plain"
	KafkaSASLScramSHA256 = "scram-sha-256"
	KafkaSASLScramSHA512 = "scram-sha-512"
)

SASL mechanisms accepted by KafkaSASLConfig.Mechanism.

View Source
const (
	SQLDriverMySQL    = "mysql"
	SQLDriverPostgres = "postgres"
)

SQL drivers accepted by SQLCheckConfig.Driver.

View Source
const DefaultGoBGPAPIListen = "127.0.0.1:50051"

DefaultGoBGPAPIListen is the default gRPC listen address for the embedded GoBGP API.

Variables

This section is empty.

Functions

func ApplyDefaults

func ApplyDefaults(cfg *Config)

ApplyDefaults fills in zero-value fields with sensible defaults.

func RestartRequired added in v0.14.0

func RestartRequired(running, candidate *Config) []string

RestartRequired lists the config sections that differ between the running config and a candidate and cannot change at runtime. Only vips and logging.level reload live; everything else needs a restart, and a reload that touches it is rejected as a whole.

func Validate

func Validate(cfg *Config) []error

Validate checks the config for structural and semantic correctness. Returns a slice of errors — empty means valid.

func ValidateCheckName added in v0.12.0

func ValidateCheckName(name string) error

ValidateCheckName reports why name cannot be used as a check name.

Types

type APIConfig

type APIConfig struct {
	// Listen address for the HTTP API (e.g. ":59179" or "127.0.0.1:59179"). Default: :59179.
	// The API has no authentication; prefer a loopback or host-local address.
	Listen string `yaml:"listen" json:"listen" toml:"listen" jsonschema:"required"`
	// Maximum time to read a request's headers. 0 disables. Default: 10s.
	ReadHeaderTimeout *Duration `yaml:"read_header_timeout" json:"read_header_timeout" toml:"read_header_timeout" jsonschema:"default=10s"`
	// Maximum time to read a whole request (headers and body). 0 disables. Default: 30s.
	ReadTimeout *Duration `yaml:"read_timeout" json:"read_timeout" toml:"read_timeout" jsonschema:"default=30s"`
	// Maximum time to write a response, counted from the end of header read. Must cover
	// the slowest ad-hoc check (check.timeout) and the /metrics scrape. 0 disables. Default: 60s.
	WriteTimeout *Duration `yaml:"write_timeout" json:"write_timeout" toml:"write_timeout" jsonschema:"default=60s"`
	// Maximum time an idle keep-alive connection stays open. 0 disables. Default: 120s.
	IdleTimeout *Duration `yaml:"idle_timeout" json:"idle_timeout" toml:"idle_timeout" jsonschema:"default=120s"`
}

APIConfig configures the HTTP API server.

type AnnounceConfig added in v0.11.0

type AnnounceConfig struct {
	// Number of times to prepend the local ASN to the AS_PATH while the VIP is healthy. Added to lower_priority.as_path_prepend when pessimized. Only effective over eBGP (prepends are not applied to iBGP peers). Default: 0.
	ASPathPrepend *int `yaml:"as_path_prepend" json:"as_path_prepend" toml:"as_path_prepend" jsonschema:"minimum=0,maximum=16,default=0"`
	// BGP communities attached to every announcement of this VIP (e.g. "65535:100"). Merged with lower_priority.communities when pessimized.
	Communities []string `yaml:"communities" json:"communities" toml:"communities"`
}

AnnounceConfig defines base BGP attributes applied to every announcement of a VIP. When the VIP is pessimized these are combined with LowerPriorityConfig: the prepend counts are added and the community lists are merged, so a degraded node always ranks below a healthy node that has a larger base prepend.

type BFDConfig added in v0.4.0

type BFDConfig struct {
	// Enable BFD for this peer. Default: false.
	Enabled bool `yaml:"enabled" json:"enabled" toml:"enabled" jsonschema:"default=false"`
	// UDP port for the BFD session. Default: 0 (BFD daemon default, typically 3784).
	Port uint32 `yaml:"port,omitempty" json:"port,omitempty" toml:"port,omitempty" jsonschema:"minimum=1,maximum=65535"`
	// Desired minimum BFD transmit interval in microseconds. Default: 0 (BFD daemon default).
	DesiredMinimumTxInterval uint32 `` /* 157-byte string literal not displayed */
	// Required minimum BFD receive interval in microseconds. Default: 0 (BFD daemon default).
	RequiredMinimumReceive uint32 `` /* 148-byte string literal not displayed */
	// BFD detection time multiplier. Default: 0 (BFD daemon default, typically 3).
	DetectionMultiplier uint32 `` /* 136-byte string literal not displayed */
}

BFDConfig configures Bidirectional Forwarding Detection for a BGP peer. BFD provides rapid link-failure detection independent of BGP hold timers. All interval fields are in microseconds (µs); 0 means use the GoBGP/BFD daemon default.

type BGPConfig

type BGPConfig struct {
	// Enable BGP graceful restart.
	GracefulRestart *bool `yaml:"graceful_restart" json:"graceful_restart" toml:"graceful_restart"`
	// BGP hold time. Default: 90s.
	HoldTime *Duration `yaml:"hold_time" json:"hold_time" toml:"hold_time"`
	// BGP keepalive interval. Default: 30s.
	KeepaliveTime *Duration `yaml:"keepalive_time" json:"keepalive_time" toml:"keepalive_time"`
	// Local address to listen for inbound BGP TCP sessions. If empty, falls back to router.local_address, then 0.0.0.0.
	ListenAddress string `yaml:"listen_address" json:"listen_address" toml:"listen_address"`
	// TCP port to listen on for inbound BGP TCP sessions. Default: 179. Set to -1 to disable BGP listening entirely.
	ListenPort int `yaml:"listen_port" json:"listen_port" toml:"listen_port" jsonschema:"minimum=-1,maximum=65535"`
	// Embedded GoBGP gRPC API configuration (used by gobgp CLI for debugging).
	GoBGPAPI GoBGPAPIConfig `yaml:"gobgp_api,omitempty" json:"gobgp_api,omitempty" toml:"gobgp_api,omitempty"`
	// List of BGP neighbors (peers) to establish sessions with.
	Neighbors []NeighborConfig `yaml:"neighbors" json:"neighbors" toml:"neighbors" jsonschema:"required,minItems=1"`
}

BGPConfig defines global BGP parameters and neighbors.

type CheckConfig

type CheckConfig struct {
	// Name of this check in logs, metrics (check label), /status and checks_policy
	// expressions. Letters, digits and underscores, not starting with a digit. Defaults to
	// the check type; required when a VIP has several checks of the same type.
	Name string `yaml:"name,omitempty" json:"name,omitempty" toml:"name,omitempty" jsonschema:"pattern=^[A-Za-z_][A-Za-z0-9_]*$"`
	// Health check backend type.
	Type string `` /* 146-byte string literal not displayed */
	// Export check-type-specific metrics for this VIP (ping RTT histogram and packet loss,
	// HTTP status code and TLS certificate expiry, DNS rcode and answer count per name,
	// gRPC status code). Off by default to keep the metric set small.
	DetailedMetrics bool `yaml:"detailed_metrics" json:"detailed_metrics" toml:"detailed_metrics" jsonschema:"default=false"`
	// Interval between consecutive health checks. Default: 1s.
	Interval *Duration `yaml:"interval" json:"interval" toml:"interval" jsonschema:"default=1s"`
	// Maximum time to wait for a check to complete; must be less than interval. Default: 100ms.
	Timeout *Duration `yaml:"timeout" json:"timeout" toml:"timeout" jsonschema:"default=100ms"`
	// Number of consecutive successes required to mark healthy (HAProxy-style). Default: 1.
	Rise *int `yaml:"rise" json:"rise" toml:"rise" jsonschema:"minimum=1,default=1"`
	// Number of consecutive failures required to mark unhealthy (HAProxy-style). Default: 3.
	Fall *int `yaml:"fall" json:"fall" toml:"fall" jsonschema:"minimum=1,default=3"`
	// HTTP check configuration (required when type is "http").
	HTTP *HTTPCheckConfig `yaml:"http,omitempty" json:"http,omitempty" toml:"http,omitempty"`
	// DNS check configuration (required when type is "dns").
	DNS *DNSCheckConfig `yaml:"dns,omitempty" json:"dns,omitempty" toml:"dns,omitempty"`
	// Ping (ICMP) check configuration (required when type is "ping").
	Ping *PingCheckConfig `yaml:"ping,omitempty" json:"ping,omitempty" toml:"ping,omitempty"`
	// UDP check configuration (required when type is "udp").
	UDP *UDPCheckConfig `yaml:"udp,omitempty" json:"udp,omitempty" toml:"udp,omitempty"`
	// TCP check configuration (required when type is "tcp").
	TCP *TCPCheckConfig `yaml:"tcp,omitempty" json:"tcp,omitempty" toml:"tcp,omitempty"`
	// Listening-socket check configuration (required when type is "listen").
	Listen *ListenCheckConfig `yaml:"listen,omitempty" json:"listen,omitempty" toml:"listen,omitempty"`
	// SQL check configuration (required when type is "sql").
	SQL *SQLCheckConfig `yaml:"sql,omitempty" json:"sql,omitempty" toml:"sql,omitempty"`
	// Kafka check configuration (required when type is "kafka").
	Kafka *KafkaCheckConfig `yaml:"kafka,omitempty" json:"kafka,omitempty" toml:"kafka,omitempty"`
	// gRPC check configuration (required when type is "grpc").
	GRPC *GRPCCheckConfig `yaml:"grpc,omitempty" json:"grpc,omitempty" toml:"grpc,omitempty"`
}

CheckConfig defines health check type, scheduling, and type-specific parameters.

func (*CheckConfig) EffectiveName added in v0.12.0

func (c *CheckConfig) EffectiveName() string

EffectiveName returns the check name, defaulting to the check type.

type ChecksEvaluator added in v0.12.0

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

ChecksEvaluator folds per-check health into one VIP health.

func CompileChecksPolicy added in v0.12.0

func CompileChecksPolicy(policy string, names []string) (*ChecksEvaluator, error)

CompileChecksPolicy builds the evaluator for a checks_policy value given the VIP's check names. "all" and "any" are shortcuts; anything else is an expr-lang boolean expression (https://expr-lang.org) in which every check name is a boolean variable, e.g. "web || (dns && ping)". Unknown names and non-boolean results are rejected at compile time.

func (*ChecksEvaluator) Eval added in v0.12.0

func (e *ChecksEvaluator) Eval(healthy map[string]bool) bool

Eval returns the combined health for the given per-check health. Checks missing from healthy count as unhealthy.

func (*ChecksEvaluator) Policy added in v0.12.0

func (e *ChecksEvaluator) Policy() string

Policy returns the policy string the evaluator was compiled from.

type Config

type Config struct {
	// Configuration schema version identifier.
	Schema string `yaml:"schema" json:"schema" toml:"schema" jsonschema:"required,enum=v1"`
	// BGP router identity and addressing.
	Router RouterConfig `yaml:"router" json:"router" toml:"router" jsonschema:"required"`
	// HTTP API server configuration (healthz, metrics, status).
	API APIConfig `yaml:"api" json:"api" toml:"api" jsonschema:"required"`
	// Structured logging configuration.
	Logging LoggingConfig `yaml:"logging" json:"logging" toml:"logging"`
	// OpenTelemetry export configuration (traces, metrics, logs). Disabled when endpoint is empty.
	OTel OTelConfig `yaml:"otel" json:"otel" toml:"otel"`
	// Locations of kernel filesystems, for checks that read them.
	Paths PathsConfig `yaml:"paths,omitempty" json:"paths,omitempty" toml:"paths,omitempty"`
	// BGP session parameters and neighbor definitions.
	BGP BGPConfig `yaml:"bgp" json:"bgp" toml:"bgp" jsonschema:"required"`
	// List of Virtual IPs to announce via BGP, each with a health check.
	VIPs []VIPConfig `yaml:"vips" json:"vips" toml:"vips" jsonschema:"required,minItems=1"`
}

Config is the top-level configuration for pathosd.

func Load

func Load(path string) (*Config, error)

Load reads a config file, detects format by extension, parses, applies defaults, and validates.

func LoadRaw added in v0.14.0

func LoadRaw(path string) (*Config, []byte, error)

LoadRaw is Load that also returns the file's bytes as read, before placeholder expansion, so a caller can tell whether the file changed.

func Parse

func Parse(data []byte, format string) (*Config, error)

Parse decodes raw bytes into Config using the specified format. Does not apply defaults or validate.

type DNSCheckConfig

type DNSCheckConfig struct {
	// DNS names to query. All must resolve successfully for the check to pass.
	Names []string `yaml:"names" json:"names" toml:"names" jsonschema:"required,minItems=1"`
	// DNS resolver address (ip or ip:port). Defaults to VIP prefix IP.
	Resolver string `yaml:"resolver" json:"resolver" toml:"resolver"`
	// DNS resolver port (used when resolver is an IP without port). Default: 53.
	Port uint16 `yaml:"port" json:"port" toml:"port"`
	// DNS query type. Default: A.
	QueryType string `` /* 156-byte string literal not displayed */
}

DNSCheckConfig defines a DNS health check.

type Duration

type Duration struct {
	time.Duration
}

Duration wraps time.Duration for JSON and TOML unmarshaling from strings like "1s", "500ms". goccy/go-yaml handles time.Duration natively, so no YAML methods are needed. TOML uses TextUnmarshaler; JSON stdlib needs explicit marshal/unmarshal.

func (Duration) MarshalJSON

func (d Duration) MarshalJSON() ([]byte, error)

func (Duration) MarshalText

func (d Duration) MarshalText() ([]byte, error)

func (*Duration) UnmarshalJSON

func (d *Duration) UnmarshalJSON(b []byte) error

func (*Duration) UnmarshalText

func (d *Duration) UnmarshalText(text []byte) error

type GRPCCheckConfig added in v0.5.0

type GRPCCheckConfig struct {
	// Host to connect to. Defaults to VIP prefix IP for /32 or /128.
	Host string `yaml:"host" json:"host" toml:"host"`
	// Port to connect to. Required.
	Port uint16 `yaml:"port" json:"port" toml:"port" jsonschema:"required,minimum=1,maximum=65535"`
	// Enable TLS transport. Default: false (plaintext).
	TLS bool `yaml:"tls" json:"tls" toml:"tls" jsonschema:"default=false"`
	// Skip TLS certificate verification. Requires tls=true. Mutually exclusive with tls_ca_cert.
	TLSInsecure bool `yaml:"tls_insecure" json:"tls_insecure" toml:"tls_insecure" jsonschema:"default=false"`
	// Path to a PEM-encoded CA certificate file for TLS verification. Requires tls=true.
	// Mutually exclusive with tls_insecure.
	TLSCACert string `yaml:"tls_ca_cert" json:"tls_ca_cert" toml:"tls_ca_cert"`
	// TLS SNI server name used during the handshake and for certificate verification.
	// Requires tls=true. Defaults to the connect host.
	TLSServerName string `yaml:"tls_server_name" json:"tls_server_name" toml:"tls_server_name"`
	// Full gRPC method path to call, e.g. "myapp.v1.Greeter/Hello".
	// Leading slash is optional. When empty (default), the standard gRPC Health
	// Checking Protocol is used (grpc.health.v1.Health/Check).
	Method string `yaml:"method" json:"method" toml:"method"`
	// Service name passed in the HealthCheckRequest when using the standard health
	// protocol (method is empty). Empty string means server-wide health check.
	Service string `yaml:"service" json:"service" toml:"service"`
	// gRPC status codes considered a passing result. Only used when method is set;
	// the standard health protocol always requires SERVING.
	// Values are gRPC status code names (case-insensitive): OK, Canceled, Unknown,
	// InvalidArgument, DeadlineExceeded, NotFound, AlreadyExists, PermissionDenied,
	// ResourceExhausted, FailedPrecondition, Aborted, OutOfRange, Unimplemented,
	// Internal, Unavailable, DataLoss, Unauthenticated. Default: ["OK"].
	OKCodes []string `yaml:"ok_codes" json:"ok_codes" toml:"ok_codes"`
	// Additional gRPC metadata sent with each call (analogous to HTTP headers).
	Metadata map[string]string `yaml:"metadata" json:"metadata" toml:"metadata"`
}

GRPCCheckConfig defines a gRPC health check. When method is empty the standard gRPC Health Checking Protocol is used (grpc.health.v1.Health/Check). When method is set, that unary RPC is called with an empty proto3 request and the response gRPC status code is checked against ok_codes — similar to how the HTTP checker validates response_codes.

type GoBGPAPIConfig added in v0.2.0

type GoBGPAPIConfig struct {
	// Enable embedded GoBGP gRPC API server. Default: false.
	Enabled bool `yaml:"enabled" json:"enabled" toml:"enabled" jsonschema:"default=false"`
	// gRPC listen address used when enabled. Supports host:port or unix:///path. Default: 127.0.0.1:50051.
	Listen string `yaml:"listen,omitempty" json:"listen,omitempty" toml:"listen,omitempty"`
}

GoBGPAPIConfig configures the embedded GoBGP gRPC API.

type HTTPCheckConfig

type HTTPCheckConfig struct {
	// URL to check. Can be a full URL (https://example.com/healthz) or a path (/healthz). When a full URL is given, proto and Host header are derived from it. Default: /.
	URL string `yaml:"url" json:"url" toml:"url" jsonschema:"default=/"`
	// Protocol override. Derived from full URL if not set. Default: http.
	Proto string `yaml:"proto" json:"proto" toml:"proto" jsonschema:"enum=http,enum=https"`
	// Host to connect to and send in the Host header. Defaults to VIP prefix IP for /32 or /128 prefixes.
	Host string `yaml:"host" json:"host" toml:"host"`
	// Port override. Defaults to 80 for http, 443 for https.
	Port uint16 `yaml:"port" json:"port" toml:"port"`
	// HTTP method. Default: GET.
	Method string `yaml:"method" json:"method" toml:"method" jsonschema:"enum=GET,enum=HEAD,default=GET"`
	// List of acceptable HTTP response status codes. Default: [200].
	ResponseCodes []int `yaml:"response_codes" json:"response_codes" toml:"response_codes"`
	// Exact string that must be present in the response body.
	ResponseText string `yaml:"response_text" json:"response_text" toml:"response_text"`
	// Regular expression that must match the response body.
	ResponseRegex string `yaml:"response_regex" json:"response_regex" toml:"response_regex"`
	// JQ expression evaluated against the JSON response body; check passes when the result is "true".
	ResponseJQ string `yaml:"response_jq" json:"response_jq" toml:"response_jq"`
	// Skip TLS certificate verification. Mutually exclusive with tls_ca_cert.
	TLSInsecure bool `yaml:"tls_insecure" json:"tls_insecure" toml:"tls_insecure"`
	// Path to a PEM-encoded CA certificate file for TLS verification. Mutually exclusive with tls_insecure.
	TLSCACert string `yaml:"tls_ca_cert" json:"tls_ca_cert" toml:"tls_ca_cert"`
	// TLS SNI server name sent during the handshake and used for certificate verification.
	// Auto-defaults to the URL hostname for HTTPS checks when the connect host (host field)
	// differs from the URL hostname — covers bare-IP VIPs and k8s Service names alike.
	// Set explicitly to override.
	TLSServerName string `yaml:"tls_server_name" json:"tls_server_name" toml:"tls_server_name"`
	// Forward HTTP(S) proxy URL (e.g. http://proxy.example:3128) to route the check through.
	// The check target is a regular URL the proxy resolves and fetches; the origin host is
	// derived from the url field, not from the VIP. user:pass@ in the proxy URL is supported
	// and sent as Proxy-Authorization. Mutually incompatible with tls_server_name-driven
	// connect-to-VIP semantics. Requires url to be a full URL.
	Proxy string `yaml:"proxy" json:"proxy" toml:"proxy"`
	// Additional HTTP headers to send with the check request.
	Headers map[string]string `yaml:"headers" json:"headers" toml:"headers"`
	// Reuse the TCP/TLS connection across checks (HTTP keep-alive). Off by default so
	// every check exercises a full connect and TLS handshake, including certificate
	// verification. Enable for fast intervals where handshake cost matters; note the
	// certificate is then only re-verified when the idle connection is dropped.
	KeepAlive bool `yaml:"keep_alive" json:"keep_alive" toml:"keep_alive" jsonschema:"default=false"`
}

HTTPCheckConfig defines an HTTP health check.

type KafkaCheckConfig added in v0.13.0

type KafkaCheckConfig struct {
	// Broker host (IP or DNS name). Defaults to the VIP prefix IP for /32 or /128.
	Host string `yaml:"host" json:"host" toml:"host"`
	// Broker port. Default: 9092.
	Port uint16 `yaml:"port" json:"port" toml:"port" jsonschema:"minimum=1,maximum=65535,default=9092"`
	// Client ID presented to the broker (visible in broker logs and quotas). Default: pathosd.
	ClientID string `yaml:"client_id,omitempty" json:"client_id,omitempty" toml:"client_id,omitempty" jsonschema:"default=pathosd"`
	// Enable TLS. Default: false (plaintext).
	TLS bool `yaml:"tls,omitempty" json:"tls,omitempty" toml:"tls,omitempty" jsonschema:"default=false"`
	// Skip certificate verification. Requires tls=true. Mutually exclusive with tls_ca_cert.
	TLSInsecure bool `yaml:"tls_insecure,omitempty" json:"tls_insecure,omitempty" toml:"tls_insecure,omitempty" jsonschema:"default=false"`
	// Path to a PEM-encoded CA certificate for verification. Requires tls=true.
	TLSCACert string `yaml:"tls_ca_cert,omitempty" json:"tls_ca_cert,omitempty" toml:"tls_ca_cert,omitempty"`
	// TLS server name for SNI and verification. Defaults to host.
	TLSServerName string `yaml:"tls_server_name,omitempty" json:"tls_server_name,omitempty" toml:"tls_server_name,omitempty"`
	// SASL authentication. Omit for an unauthenticated listener.
	SASL *KafkaSASLConfig `yaml:"sasl,omitempty" json:"sasl,omitempty" toml:"sasl,omitempty"`
	// Topic that must exist with a leader for every partition. Empty: only
	// broker metadata is requested (cheap on large clusters).
	Topic string `yaml:"topic,omitempty" json:"topic,omitempty" toml:"topic,omitempty"`
	// Minimum number of brokers the metadata must list. Default: 1.
	MinBrokers int `yaml:"min_brokers,omitempty" json:"min_brokers,omitempty" toml:"min_brokers,omitempty" jsonschema:"minimum=1,default=1"`
}

KafkaCheckConfig defines a check that connects to a Kafka broker (API version negotiation, optional TLS and SASL) and requests cluster metadata. It passes when the broker answers with at least min_brokers brokers and, if topic is set, that topic exists with a leader for every partition.

type KafkaSASLConfig added in v0.13.0

type KafkaSASLConfig struct {
	// Mechanism: plain, scram-sha-256 or scram-sha-512. Required.
	Mechanism string `yaml:"mechanism" json:"mechanism" toml:"mechanism" jsonschema:"required,enum=plain,enum=scram-sha-256,enum=scram-sha-512"`
	// User name. Required.
	User string `yaml:"user" json:"user" toml:"user" jsonschema:"required"`
	// Password; use an environment placeholder (%{KAFKA_PASSWORD}) rather than a literal.
	Password string `yaml:"password" json:"password" toml:"password" jsonschema:"required"`
}

KafkaSASLConfig holds SASL credentials for the Kafka check.

type ListenCheckConfig added in v0.13.0

type ListenCheckConfig struct {
	// Transport protocol of the socket: "tcp" or "udp". Required.
	Proto string `yaml:"proto" json:"proto" toml:"proto" jsonschema:"required,enum=tcp,enum=udp"`
	// Local port the socket must be bound to. Required.
	Port uint16 `yaml:"port" json:"port" toml:"port" jsonschema:"required,minimum=1,maximum=65535"`
	// Local address the socket must be bound to; a wildcard bind (0.0.0.0, ::)
	// also matches. Defaults to the VIP prefix IP for /32 or /128.
	Host string `yaml:"host" json:"host" toml:"host"`
	// Read the socket table of this process's network namespace (<procfs>/<pid>/net)
	// instead of pathosd's own. Use 1 with paths.procfs pointing at the host's /proc
	// to check host sockets from a container with its own network namespace.
	// Default: 0 (pathosd's namespace).
	NetnsPID int `yaml:"netns_pid,omitempty" json:"netns_pid,omitempty" toml:"netns_pid,omitempty" jsonschema:"minimum=0"`
	// Procfs is filled from paths.procfs by ApplyDefaults; not a config key.
	Procfs string `yaml:"-" json:"-" toml:"-" jsonschema:"-"`
}

ListenCheckConfig defines a check that passes when a socket on this host is bound to the port: a listening TCP socket or any bound UDP socket. It reads the kernel socket tables (/proc/net/tcp, udp and their v6 variants) and sends no traffic, so it suits services that log every stray datagram. It only sees the network namespace pathosd runs in (Linux only).

type LoggingConfig

type LoggingConfig struct {
	// Minimum log level.
	Level string `yaml:"level" json:"level" toml:"level" jsonschema:"enum=debug,enum=info,enum=warn,enum=error,default=info"`
	// Log output format.
	Format string `yaml:"format" json:"format" toml:"format" jsonschema:"enum=text,enum=json,default=text"`
	// Minimum log level for OTEL log export. Defaults to the console level when unset.
	// Set to a lower level than logging.level to send more detail to the OTEL receiver
	// while keeping the console output quieter (e.g. level: warn, otel_level: debug).
	OTelLevel string `` /* 138-byte string literal not displayed */
	// Prefix console log records with a timestamp. Default: false when stderr is the
	// systemd journal (journald stores its own timestamps), true otherwise.
	Timestamps *bool `yaml:"timestamps,omitempty" json:"timestamps,omitempty" toml:"timestamps,omitempty"`
}

LoggingConfig controls structured logging output.

type LowerPriorityConfig

type LowerPriorityConfig struct {
	// Number of additional times to prepend the local ASN to the AS_PATH when pessimized, on top of announce.as_path_prepend. Default: 6.
	ASPathPrepend *int `yaml:"as_path_prepend" json:"as_path_prepend" toml:"as_path_prepend" jsonschema:"minimum=1,maximum=16,default=6"`
	// BGP communities to attach to pessimized route announcements (e.g. "65535:666").
	Communities []string `yaml:"communities" json:"communities" toml:"communities"`
}

LowerPriorityConfig defines BGP attributes for pessimized announcements.

type NeighborConfig

type NeighborConfig struct {
	// Human-readable name for this peer (used in logs and metrics).
	Name string `yaml:"name" json:"name" toml:"name" jsonschema:"required"`
	// IPv4 or IPv6 address of the BGP peer.
	Address string `yaml:"address" json:"address" toml:"address" jsonschema:"required"`
	// Peer's Autonomous System Number.
	PeerASN uint32 `yaml:"peer_asn" json:"peer_asn" toml:"peer_asn" jsonschema:"required,minimum=1,maximum=4294967295"`
	// If true, all VIPs require this peer to be established. Default: false.
	Required *bool `yaml:"required" json:"required" toml:"required"`
	// TCP port for the BGP session. Default: 179.
	Port uint16 `yaml:"port" json:"port" toml:"port"`
	// Local source address for active peering with this neighbor. If empty, falls back to router.local_address.
	LocalAddress string `yaml:"local_address" json:"local_address" toml:"local_address"`
	// Wait for the peer to initiate the connection instead of connecting actively.
	Passive bool `yaml:"passive" json:"passive" toml:"passive"`
	// Enable eBGP multihop — required when the peer is not directly connected (e.g. loopback-based sessions).
	EnableMultihop bool `yaml:"enable_multihop" json:"enable_multihop" toml:"enable_multihop"`
	// IP TTL for eBGP multihop sessions. 0 means use GoBGP default (255). Must be >= 2 when set explicitly. Only used when enable_multihop is true.
	MultihopTTL uint32 `yaml:"multihop_ttl" json:"multihop_ttl" toml:"multihop_ttl" jsonschema:"minimum=0,maximum=255"`
	// BFD configuration for this peer. Requires a BFD daemon (e.g. FRR) running on the host.
	BFD *BFDConfig `yaml:"bfd,omitempty" json:"bfd,omitempty" toml:"bfd,omitempty"`
	// TCP MD5 signature password (RFC 2385) shared with this peer. The kernel signs and
	// verifies every segment of the session, so a mismatch or a third host cannot open,
	// hijack or reset it. Keep the secret out of the file with a %{ENV_VAR} placeholder.
	// Linux limits the key to 80 bytes. Note: the embedded GoBGP gRPC API returns it in
	// peer configuration, so keep that API on a local socket.
	AuthPassword string `yaml:"auth_password,omitempty" json:"auth_password,omitempty" toml:"auth_password,omitempty" jsonschema:"maxLength=80"`
}

NeighborConfig defines a BGP peer.

type OTelConfig added in v0.3.0

type OTelConfig struct {
	// Master switch for all OTEL export. Default: true.
	// Set to false to disable OTEL entirely without removing the endpoint.
	Enabled *bool `yaml:"enabled" json:"enabled" toml:"enabled" jsonschema:"default=true"`
	// OTLP collector endpoint URL. If empty, OTEL export is disabled.
	// The URL scheme selects the transport protocol automatically:
	//   grpc://host:4317  — gRPC (plaintext)
	//   grpcs://host:4317 — gRPC (TLS)
	//   http://host:4318  — OTLP/HTTP (plaintext)
	//   https://host:4318 — OTLP/HTTP (TLS)
	Endpoint string `yaml:"endpoint" json:"endpoint" toml:"endpoint"`
	// Force plaintext transport (no TLS) for all signals, whatever the endpoint scheme says.
	// grpc:// and http:// endpoints are plaintext already; with grpcs:// or https:// this
	// disables TLS entirely (it does not skip certificate verification), so the export
	// fails against a TLS-only collector. Can be overridden per signal.
	Insecure bool `yaml:"insecure" json:"insecure" toml:"insecure" jsonschema:"default=false"`
	// Additional headers sent with every OTLP request (e.g. for API-key authentication).
	// Can be extended or overridden per signal.
	Headers map[string]string `yaml:"headers" json:"headers" toml:"headers"`
	// OTEL resource service.name attribute. Default: "pathosd".
	ServiceName string `yaml:"service_name" json:"service_name" toml:"service_name"`
	// Per-signal configuration. Each signal inherits the global endpoint, insecure, and headers
	// and is enabled by default. Use these to override per signal.
	Traces  OTelSignalConfig `yaml:"traces" json:"traces" toml:"traces"`
	Metrics OTelSignalConfig `yaml:"metrics" json:"metrics" toml:"metrics"`
	Logs    OTelSignalConfig `yaml:"logs" json:"logs" toml:"logs"`
}

OTelConfig configures OpenTelemetry export (traces, metrics, logs).

func (OTelConfig) IsEnabled added in v0.3.1

func (o OTelConfig) IsEnabled() bool

IsEnabled reports whether OTEL export is enabled globally. Returns true when Enabled is nil (unset = enabled by default).

type OTelProtocol added in v0.3.1

type OTelProtocol int

OTelProtocol represents the resolved OTLP transport.

const (
	OTelProtocolGRPC OTelProtocol = iota
	OTelProtocolHTTP
)

func ParseOTelEndpoint added in v0.3.1

func ParseOTelEndpoint(rawURL string) (proto OTelProtocol, normURL string, err error)

ParseOTelEndpoint resolves the OTLP transport from the URL scheme and returns the normalised URL that the OTEL SDK exporters expect.

Scheme mapping:

grpc://  → gRPC, normalised to http://
grpcs:// → gRPC, normalised to https://
http://  → OTLP/HTTP, unchanged
https:// → OTLP/HTTP, unchanged

type OTelSignalConfig added in v0.3.1

type OTelSignalConfig struct {
	// Per-signal endpoint URL. Overrides the top-level otel.endpoint for this signal.
	// Leave empty to inherit the global endpoint.
	// The URL scheme determines the transport: grpc:// or grpcs:// selects gRPC;
	// http:// or https:// selects OTLP/HTTP.
	Endpoint string `yaml:"endpoint" json:"endpoint" toml:"endpoint"`
	// Enable this signal. Default: true (inherits the global otel.enabled value).
	Enabled *bool `yaml:"enabled" json:"enabled" toml:"enabled" jsonschema:"default=true"`
	// Force plaintext transport (no TLS) for this signal, whatever the endpoint scheme says.
	// Overrides the global otel.insecure. Leave unset to inherit the global value.
	Insecure *bool `yaml:"insecure" json:"insecure" toml:"insecure"`
	// Additional headers for this signal, merged on top of the global otel.headers.
	// Signal-level keys take precedence over global keys.
	Headers map[string]string `yaml:"headers" json:"headers" toml:"headers"`
}

OTelSignalConfig configures a single OTEL signal (traces, metrics, or logs).

func (OTelSignalConfig) EffectiveEndpoint added in v0.3.1

func (s OTelSignalConfig) EffectiveEndpoint(global string) string

EffectiveEndpoint returns the signal-specific endpoint when set, otherwise the global endpoint.

func (OTelSignalConfig) EffectiveHeaders added in v0.3.1

func (s OTelSignalConfig) EffectiveHeaders(global map[string]string) map[string]string

EffectiveHeaders returns the global headers merged with the signal-level headers. Signal-level keys take precedence over global keys.

func (OTelSignalConfig) EffectiveInsecure added in v0.3.1

func (s OTelSignalConfig) EffectiveInsecure(global bool) bool

EffectiveInsecure returns the signal-level insecure flag when explicitly set, otherwise falls back to the global value.

func (OTelSignalConfig) IsEnabled added in v0.3.1

func (s OTelSignalConfig) IsEnabled() bool

IsEnabled reports whether the signal is enabled. Returns true when Enabled is nil (unset = enabled by default).

type PathsConfig added in v0.13.0

type PathsConfig struct {
	// Mount point of procfs. In a container mount the host's /proc at /host/proc
	// (read-only) and set this to "/host/proc". Default: /proc.
	Procfs string `yaml:"procfs,omitempty" json:"procfs,omitempty" toml:"procfs,omitempty" jsonschema:"default=/proc"`
}

PathsConfig points checks at the kernel filesystems, node-exporter style.

type PingCheckConfig

type PingCheckConfig struct {
	// Destination IP address to ping. Defaults to VIP prefix IP.
	DstIP string `yaml:"dst_ip" json:"dst_ip" toml:"dst_ip"`
	// Source IP address for outgoing ICMP packets.
	SrcIP string `yaml:"src_ip" json:"src_ip" toml:"src_ip"`
	// Use privileged raw ICMP socket mode. Requires root/CAP_NET_RAW. Default: false (unprivileged UDP mode).
	Privileged bool `yaml:"privileged,omitempty" json:"privileged,omitempty" toml:"privileged,omitempty" jsonschema:"default=false"`
	// Number of ICMP echo requests to send per check cycle. Default: 1.
	Count int `yaml:"count" json:"count" toml:"count" jsonschema:"minimum=1,maximum=60,default=1"`
	// Per-packet timeout for ICMP replies.
	Timeout *Duration `yaml:"timeout" json:"timeout" toml:"timeout"`
	// Interval between individual ICMP packets within a check cycle.
	Interval *Duration `yaml:"interval" json:"interval" toml:"interval"`
	// Maximum acceptable packet loss ratio (0.0–1.0). Default: 0 (no loss allowed).
	MaxLossRatio float64 `yaml:"max_loss_ratio" json:"max_loss_ratio" toml:"max_loss_ratio" jsonschema:"minimum=0,maximum=1,default=0"`
}

PingCheckConfig defines an ICMP ping health check.

type PolicyConfig

type PolicyConfig struct {
	// Action to take when the health check fails: withdraw the route entirely, or lower its BGP priority.
	FailAction string `` /* 126-byte string literal not displayed */
	// Path to a drain lock file. When present and the check is healthy, the VIP is announced pessimized (using the lower_priority attributes) instead of at full priority, regardless of fail_action. Does not prevent withdrawal on failure. Useful for maintenance drains.
	LowerPriorityFile string `yaml:"lower_priority_file" json:"lower_priority_file,omitempty" toml:"lower_priority_file,omitempty"`
	// BGP attributes applied to every announcement of this VIP, healthy or pessimized. Use it to rank this node below another healthy node for the same VIP (standby ordering).
	Announce *AnnounceConfig `yaml:"announce" json:"announce,omitempty" toml:"announce,omitempty"`
	// BGP attributes used for pessimized announcements: on check failure when fail_action is lower_priority, and whenever lower_priority_file is present.
	LowerPriority *LowerPriorityConfig `yaml:"lower_priority" json:"lower_priority,omitempty" toml:"lower_priority,omitempty"`
}

PolicyConfig defines how VIP state changes on check failure.

type RouterConfig

type RouterConfig struct {
	// Autonomous System Number for this router (1–4294967295).
	ASN uint32 `yaml:"asn" json:"asn" toml:"asn" jsonschema:"required,minimum=1,maximum=4294967295"`
	// BGP Router ID in dotted-quad notation (e.g. 10.0.0.1).
	RouterID string `yaml:"router_id" json:"router_id" toml:"router_id" jsonschema:"required,format=ipv4"`
	// Local address to bind BGP sessions. If empty, the OS selects the source address.
	LocalAddress string `yaml:"local_address" json:"local_address" toml:"local_address"`
	// IPv6 local address used as the next-hop (and listen address) for IPv6
	// VIP routes. Required when any VIP prefix is IPv6. This is separate from
	// local_address so an IPv4 peer source and IPv6 route next-hop can coexist.
	LocalAddressIPv6 string `yaml:"local_address_ipv6" json:"local_address_ipv6" toml:"local_address_ipv6"`
}

RouterConfig identifies this BGP speaker.

type SQLCheckConfig added in v0.13.0

type SQLCheckConfig struct {
	// Database driver: "mysql" (also MariaDB) or "postgres". Required.
	Driver string `yaml:"driver" json:"driver" toml:"driver" jsonschema:"required,enum=mysql,enum=postgres"`
	// Server host (IP or DNS name). Defaults to the VIP prefix IP for /32 or /128.
	Host string `yaml:"host" json:"host" toml:"host"`
	// Server port. Default: 3306 for mysql, 5432 for postgres.
	Port uint16 `yaml:"port" json:"port" toml:"port" jsonschema:"minimum=1,maximum=65535"`
	// Login user. Required. Grant it only what the queries need.
	User string `yaml:"user" json:"user" toml:"user" jsonschema:"required"`
	// Login password; use an environment placeholder (%{DB_PASSWORD}) rather than a literal.
	Password string `yaml:"password,omitempty" json:"password,omitempty" toml:"password,omitempty"`
	// Database to connect to. Optional for mysql; postgres defaults to the user name.
	Database string `yaml:"database,omitempty" json:"database,omitempty" toml:"database,omitempty"`
	// Enable TLS. Default: false (plaintext).
	TLS bool `yaml:"tls,omitempty" json:"tls,omitempty" toml:"tls,omitempty" jsonschema:"default=false"`
	// Skip certificate verification. Requires tls=true. Mutually exclusive with tls_ca_cert.
	TLSInsecure bool `yaml:"tls_insecure,omitempty" json:"tls_insecure,omitempty" toml:"tls_insecure,omitempty" jsonschema:"default=false"`
	// Path to a PEM-encoded CA certificate for verification. Requires tls=true.
	TLSCACert string `yaml:"tls_ca_cert,omitempty" json:"tls_ca_cert,omitempty" toml:"tls_ca_cert,omitempty"`
	// TLS server name for SNI and verification. Defaults to host.
	TLSServerName string `yaml:"tls_server_name,omitempty" json:"tls_server_name,omitempty" toml:"tls_server_name,omitempty"`
	// Reuse the connection across checks. Off by default so every check
	// exercises connect and authentication.
	KeepAlive bool `yaml:"keep_alive,omitempty" json:"keep_alive,omitempty" toml:"keep_alive,omitempty" jsonschema:"default=false"`
	// Queries to run in order on one connection. Default: a single "SELECT 1".
	Queries []SQLQueryConfig `yaml:"queries,omitempty" json:"queries,omitempty" toml:"queries,omitempty"`
	// Upper bound on rows fetched per query. Default: 100.
	MaxRows int `yaml:"max_rows,omitempty" json:"max_rows,omitempty" toml:"max_rows,omitempty" jsonschema:"minimum=1,default=100"`
}

SQLCheckConfig defines a check that connects to a SQL server and runs queries. The check passes when every query succeeds and, where result_jq is set, the rows satisfy the expression. Nothing database-specific is built in: replication lag, read-only state or application tables are all expressed as a query plus a jq condition.

type SQLQueryConfig added in v0.13.0

type SQLQueryConfig struct {
	// Name used in details, metrics (query label) and errors. Default: q1, q2, …
	Name string `yaml:"name,omitempty" json:"name,omitempty" toml:"name,omitempty"`
	// Statement to execute. Required.
	SQL string `yaml:"sql" json:"sql" toml:"sql" jsonschema:"required"`
	// jq expression evaluated against the rows as a JSON array of
	// {column: value} objects (numbers for numeric columns, strings otherwise);
	// must yield true. E.g. ".[0].Seconds_Behind_Source < 60" or
	// ".[0].read_only == 0". Empty: the query only has to succeed.
	ResultJQ string `yaml:"result_jq,omitempty" json:"result_jq,omitempty" toml:"result_jq,omitempty"`
}

SQLQueryConfig is one statement of a SQL check.

func (*SQLQueryConfig) EffectiveName added in v0.13.0

func (q *SQLQueryConfig) EffectiveName(index int) string

EffectiveName returns the query name, defaulting to q<index+1>.

type TCPCheckConfig added in v0.3.0

type TCPCheckConfig struct {
	// Host to connect to. Defaults to VIP prefix IP for /32 or /128.
	Host string `yaml:"host" json:"host" toml:"host"`
	// TCP port to connect to. Required.
	Port uint16 `yaml:"port" json:"port" toml:"port" jsonschema:"required,minimum=1,maximum=65535"`
}

TCPCheckConfig defines a TCP port reachability check. The checker dials host:port and considers a successful connection as passing.

type UDPCheckConfig added in v0.3.0

type UDPCheckConfig struct {
	// Host to send the probe to. Defaults to VIP prefix IP for /32 or /128.
	Host string `yaml:"host" json:"host" toml:"host"`
	// UDP port to probe. Required.
	Port uint16 `yaml:"port" json:"port" toml:"port" jsonschema:"required,minimum=1,maximum=65535"`
	// Payload to send with the probe datagram, as a string (YAML/TOML escapes such as
	// "\x00" or "\u0000" work). Default: a single null byte.
	Payload string `yaml:"payload" json:"payload" toml:"payload"`
}

UDPCheckConfig defines a UDP port reachability check. The checker sends a small probe datagram to host:port. An ICMP port-unreachable reply (surfaced as ECONNREFUSED on a connected UDP socket) means nothing is listening → check fails. A read timeout with no error means the datagram was accepted → check passes.

type VIPChange added in v0.14.0

type VIPChange struct {
	Old, New *VIPConfig
	// ChecksChanged lists the checks (by effective name) whose definition
	// differs or that are new in the candidate: every one of them must
	// reach a verdict before the VIP switches to the new definition. When
	// require_local_address or local_interface changed, every check is
	// listed, since the guard wraps each checker.
	ChecksChanged []*CheckConfig
	// ChecksRemoved lists running checks absent from the candidate.
	ChecksRemoved []*CheckConfig
	// PolicyChanged is set when policy or checks_policy differ.
	PolicyChanged bool
}

VIPChange describes how one VIP differs.

type VIPChanges added in v0.14.0

type VIPChanges struct {
	// Added VIPs appear only in the candidate.
	Added []*VIPConfig
	// Removed VIPs appear only in the running config. A VIP whose prefix
	// changed is listed here and in Added: the old route must go and the
	// new one must prove health.
	Removed []*VIPConfig
	// Changed VIPs exist in both with the same prefix but differ.
	Changed []VIPChange
	// Unchanged names, in candidate order.
	Unchanged []string
}

VIPChanges is the result of DiffVIPs.

func DiffVIPs added in v0.14.0

func DiffVIPs(running, candidate []VIPConfig) VIPChanges

DiffVIPs compares two VIP lists by name. Both must have defaults applied.

func (VIPChanges) IsEmpty added in v0.14.0

func (c VIPChanges) IsEmpty() bool

IsEmpty reports whether nothing changed.

type VIPConfig

type VIPConfig struct {
	// Human-readable name for this VIP (used in logs and metrics).
	Name string `yaml:"name" json:"name" toml:"name" jsonschema:"required"`
	// IP prefix to announce (e.g. 10.0.0.1/32 or 2001:db8::1/128).
	Prefix string `yaml:"prefix" json:"prefix" toml:"prefix" jsonschema:"required"`
	// Health check for this VIP. Exactly one of check or checks is required.
	Check CheckConfig `yaml:"check,omitempty" json:"check,omitempty" toml:"check,omitempty" jsonschema:"oneof_required=single_check"`
	// Several health checks for this VIP, combined by checks_policy. Each entry is a full
	// check definition with its own interval, timeout, rise and fall. Exactly one of check
	// or checks is required.
	Checks []CheckConfig `` /* 126-byte string literal not displayed */
	// How the health of several checks combines into the VIP health: "all" (every check
	// must be healthy), "any" (one healthy check suffices) or a boolean expression over
	// the check names such as "web || (dns && ping)" (expr-lang syntax: && || ! and parentheses).
	// Default: all.
	ChecksPolicy string `` /* 170-byte string literal not displayed */
	// Policy controlling how BGP announcements react to check failures.
	Policy PolicyConfig `yaml:"policy" json:"policy" toml:"policy" jsonschema:"required"`
	// Fail the health check while the VIP address is not configured on a local interface,
	// so a route is never announced for an address this host cannot serve. Default: false.
	RequireLocalAddress bool `yaml:"require_local_address" json:"require_local_address" toml:"require_local_address" jsonschema:"default=false"`
	// Interface the VIP address must be on for require_local_address (e.g. dummy-vip). Any interface when empty.
	LocalInterface string `yaml:"local_interface" json:"local_interface" toml:"local_interface"`
}

VIPConfig defines a Virtual IP with its health check and policy.

func (*VIPConfig) CheckList added in v0.12.0

func (v *VIPConfig) CheckList() []*CheckConfig

CheckList returns the VIP's checks in config order: the checks list when set, otherwise the single check. Pointers refer into the config.

func (*VIPConfig) EffectiveChecksPolicy added in v0.12.0

func (v *VIPConfig) EffectiveChecksPolicy() string

EffectiveChecksPolicy returns checks_policy with its default applied.

Jump to

Keyboard shortcuts

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