DEV(cache_critical_dns): add additional service runtime variable

We'd like to lean on the DNS caching service for more than the standard
DB and Redis hosts, but without having to add additional code each time.
Define a new environment variable
DISCOURSE_DNS_CACHE_ADDITIONAL_SERVICE_NAMES (admittedly a mouthful)
which is a list of service names to be added to the static list at
process execution time.

For example, plugin foo may reference two services that you want to
cache the address of. By specifying the following two variables in the
process environment, cache_critical_dns will perform the lookup
alongside the DB and Redis host variables.

```
DISCOURSE_DNS_CACHE_ADDITIONAL_SERVICE_NAMES='FOO_SERVICE1,FOO_SERVICE2'
FOO_SERVICE1='foo.service1.example.com'
FOO_SERVICE1_SRV='foo._tcp.example.com'
FOO_SERVICE2='foo.service2.example.com'
```

The behaviour when it comes to SRV record lookup is the same as
previously implemented for the `DISCOURSE_DB_..` and
`DISCOURSE_REDIS_..` variables.

For the purposes of the health checks, services defined in the list _are
always considered healthy_. This is a compromise for conveniences sake.
Defining a dynamic method for health checks at runtime is not practical.

See t/88457/32.
This commit is contained in:
Michael Fitz-Payne 2023-01-19 14:12:25 +10:00 committed by Michael Fitz-Payne
parent b00e160dae
commit df4a9f96ae

View File

@ -15,6 +15,18 @@ require 'optparse'
# service in the process environment. Any hosts that fail the healthcheck will # service in the process environment. Any hosts that fail the healthcheck will
# never be cached. # never be cached.
# #
# The list of environment variables that cache_critical_dns will read for
# critical service hostnames can be extended at process execution time by
# specifying environment variable names within the
# DISCOURSE_DNS_CACHE_ADDITIONAL_SERVICE_NAMES environment variable. This is a
# comma-delimited string of extra environment variables to be added to the list
# defined in the static CRITICAL_HOST_ENV_VARS hash.
#
# DISCOURSE_DNS_CACHE_ADDITIONAL_SERVICE_NAMES serves as a kind of lookup table
# for extra services for caching. Any environment variable names within this
# list are treated with the same rules as the DISCOURSE_DB_HOST (and co.)
# variables, as described below.
#
# This is as far as you need to read if you are using CNAME or A records for # This is as far as you need to read if you are using CNAME or A records for
# your services. # your services.
# #
@ -88,7 +100,11 @@ CRITICAL_HOST_ENV_VARS = %w{
DISCOURSE_REDIS_REPLICA_HOST DISCOURSE_REDIS_REPLICA_HOST
DISCOURSE_MESSAGE_BUS_REDIS_HOST DISCOURSE_MESSAGE_BUS_REDIS_HOST
DISCOURSE_MESSAGE_BUS_REDIS_REPLICA_HOST DISCOURSE_MESSAGE_BUS_REDIS_REPLICA_HOST
} }.union(
ENV.fetch('DISCOURSE_DNS_CACHE_ADDITIONAL_SERVICE_NAMES', '')
.split(',')
.map(&:strip)
)
DEFAULT_DB_NAME = "discourse" DEFAULT_DB_NAME = "discourse"
DEFAULT_REDIS_PORT = 6379 DEFAULT_REDIS_PORT = 6379
@ -243,7 +259,10 @@ ensure
client.close if client client.close if client
end end
HEALTH_CHECKS = { HEALTH_CHECKS = Hash.new(
# unknown keys (like services defined at runtime) are assumed to be healthy
lambda { |addr| true }
).merge!({
"DISCOURSE_DB_HOST": lambda { |addr| "DISCOURSE_DB_HOST": lambda { |addr|
postgres_healthcheck( postgres_healthcheck(
host: addr, host: addr,
@ -274,7 +293,7 @@ HEALTH_CHECKS = {
host: addr, host: addr,
port: env_as_int("DISCOURSE_MESSAGE_BUS_REDIS_REPLICA_PORT", DEFAULT_REDIS_PORT), port: env_as_int("DISCOURSE_MESSAGE_BUS_REDIS_REPLICA_PORT", DEFAULT_REDIS_PORT),
password: ENV["DISCOURSE_MESSAGE_BUS_REDIS_PASSWORD"])}, password: ENV["DISCOURSE_MESSAGE_BUS_REDIS_PASSWORD"])},
} })
def log(msg) def log(msg)
STDERR.puts "#{Time.now.utc.iso8601}: #{msg}" STDERR.puts "#{Time.now.utc.iso8601}: #{msg}"