Documentation ¶
Overview ¶
Package etcd implements a distributed storage backend for Caddy using etcd.
Deprecated: This storage backend is deprecated and not recommended for production use. The etcd implementation introduces significant operational complexity and potential reliability challenges. For clustered storage needs, please consider using the S3 storage backend (github.com/techknowlogick/certmagic-s3) which provides better reliability and simpler operations while meeting Caddy's distributed storage requirements.
Index ¶
- Variables
- func FilterExactPrefix(prefix string, cut string) func(*mvccpb.KeyValue) bool
- func FilterPrefix(prefix string, cut string) func(*mvccpb.KeyValue) bool
- func FilterRemoveDirectories() func(*mvccpb.KeyValue) bool
- func IsConnectionError(e error) bool
- func IsFailedChecksumError(e error) bool
- func IsLockError(e error) bool
- func IsNotExistError(e error) bool
- type AuthConfig
- type Cluster
- func (Cluster) CaddyModule() caddy.ModuleInfo
- func (c Cluster) CertMagicStorage() (certmagic.Storage, error)
- func (c Cluster) Delete(_ context.Context, key string) error
- func (c Cluster) Exists(_ context.Context, key string) bool
- func (c Cluster) List(_ context.Context, prefix string, recursive bool) ([]string, error)
- func (c Cluster) Load(_ context.Context, key string) ([]byte, error)
- func (c Cluster) Lock(_ context.Context, key string) error
- func (c *Cluster) Provision(ctx caddy.Context) error
- func (c Cluster) Stat(_ context.Context, key string) (certmagic.KeyInfo, error)
- func (c Cluster) Store(_ context.Context, key string, value []byte) error
- func (c Cluster) Unlock(_ context.Context, key string) error
- func (c *Cluster) UnmarshalCaddyfile(d *caddyfile.Dispenser) error
- func (c *Cluster) Validate() error
- type ClusterConfig
- type ConfigOption
- func ConfigOptsFromEnvironment() ([]ConfigOption, error)
- func WithAutoSyncInterval(s string) ConfigOption
- func WithCaddyFile(s string) ConfigOption
- func WithDialTimeout(s string) ConfigOption
- func WithDisableCaddyfileLoad(s string) ConfigOption
- func WithKeepAliveTime(s string) ConfigOption
- func WithKeepAliveTimeout(s string) ConfigOption
- func WithPassword(s string) ConfigOption
- func WithPrefix(s string) ConfigOption
- func WithRejectOldCluster(s string) ConfigOption
- func WithRequestTimeout(s string) ConfigOption
- func WithServers(s string) ConfigOption
- func WithTLSCA(s string) ConfigOption
- func WithTLSCert(s string) ConfigOption
- func WithTLSKey(s string) ConfigOption
- func WithTLSServerName(s string) ConfigOption
- func WithTLSSkipVerify(s string) ConfigOption
- func WithTimeout(s string) ConfigOption
- func WithUsername(s string) ConfigOption
- type ConnectionConfig
- type ConnectionError
- type Duration
- type FailedChecksum
- type Lock
- type LockError
- type Metadata
- type NotExist
- type Service
- type TLSConfig
Constants ¶
This section is empty.
Variables ¶
var ( ErrLockTimeout = fmt.Errorf("lock timeout exceeded") ErrNoConnection = fmt.Errorf("etcd cluster is not available") ErrClusterDown = fmt.Errorf("etcd cluster is not available") ErrInvalidConfig = fmt.Errorf("invalid configuration") )
Error types for specific failure cases
Functions ¶
func FilterExactPrefix ¶
FilterExactPrefix returns a filter function that matches only terminal nodes (files) with the exact path prefix FilterExactPrefix returns a filter function that matches only terminal nodes (files) with the exact path prefix. It trims the base prefix (cut) before matching.
Parameters:
- prefix: The exact prefix to match after trimming (e.g. /path/to/dir)
- cut: The base prefix to remove before matching (e.g. /caddy)
Returns a filter function that matches only files directly under the given prefix, not in subdirectories. For example, with prefix "/foo", it matches "/foo/file.txt" but not "/foo/bar/file.txt"
func FilterPrefix ¶
FilterPrefix returns a filter function that matches keys with the given prefix FilterPrefix returns a filter function that matches keys with the given prefix. It trims the base prefix (cut) from each key before checking the match prefix.
Parameters:
- prefix: The prefix to match against after trimming the base prefix
- cut: The base prefix to remove before matching (e.g. /caddy)
Returns a filter function that can be used with List() to filter by key prefix
func FilterRemoveDirectories ¶
FilterRemoveDirectories returns a filter function that removes directory entries A key is considered a directory if it has no value FilterRemoveDirectories returns a filter function that removes directory entries. A key is considered a directory if it has no value stored in etcd. This is useful for getting only leaf nodes (files) in a directory structure.
Returns a filter function that can be used with List() to exclude directories
func IsConnectionError ¶
IsConnectionError checks if the error is a ConnectionError IsConnectionError checks if the given error is related to etcd connection issues. Returns true if the error is of type ConnectionError, false otherwise.
func IsFailedChecksumError ¶
IsFailedChecksumError checks to see if error is of type FailedChecksum IsFailedChecksumError checks if the given error indicates a checksum validation failure. Returns true if the error is of type FailedChecksum, false otherwise.
func IsLockError ¶
IsLockError checks if the error is a LockError IsLockError checks if the given error is related to lock acquisition failure. Returns true if the error is of type LockError, false otherwise.
func IsNotExistError ¶
IsNotExistError checks to see if error is of type NotExist IsNotExistError checks if the given error indicates a key does not exist. Returns true if the error is of type NotExist, false otherwise.
Types ¶
type AuthConfig ¶
type AuthConfig struct { Username string `json:"username,omitempty"` // Username for etcd authentication Password string `json:"password,omitempty"` // Password for etcd authentication }
AuthConfig holds authentication credentials for etcd access. Both username and password must be provided together if authentication is enabled.
type Cluster ¶
type Cluster struct {
// contains filtered or unexported fields
}
Cluster implements certmagic.Storage using etcd as the storage backend. It provides distributed locking, atomic operations, and consistent storage across multiple Caddy instances in a cluster.
func (Cluster) CaddyModule ¶
func (Cluster) CaddyModule() caddy.ModuleInfo
CaddyModule returns the Caddy module information.
func (Cluster) CertMagicStorage ¶
CertMagicStorage converts c to a certmagic.Storage instance.
func (*Cluster) UnmarshalCaddyfile ¶
UnmarshalCaddyfile implements caddyfile.Unmarshaler. Syntax:
storage etcd { prefix <key_prefix> endpoints { <endpoint1> <endpoint2> ... } timeout <duration> caddyfile <path> disable_caddyfile_load auth { username <username> password <password> } tls { cert <path> key <path> ca <path> server_name <name> insecure_skip_verify } connection { dial_timeout <duration> keepalive_time <duration> keepalive_timeout <duration> auto_sync_interval <duration> request_timeout <duration> reject_old_cluster <bool> } }
type ClusterConfig ¶
type ClusterConfig struct { KeyPrefix string `json:"key_prefix,omitempty"` ServerIP []string `json:"endpoints,omitempty"` LockTimeout Duration `json:"lock_timeout,string,omitempty"` CaddyFile []byte `json:"-"` // Not exposed in JSON CaddyFilePath string `json:"-"` // Not exposed in JSON DisableCaddyLoad bool `json:"disable_caddyfile_load,omitempty"` TLS TLSConfig `json:"tls,omitempty"` Auth AuthConfig `json:"auth,omitempty"` Connection ConnectionConfig `json:"connection,omitempty"` // contains filtered or unexported fields }
func NewClusterConfig ¶
func NewClusterConfig(opts ...ConfigOption) (*ClusterConfig, error)
NewClusterConfig returns a new configuration with options passed as functional options and validates the configuration
func (*ClusterConfig) Validate ¶
func (c *ClusterConfig) Validate() error
Validate checks if the configuration is valid
type ConfigOption ¶
type ConfigOption func(c *ClusterConfig) error
ConfigOption represents a functional option for ClusterConfig
func ConfigOptsFromEnvironment ¶
func ConfigOptsFromEnvironment() ([]ConfigOption, error)
ConfigOptsFromEnvironment reads environment variables and returns options that can be applied via NewClusterConfig. It validates required pairs of environment variables and returns any validation errors.
func WithAutoSyncInterval ¶
func WithAutoSyncInterval(s string) ConfigOption
WithAutoSyncInterval sets the auto sync interval for etcd connections
func WithCaddyFile ¶
func WithCaddyFile(s string) ConfigOption
WithCaddyFile sets the path to the bootstrap Caddyfile to load on initial start if configuration information is not already present in etcd. The first cluster instance will load this file and store it in etcd. Subsequent members of the cluster will prioritize configuration from etcd even if this file is present. This function will not error even if the Caddyfile is not present. If a caddyfile cannot be read from etcd, from this file, or from the default loader, caddy will start with an empty default configuration.
func WithDialTimeout ¶
func WithDialTimeout(s string) ConfigOption
WithDialTimeout sets the dial timeout for etcd connections
func WithDisableCaddyfileLoad ¶
func WithDisableCaddyfileLoad(s string) ConfigOption
WithDisableCaddyfileLoad will skip all attempts at loading the caddyfile from etcd and force caddy to fall back to other enabled caddyfile loader plugins or the default loader
func WithKeepAliveTime ¶
func WithKeepAliveTime(s string) ConfigOption
WithKeepAliveTime sets the keepalive time for etcd connections
func WithKeepAliveTimeout ¶
func WithKeepAliveTimeout(s string) ConfigOption
WithKeepAliveTimeout sets the keepalive timeout for etcd connections
func WithPassword ¶
func WithPassword(s string) ConfigOption
WithPassword sets the password for etcd authentication
func WithPrefix ¶
func WithPrefix(s string) ConfigOption
WithPrefix sets the etcd namespace for caddy data. Default is `/caddy`. Prefixes are normalized to use `/` as a path separator.
func WithRejectOldCluster ¶
func WithRejectOldCluster(s string) ConfigOption
WithRejectOldCluster sets whether to reject connecting to old clusters
func WithRequestTimeout ¶
func WithRequestTimeout(s string) ConfigOption
WithRequestTimeout sets the request timeout for etcd operations
func WithServers ¶
func WithServers(s string) ConfigOption
WithServers sets the etcd server endpoints. Multiple endpoints are assumed to be separated by a comma, and consist of a full URL, including scheme and port (i.e., http://127.0.0.1:2379) The default config uses port 2379 on localhost.
func WithTLSCA ¶
func WithTLSCA(s string) ConfigOption
WithTLSCA sets the CA certificate file for TLS
func WithTLSCert ¶
func WithTLSCert(s string) ConfigOption
WithTLSCert sets the client certificate file for TLS
func WithTLSKey ¶
func WithTLSKey(s string) ConfigOption
WithTLSKey sets the client key file for TLS
func WithTLSServerName ¶
func WithTLSServerName(s string) ConfigOption
WithTLSServerName sets the server name for TLS verification
func WithTLSSkipVerify ¶
func WithTLSSkipVerify(s string) ConfigOption
WithTLSSkipVerify sets whether to skip TLS verification
func WithTimeout ¶
func WithTimeout(s string) ConfigOption
WithTimeout sets the time locks should be considered abandoned. Locks that exist longer than this setting will be overwritten by the next client that acquires the lock. The default is 5 minutes. This option takes standard Go duration formats such as 5m, 1h, etc.
func WithUsername ¶
func WithUsername(s string) ConfigOption
WithUsername sets the username for etcd authentication
type ConnectionConfig ¶
type ConnectionConfig struct { DialTimeout Duration `json:"dial_timeout,string,omitempty"` // Timeout for establishing initial connection KeepAliveTime Duration `json:"keepalive_time,string,omitempty"` // Time between keepalive probes KeepAliveTimeout Duration `json:"keepalive_timeout,string,omitempty"` // Time to wait for keepalive response AutoSyncInterval Duration `json:"auto_sync_interval,string,omitempty"` // Interval for endpoint auto-synchronization RequestTimeout Duration `json:"request_timeout,string,omitempty"` // Timeout for individual requests RejectOldCluster bool `json:"reject_old_cluster,omitempty"` // Whether to reject connecting to old clusters }
ConnectionConfig holds etcd connection settings including timeouts, keepalive parameters, and other connection-related configuration options.
type ConnectionError ¶
ConnectionError represents connection-related errors
func (ConnectionError) Error ¶
func (e ConnectionError) Error() string
func (ConnectionError) Unwrap ¶
func (e ConnectionError) Unwrap() error
type Duration ¶
Duration wraps time.Duration to provide JSON marshaling/unmarshaling
func (*Duration) UnmarshalJSON ¶
type FailedChecksum ¶
type FailedChecksum struct {
Key string
}
FailedChecksum error is returned when the data returned by Load does not match the SHA1 checksum stored in its metadata node
func (FailedChecksum) Error ¶
func (e FailedChecksum) Error() string
type Lock ¶
type Lock struct { Token string // Random token identifying the client holding the lock Obtained string // UTC timestamp when the lock was obtained Key string // The key being locked LeaseID clientv3.LeaseID // Lease ID associated with this lock }
Lock represents a distributed lock in etcd. Features:
- Unique token per client for lock ownership
- Automatic lock extension for same client
- Configurable lock timeouts
- Automatic cleanup of stale locks
- Safe concurrent access across cluster
Note: The implementation assumes a single client does not attempt to acquire the same lock from multiple goroutines simultaneously. Such usage may result in race conditions where the last write wins.
type Metadata ¶
type Metadata struct { Path string // Full path to the node Size int // Size of the value in bytes Timestamp time.Time // Last modification time Hash [20]byte // SHA1 hash of the value IsDir bool // Whether this node represents a directory }
Metadata stores information about a particular node that represents a file in etcd
func NewMetadata ¶
NewMetadata returns metadata information given a path and a file to be stored at the path. Typically, one metadata node is stored for each file node in etcd.
type NotExist ¶
type NotExist struct {
Key string
}
NotExist is returned when a key lookup fails when calling Load or Metadata
type Service ¶
type Service interface { Store(key string, value []byte) error Load(key string) ([]byte, error) Delete(key string) error Metadata(key string) (*Metadata, error) Lock(key string) error Unlock(key string) error List(path string, filters ...func(*mvccpb.KeyValue) bool) ([]string, error) // contains filtered or unexported methods }
func NewService ¶
func NewService(c *ClusterConfig) (Service, error)
NewService returns a new low level service to store and load values in etcd. The service implements filesystem-like semantics on top of etcd's key/value storage, with support for:
- Atomic transactions for data consistency
- Metadata tracking for each stored value
- Directory-like operations with recursive listing
- Distributed locking with configurable timeouts
- Automatic connection management and retries
- Data integrity verification via checksums
The service uses exponential backoff for retries and transactions to handle temporary failures. While best efforts are made to maintain consistency, prolonged etcd unavailability may impact the system's ability to recover to a fully coherent state.
type TLSConfig ¶
type TLSConfig struct { CertFile string `json:"cert_file,omitempty"` // Path to client certificate file KeyFile string `json:"key_file,omitempty"` // Path to client key file CAFile string `json:"ca_file,omitempty"` // Path to CA certificate for server verification ServerName string `json:"server_name,omitempty"` // Expected server name for verification SkipVerify bool `json:"skip_verify,omitempty"` // Whether to skip TLS verification (not recommended) }
ClusterConfig maintains configuration for connecting to and interacting with etcd. It includes settings for:
- Server endpoints and key prefixes
- TLS security and authentication
- Connection timeouts and keepalive settings
- Lock timeouts and operational parameters
- Optional Caddyfile loading configuration
TLSConfig holds TLS-related configuration for secure etcd connections. It includes paths to certificates and keys, as well as verification options.