Add configuration option for the metric server interface (#25)

Add a configuration option `interface` to allow configuring where the
HTTP metric server should bind to.
This commit is contained in:
Lars Strojny 2022-11-17 13:15:07 +01:00 committed by GitHub
parent 04706f69d5
commit 261fa74ac9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 31 additions and 7 deletions

View file

@ -134,6 +134,11 @@ Once *Prometheus* is restarted, metrics with the `homebridge_` prefix should sta
// TCP port where the Prometheus metrics server listens. Default: 36123
"port": number,
// Interface where the Prometheus metrics server listens. Default: "::" which means "any interface".
// Can be an IP, a hostname, "0.0.0.0" for all IPv4 interfaces, "::1" for all IPv6 interfaces.
// Default is "::" which means any interface
"interface": string,
// How frequently the services should be rediscovered (in seconds). Default: 60
"refresh_interval": number,

View file

@ -26,12 +26,18 @@
"default": "homebridge"
},
"port": {
"title": "Probe server port",
"description": "TCP port for the prometheus probe server to listen to",
"title": "Metrics server port",
"description": "TCP port where the Prometheus metrics server listens",
"type": "integer",
"required": false,
"default": 36123
},
"interface": {
"title": "Metrics server interface",
"description": "Interface where the Prometheus metrics server listens. Can be an IP, a hostname, \"0.0.0.0\" for all IPv4 interfaces, \"::1\" for all IPv6 interfaces. Default is \"::\" which means \"any interface\"",
"type": "string",
"default": "::"
},
"refresh_interval": {
"title": "Service refresh interval",
"description": "Discover new services every <interval> seconds",
@ -54,17 +60,20 @@
"default": 20
},
"tls_cert_file": {
"title": "TLS cert file",
"description": "Path to TLS certificate file (in PEM format)",
"type": "string",
"required": false
},
"tls_key_file": {
"title": "TLS key file",
"description": "Path to TLS key file",
"type": "string",
"required": false
},
"basic_auth": {
"description": "Usernames and passwords for basic auth. Key is the username, value is the password. Password must be encoded with bcrypt",
"title": "Basic auth username/password pairs",
"description": "Usernames and passwords for basic auth. Object key is the username, object value is the password. Password must be encoded with bcrypt. Example: {\"joanna\": \"$2a$12$5/mmmRB28wg9yzaXhee5Iupq3UrFr/qMgAe9LvAxGoY5jLcfVGTUq\"}",
"type": "object",
"additionalProperties": { "type": "string" },
"required": false

View file

@ -15,7 +15,10 @@ export interface HttpServerController {
export type HttpAdapter = (config: HttpServer) => Promise<HttpServerController>
export type HttpConfig = Pick<Config, 'debug' | 'port' | 'prefix' | 'basic_auth' | 'tls_cert_file' | 'tls_key_file'>
export type HttpConfig = Pick<
Config,
'debug' | 'port' | 'interface' | 'prefix' | 'basic_auth' | 'tls_cert_file' | 'tls_key_file'
>
export interface HttpServer {
log?: Logger

View file

@ -97,7 +97,7 @@ export const fastifyServe: HttpAdapter = async (server: HttpServer) => {
adaptResponseToReply(server.onMetrics(), reply)
})
await listen(fastify, server.config.port, '::')
await listen(fastify, server.config.port, server.config.interface)
return {
shutdown() {

View file

@ -6,7 +6,13 @@ export const ConfigBoundary = z.object({
pin: z.string().regex(new RegExp('^\\d{3}-\\d{2}-\\d{3}$')).describe('Homebridge PIN for service authentication'),
debug: z.boolean().default(false),
prefix: z.string().default('homebridge'),
port: z.number().int().describe('TCP port for the prometheus probe server to listen to').default(36123),
port: z.number().int().describe('TCP port where the Prometheus metrics server listens').default(36123),
interface: z
.string()
.describe(
'Interface where the Prometheus metrics server listens. Can be an IP, a hostname, "0.0.0.0" for all IPv4 interfaces, "::1" for all IPv6 interfaces. Default is "::" which means "any interface"',
)
.default('::'),
refresh_interval: z.number().int().describe('Discover new services every <interval> seconds').default(60),
request_timeout: z
.number()
@ -23,7 +29,7 @@ export const ConfigBoundary = z.object({
basic_auth: z
.record(z.string())
.describe(
'Usernames and passwords for basic auth. Key is the username, value is the password. Password must be encoded with bcrypt',
'Usernames and passwords for basic auth. Object key is the username, object value is the password. Password must be encoded with bcrypt. Example: {"joanna": "$2a$12$5/mmmRB28wg9yzaXhee5Iupq3UrFr/qMgAe9LvAxGoY5jLcfVGTUq"}',
)
.optional(),
})

View file

@ -17,6 +17,7 @@ function createTestServerWithBasicAuth(basicAuth: Record<string, string>): { htt
const http = createServer()
const prometheus = new TestablePrometheusServer({
port: 0,
interface: 'localhost',
debug: false,
prefix: 'homebridge',
basic_auth: basicAuth,