Documentation
¶
Index ¶
- Constants
- Variables
- func StartApiServer(apiBinding string)
- type ActiveConnections
- type AllowDenyConfig
- type AllowDenyLists
- type AutoScale
- type ClientFilter
- type ClientInfo
- type Config
- type ConnectionNotifier
- type Connector
- func (c *Connector) AcceptConnection(conn net.Conn)
- func (c *Connector) HandleConnection(frontendConn net.Conn)
- func (c *Connector) StartAcceptingConnections(listenAddress string, connRateLimit int) error
- func (c *Connector) UseClientFilter(filter *ClientFilter)
- func (c *Connector) UseConnectionNotifier(notifier ConnectionNotifier)
- func (c *Connector) UseNgrok(config NgrokConfig)
- func (c *Connector) UseReceiveProxyProto(trustedProxyNets []*net.IPNet)
- func (c *Connector) WaitForConnections()
- type ConnectorMetrics
- type IDockerWatcher
- type IDownScaler
- type IRoutes
- type K8sWatcher
- type MetricsBackendConfig
- type MetricsBuilder
- type NgrokConfig
- type NgrokConnector
- type PlayerInfo
- type RouteFinder
- type RoutesConfig
- type RoutesConfigSchema
- type RoutesHandler
- type ScalerFunc
- type Server
- type WebhookConfig
- type WebhookNotifier
- func (w *WebhookNotifier) NotifyConnected(ctx context.Context, clientAddr net.Addr, serverAddress string, ...) error
- func (w *WebhookNotifier) NotifyDisconnected(ctx context.Context, clientAddr net.Addr, serverAddress string, ...) error
- func (w *WebhookNotifier) NotifyFailedBackendConnection(ctx context.Context, clientAddr net.Addr, server string, ...) error
- func (w *WebhookNotifier) NotifyMissingBackend(ctx context.Context, clientAddr net.Addr, server string, ...) error
- type WebhookNotifierPayload
Constants ¶
const ( DockerAPIVersion = "1.24" DockerRouterLabelHost = "mc-router.host" DockerRouterLabelPort = "mc-router.port" DockerRouterLabelDefault = "mc-router.default" DockerRouterLabelNetwork = "mc-router.network" )
const ( AnnotationExternalServerName = "mc-router.itzg.me/externalServerName" AnnotationDefaultServer = "mc-router.itzg.me/defaultServer" AnnotationAutoScaleUp = "mc-router.itzg.me/autoScaleUp" AnnotationAutoScaleDown = "mc-router.itzg.me/autoScaleDown" )
const ( MetricsBackendExpvar = "expvar" MetricsBackendPrometheus = "prometheus" MetricsBackendInfluxDB = "influxdb" MetricsBackendDiscard = "discard" )
const ( WebhookEventConnecting = "connect" WebhookEventDisconnecting = "disconnect" )
const ( WebhookStatusMissingBackend = "missing-backend" WebhookStatusFailedBackendConnection = "failed-backend-connection" WebhookStatusSuccess = "success" )
Variables ¶
var EmptyScalerFunc = func(ctx context.Context) error { return nil }
var Routes = NewRoutes()
var RoutesConfigLoader = &routesConfigLoader{}
Functions ¶
func StartApiServer ¶
func StartApiServer(apiBinding string)
Types ¶
type ActiveConnections ¶
func NewActiveConnections ¶
func NewActiveConnections() *ActiveConnections
func (*ActiveConnections) Decrement ¶
func (sm *ActiveConnections) Decrement(serverAddress string)
func (*ActiveConnections) GetCount ¶
func (sm *ActiveConnections) GetCount(serverAddress string) int
func (*ActiveConnections) Increment ¶
func (sm *ActiveConnections) Increment(serverAddress string)
type AllowDenyConfig ¶
type AllowDenyConfig struct { Global AllowDenyLists Servers map[string]AllowDenyLists }
func ParseAllowDenyConfig ¶
func ParseAllowDenyConfig(allowDenyListPath string) (*AllowDenyConfig, error)
func (*AllowDenyConfig) ServerAllowsPlayer ¶
func (allowDenyConfig *AllowDenyConfig) ServerAllowsPlayer(serverAddress string, userInfo *PlayerInfo) bool
type AllowDenyLists ¶
type AllowDenyLists struct { Allowlist []PlayerInfo Denylist []PlayerInfo }
type AutoScale ¶
type AutoScale struct { Up bool `usage:"Increase Kubernetes StatefulSet Replicas (only) from 0 to 1 on respective backend servers when accessed"` Down bool `` /* 144-byte string literal not displayed */ DownAfter string `default:"10m" usage:"Server scale down delay after there are no connections"` AllowDeny string `` /* 273-byte string literal not displayed */ }
type ClientFilter ¶
type ClientFilter struct {
// contains filtered or unexported fields
}
ClientFilter performs allow/deny filtering of client IP addresses
func NewClientFilter ¶
func NewClientFilter(allows []string, denies []string) (*ClientFilter, error)
NewClientFilter provides a mechanism to evaluate client IP addresses and determine if they should be allowed access or not. The allows and denies can each or both be nil or netip.ParseAddr allowed values.
func NewClientFilterAllowAll ¶
func NewClientFilterAllowAll() *ClientFilter
type ClientInfo ¶
func ClientInfoFromAddr ¶
func ClientInfoFromAddr(addr net.Addr) *ClientInfo
type Config ¶
type Config struct { Port int `default:"25565" usage:"The [port] bound to listen for Minecraft client connections"` Default string `usage:"host:port of a default Minecraft server to use when mapping not found"` Mapping map[string]string `usage:"Comma or newline delimited or repeated mappings of externalHostname=host:port"` ApiBinding string `usage:"The [host:port] bound for servicing API requests"` CpuProfile string `usage:"Enables CPU profiling and writes to given path"` ConnectionRateLimit int `default:"1" usage:"Max number of connections to allow per second"` InKubeCluster bool `usage:"Use in-cluster Kubernetes config"` KubeConfig string `usage:"The path to a Kubernetes configuration file"` KubeNamespace string `usage:"The namespace to watch or blank for all, which is the default"` InDocker bool `usage:"Use Docker service discovery"` InDockerSwarm bool `usage:"Use Docker Swarm service discovery"` DockerSocket string `default:"unix:///var/run/docker.sock" usage:"Path to Docker socket to use"` DockerTimeout int `default:"0" usage:"Timeout configuration in seconds for the Docker integrations"` DockerRefreshInterval int `default:"15" usage:"Refresh interval in seconds for the Docker integrations"` MetricsBackend string `default:"discard" usage:"Backend to use for metrics exposure/publishing: discard,expvar,influxdb,prometheus"` MetricsBackendConfig MetricsBackendConfig UseProxyProtocol bool `default:"false" usage:"Send PROXY protocol to backend servers"` ReceiveProxyProtocol bool `` /* 190-byte string literal not displayed */ TrustedProxies []string `usage:"Comma delimited list of CIDR notation IP blocks to trust when receiving PROXY protocol"` RecordLogins bool `default:"false" usage:"Log and generate metrics on player logins. Metrics only supported with influxdb or prometheus backend"` Routes RoutesConfig Ngrok NgrokConfig AutoScale AutoScale ClientsToAllow []string `usage:"Zero or more client IP addresses or CIDRs to allow. Takes precedence over deny."` ClientsToDeny []string `usage:"Zero or more client IP addresses or CIDRs to deny. Ignored if any configured to allow"` SimplifySRV bool `default:"false" usage:"Simplify fully qualified SRV records for mapping"` Webhook WebhookConfig `usage:"Webhook configuration"` }
type ConnectionNotifier ¶
type ConnectionNotifier interface { // NotifyMissingBackend is called when an inbound connection is received for a server that does not have a backend. NotifyMissingBackend(ctx context.Context, clientAddr net.Addr, server string, playerInfo *PlayerInfo) error // NotifyFailedBackendConnection is called when the backend connection failed. NotifyFailedBackendConnection(ctx context.Context, clientAddr net.Addr, serverAddress string, playerInfo *PlayerInfo, backendHostPort string, err error) error // NotifyConnected is called when the backend connection succeeded. NotifyConnected(ctx context.Context, clientAddr net.Addr, serverAddress string, playerInfo *PlayerInfo, backendHostPort string) error // NotifyDisconnected is called when the backend connection terminates. NotifyDisconnected(ctx context.Context, clientAddr net.Addr, serverAddress string, playerInfo *PlayerInfo, backendHostPort string) error }
type Connector ¶
type Connector struct {
// contains filtered or unexported fields
}
func NewConnector ¶
func NewConnector(ctx context.Context, metrics *ConnectorMetrics, sendProxyProto bool, recordLogins bool, autoScaleUpAllowDenyConfig *AllowDenyConfig) *Connector
func (*Connector) AcceptConnection ¶
AcceptConnection provides a way to externally supply a connection to consume. Note that this will skip rate limiting.
func (*Connector) HandleConnection ¶
func (*Connector) StartAcceptingConnections ¶
func (*Connector) UseClientFilter ¶
func (c *Connector) UseClientFilter(filter *ClientFilter)
func (*Connector) UseConnectionNotifier ¶
func (c *Connector) UseConnectionNotifier(notifier ConnectionNotifier)
func (*Connector) UseNgrok ¶
func (c *Connector) UseNgrok(config NgrokConfig)
func (*Connector) UseReceiveProxyProto ¶
func (*Connector) WaitForConnections ¶
func (c *Connector) WaitForConnections()
type ConnectorMetrics ¶
type IDockerWatcher ¶
type IDockerWatcher interface {
Start(ctx context.Context, socket string, timeoutSeconds int, refreshIntervalSeconds int, autoScaleUp bool, autoScaleDown bool) error
}
var DockerSwarmWatcher IDockerWatcher = &dockerSwarmWatcherImpl{}
var DockerWatcher IDockerWatcher = &dockerWatcherImpl{}
type IRoutes ¶
type IRoutes interface { RoutesHandler Reset() RegisterAll(mappings map[string]string) // FindBackendForServerAddress returns the host:port for the external server address, if registered. // Otherwise, an empty string is returned. Also returns the normalized version of the given serverAddress. // The 3rd value returned is an (optional) "waker" function which a caller must invoke to wake up serverAddress. // The 4th value returned is an (optional) "sleeper" function which a caller must invoke to shut down serverAddress. FindBackendForServerAddress(ctx context.Context, serverAddress string) (string, string, ScalerFunc, ScalerFunc) GetMappings() map[string]string GetDefaultRoute() string SimplifySRV(srvEnabled bool) }
type K8sWatcher ¶
K8sWatcher is a RouteFinder that can find routes from kubernetes services. It also watches for stateful sets to auto scale up/down, if enabled.
func NewK8sWatcherInCluster ¶
func NewK8sWatcherInCluster() (*K8sWatcher, error)
func NewK8sWatcherWithConfig ¶
func NewK8sWatcherWithConfig(kubeConfigFile string) (*K8sWatcher, error)
func (*K8sWatcher) Start ¶
func (w *K8sWatcher) Start(ctx context.Context, handler RoutesHandler) error
func (*K8sWatcher) String ¶
func (w *K8sWatcher) String() string
func (*K8sWatcher) WithAutoScale ¶
func (w *K8sWatcher) WithAutoScale(autoScaleUp bool, autoScaleDown bool) *K8sWatcher
func (*K8sWatcher) WithNamespace ¶
func (w *K8sWatcher) WithNamespace(namespace string) *K8sWatcher
type MetricsBackendConfig ¶
type MetricsBuilder ¶
type MetricsBuilder interface { BuildConnectorMetrics() *ConnectorMetrics Start(ctx context.Context) error }
func NewMetricsBuilder ¶
func NewMetricsBuilder(backend string, config *MetricsBackendConfig) MetricsBuilder
NewMetricsBuilder creates a new MetricsBuilder based on the specified backend. If the backend is not recognized, a discard builder is returned. config can be nil if the backend is not influxdb.
type NgrokConfig ¶
type NgrokConnector ¶
type NgrokConnector struct {
// contains filtered or unexported fields
}
type PlayerInfo ¶
func (*PlayerInfo) String ¶
func (p *PlayerInfo) String() string
type RouteFinder ¶
type RouteFinder interface { Start(ctx context.Context, handler RoutesHandler) error String() string }
RouteFinder implementations find new routes in the system that can be tracked by a RoutesHandler
type RoutesConfig ¶
type RoutesConfigSchema ¶
type RoutesConfigSchema struct { DefaultServer string `json:"default-server"` Mappings map[string]string `json:"mappings"` }
RoutesConfigSchema declares the schema of the json file that can provide routes to serve
type RoutesHandler ¶
type RoutesHandler interface { CreateMapping(serverAddress string, backend string, waker ScalerFunc, sleeper ScalerFunc) SetDefaultRoute(backend string) // DeleteMapping requests that the serverAddress be removed from routes. // Returns true if the route existed. DeleteMapping(serverAddress string) bool }
type ScalerFunc ¶
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
func (*Server) AcceptConnection ¶
AcceptConnection provides a way to externally supply a connection to consume Note that this will skip rate limiting.
func (*Server) Done ¶
func (s *Server) Done() <-chan struct{}
Done provides a channel notified when the server has closed all connections, etc
func (*Server) ReloadConfig ¶
func (s *Server) ReloadConfig()
ReloadConfig indicates that an external request, such as a SIGHUP, is requesting the routes config file to be reloaded, if enabled
type WebhookConfig ¶
type WebhookNotifier ¶
type WebhookNotifier struct {
// contains filtered or unexported fields
}
WebhookNotifier implements ConnectionNotifier by sending a POST request to a webhook URL. The payload is a JSON object defined by WebhookNotifierPayload.
func NewWebhookNotifier ¶
func NewWebhookNotifier(url string, requireUser bool) *WebhookNotifier
func (*WebhookNotifier) NotifyConnected ¶
func (w *WebhookNotifier) NotifyConnected(ctx context.Context, clientAddr net.Addr, serverAddress string, playerInfo *PlayerInfo, backendHostPort string) error
func (*WebhookNotifier) NotifyDisconnected ¶
func (w *WebhookNotifier) NotifyDisconnected(ctx context.Context, clientAddr net.Addr, serverAddress string, playerInfo *PlayerInfo, backendHostPort string) error
func (*WebhookNotifier) NotifyFailedBackendConnection ¶
func (w *WebhookNotifier) NotifyFailedBackendConnection(ctx context.Context, clientAddr net.Addr, server string, playerInfo *PlayerInfo, backendHostPort string, err error) error
func (*WebhookNotifier) NotifyMissingBackend ¶
func (w *WebhookNotifier) NotifyMissingBackend(ctx context.Context, clientAddr net.Addr, server string, playerInfo *PlayerInfo) error
type WebhookNotifierPayload ¶
type WebhookNotifierPayload struct { Event string `json:"event"` Timestamp time.Time `json:"timestamp"` Status string `json:"status"` Client *ClientInfo `json:"client"` Server string `json:"server"` PlayerInfo *PlayerInfo `json:"player,omitempty"` BackendHostPort string `json:"backend,omitempty"` Error string `json:"error,omitempty"` }