Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removed the need for dummy IP prefix. #26

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 0 additions & 14 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,6 @@ A list of IP prefixes (<IP>/<prefix length>) is stored in a text file. IP prefix

This configuration logic allows a separate process to update the list by adding or removing IP prefixes and trigger a reconfiguration of Bird in order to advertise or withdraw routes. **anycast-healthchecker** is that separate process. It monitors Anycasted services and, based on the status of the health checks, updates the list of IP prefixes.

Bird does not allow the definition of a list with no elements: if that happens Bird will produce an error and refuses to start. Because of this, anycast-healthchecker makes sure that there is always an IP prefix in the list, see ``dummy_ip_prefix`` and ``dummy_ip6_prefix`` settings in `Daemon section`_.

Configuring anycast-healthchecker
---------------------------------

Expand Down Expand Up @@ -181,8 +179,6 @@ anycast-prefixes.conf
10.189.200.255/32
];

anycast-healthchecker removes IP prefixes from the list for which a service check is not configured. But, the IP prefix set in ``dummy_ip_prefix`` does not need a service check configuration.

This the equivalent list for IPv6 prefixes::

define ACAST6_PS_ADVERTISE =
Expand Down Expand Up @@ -227,8 +223,6 @@ anycast-healthchecker uses the popular `INI`_ format for its configuration files
bird6_variable = ACAST6_PS_ADVERTISE
bird_reconfigure_cmd = sudo /usr/sbin/birdc configure
bird6_reconfigure_cmd = sudo /usr/sbin/birdc6 configure
dummy_ip_prefix = 10.189.200.255/32
dummy_ip6_prefix = 2001:db8::1/128
bird_keep_changes = false
bird6_keep_changes = false
bird_changes_counter = 128
Expand Down Expand Up @@ -302,14 +296,6 @@ Command to trigger a reconfiguration of IPv4 Bird daemon

Command to trigger a reconfiguration of IPv6 Bird daemon

* **dummy_ip_prefix** Defaults to **10.189.200.255/32**

An IP prefix in the form <IP>/<prefix length> which will be always available in the list defined by ``bird_variable`` to avoid having an empty list. The ``dummy_ip_prefix`` **must not** be used by any service or assigned to the interface set with ``interface`` or configured anywhere on the network as anycast-healthchecker **does not** perform any checks for it.

* **dummy_ip6_prefix** Defaults to **2001:db8::1/128**

An IPv6 prefix in the form <IPv6>/<prefix length> which will be always available in the list defined by ``bird6_variable`` to avoid having an empty list. The ``dummy_ip6_prefix`` **must not** be used by any service or assigned to the interface set with ``interface`` or configured anywhere on the network as anycast-healthchecker **does not** perform any checks for it.

* **bird_keep_changes** Defaults to **false**

Keep a history of changes for ``bird_conf`` file by copying it to a directory. During the startup of anycast-healthchecker a directory with the name ``history`` is created under the directory where ``bird_conf`` file resides. The daemon has to have sufficient privileges to create that directory.
Expand Down
2 changes: 0 additions & 2 deletions anycast-healthchecker.conf
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ bird_variable = ACAST_PS_ADVERTISE
bird6_variable = ACAST6_PS_ADVERTISE
bird_reconfigure_cmd = sudo /usr/sbin/birdc configure
bird6_reconfigure_cmd = sudo /usr/sbin/birdc6 configure
dummy_ip_prefix = 10.189.200.255/32
dummy_ip6_prefix = 2001:db8::1/128
bird_keep_changes = false
bird6_keep_changes = false
bird_changes_counter = 128
Expand Down
2 changes: 0 additions & 2 deletions anycast_healthchecker/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@
'bird6_variable': 'ACAST6_PS_ADVERTISE',
'bird_reconfigure_cmd': 'sudo /usr/sbin/birdc configure',
'bird6_reconfigure_cmd': 'sudo /usr/sbin/birdc6 configure',
'dummy_ip_prefix': '10.189.200.255/32',
'dummy_ip6_prefix': '2001:db8::1/128',
'bird_keep_changes': 'false',
'bird6_keep_changes': 'false',
'bird_changes_counter': 128,
Expand Down
21 changes: 1 addition & 20 deletions anycast_healthchecker/healthchecker.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,6 @@ def __init__(self, config, bird_configuration):
self.services,
ip_version)

_ip_prefixes.add(
self.bird_configuration[ip_version]['dummy_ip_prefix']
)
self.ip_prefixes[ip_version] = _ip_prefixes

self.log.info('initialize healthchecker')
Expand All @@ -97,8 +94,6 @@ def _update_bird_conf_file(self, operation):
variable_name = self.bird_configuration[ip_version]['variable_name']
changes_counter =\
self.bird_configuration[ip_version]['changes_counter']
dummy_ip_prefix =\
self.bird_configuration[ip_version]['dummy_ip_prefix']

try:
prefixes = get_ip_prefixes_from_bird(config_file)
Expand All @@ -107,18 +102,6 @@ def _update_bird_conf_file(self, operation):
"FATAL error, thus exiting main program", error)
sys.exit(1)

if not prefixes:
self.log.error("found empty bird configuration %s, this is a FATAL"
" error, thus exiting main program", config_file)
sys.exit(1)

if dummy_ip_prefix not in prefixes:
self.log.warning("dummy IP prefix %s wasn't found in bird "
"configuration, adding it. This shouldn't have "
"happened!", dummy_ip_prefix)
prefixes.insert(0, dummy_ip_prefix)
conf_updated = True

ip_prefixes_without_check = set(prefixes).difference(
self.ip_prefixes[ip_version])
if ip_prefixes_without_check:
Expand Down Expand Up @@ -149,7 +132,6 @@ def _update_bird_conf_file(self, operation):
# some IP prefixes are either removed or added, create
# configuration with new data.
tempname = write_temp_bird_conf(
dummy_ip_prefix,
config_file,
variable_name,
prefixes
Expand All @@ -165,8 +147,7 @@ def _update_bird_conf_file(self, operation):
self.log.info("Bird configuration for IPv%s is updated",
ip_version)

# dummy_ip_prefix is always there
if len(prefixes) == 1:
if len(prefixes) == 0:
self.log.warning("Bird configuration doesn't have IP prefixes for "
"any of the services we monitor! It means local "
"node doesn't receive any traffic")
Expand Down
48 changes: 10 additions & 38 deletions anycast_healthchecker/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,6 @@ def ip_prefixes_sanity_check(config, bird_configuration):
modify_ip_prefixes(config,
bird_configuration[ip_version]['config_file'],
bird_configuration[ip_version]['variable_name'],
bird_configuration[ip_version]['dummy_ip_prefix'],
bird_configuration[ip_version]['reconfigure_cmd'],
bird_configuration[ip_version]['keep_changes'],
bird_configuration[ip_version]['changes_counter'],
Expand All @@ -169,7 +168,6 @@ def modify_ip_prefixes(
config,
config_file,
variable_name,
dummy_ip_prefix,
reconfigure_cmd,
keep_changes,
changes_counter,
Expand All @@ -178,14 +176,12 @@ def modify_ip_prefixes(

Depending on the configuration either removes or reports IP prefixes found
in Bird configuration for which we don't have a service check associated
with them. Moreover, it adds the dummy IP prefix if it isn't present and
ensures that the correct variable name is set.
with them. Moreover, it ensures that the correct variable name is set.

Arguments:
config (obg): A configparser object which holds our configuration.
config_file (str): The file name of bird configuration
variable_name (str): The name of the variable set in bird configuration
dummy_ip_prefix (str): The dummy IP prefix, which must be always
reconfigure_cmd (str): The command to run to trigger a reconfiguration
on Bird daemon upon successful configuration update
keep_changes (boolean): To enable keeping a history of changes applied
Expand Down Expand Up @@ -215,19 +211,11 @@ def modify_ip_prefixes(
"correct one %s", _name, variable_name)
update_bird_conf = True

if dummy_ip_prefix not in ip_prefixes_in_bird:
log.warning("dummy IP prefix %s is missing from bird configuration "
"%s, adding it", dummy_ip_prefix, config_file)
ip_prefixes_in_bird.insert(0, dummy_ip_prefix)
update_bird_conf = True

# Find IP prefixes in Bird configuration without a check.
ip_prefixes_with_check = get_ip_prefixes_from_config(
config,
services,
ip_version)
# dummy_ip_prefix doesn't have a config by design
ip_prefixes_with_check.add(dummy_ip_prefix)

ip_prefixes_without_check = set(ip_prefixes_in_bird).difference(
ip_prefixes_with_check)
Expand All @@ -251,7 +239,6 @@ def modify_ip_prefixes(
if keep_changes:
archive_bird_conf(config_file, changes_counter)
tempname = write_temp_bird_conf(
dummy_ip_prefix,
config_file,
variable_name,
ip_prefixes_in_bird
Expand Down Expand Up @@ -344,7 +331,7 @@ def configuration_check(config):
# Catch the case where the directory, under which we store the pid file, is
# missing.
if not os.path.isdir(os.path.dirname(pidfile)):
raise ValueError("{d} doesn't exit".format(d=os.path.dirname(pidfile)))
raise ValueError("{d} doesn't exist".format(d=os.path.dirname(pidfile)))

if not isinstance(num_level, int):
raise ValueError('Invalid log level: {}'.format(log_level))
Expand Down Expand Up @@ -481,15 +468,9 @@ def build_bird_configuration(config):
else:
config_file = config.get('daemon', 'bird_conf')

dummy_ip_prefix = config.get('daemon', 'dummy_ip_prefix')
if not valid_ip_prefix(dummy_ip_prefix):
raise ValueError("invalid dummy IPv4 prefix: {i}"
.format(i=dummy_ip_prefix))

bird_configuration[4] = {
'config_file': config_file,
'variable_name': config.get('daemon', 'bird_variable'),
'dummy_ip_prefix': dummy_ip_prefix,
'reconfigure_cmd': config.get('daemon', 'bird_reconfigure_cmd'),
'keep_changes': config.getboolean('daemon', 'bird_keep_changes'),
'changes_counter': config.getint('daemon', 'bird_changes_counter')
Expand All @@ -503,14 +484,9 @@ def build_bird_configuration(config):
else:
config_file = config.get('daemon', 'bird6_conf')

dummy_ip_prefix = config.get('daemon', 'dummy_ip6_prefix')
if not valid_ip_prefix(dummy_ip_prefix):
raise ValueError("invalid dummy IPv6 prefix: {i}"
.format(i=dummy_ip_prefix))
bird_configuration[6] = {
'config_file': config_file,
'variable_name': config.get('daemon', 'bird6_variable'),
'dummy_ip_prefix': dummy_ip_prefix,
'reconfigure_cmd': config.get('daemon', 'bird6_reconfigure_cmd'),
'keep_changes': config.getboolean('daemon', 'bird6_keep_changes'),
'changes_counter': config.getint('daemon', 'bird6_changes_counter')
Expand Down Expand Up @@ -778,16 +754,14 @@ def reconfigure_bird(cmd):
"broken:%s", output)


def write_temp_bird_conf(dummy_ip_prefix,
config_file,
def write_temp_bird_conf(config_file,
variable_name,
prefixes):
"""Write in a temporary file the list of IP-Prefixes.

A failure to create and write the temporary file will exit main program.

Arguments:
dummy_ip_prefix (str): The dummy IP prefix, which must be always
config_file (str): The file name of bird configuration
variable_name (str): The name of the variable set in bird configuration
prefixes (list): The list of IP-Prefixes to write
Expand All @@ -797,8 +771,6 @@ def write_temp_bird_conf(dummy_ip_prefix,

"""
log = logging.getLogger(PROGRAM_NAME)
comment = ("# {i} is a dummy IP Prefix. It should NOT be used and "
"REMOVED from the constant.".format(i=dummy_ip_prefix))

# the temporary file must be on the same filesystem as the bird config
# as we use os.rename to perform an atomic update on the bird config.
Expand All @@ -812,13 +784,13 @@ def write_temp_bird_conf(dummy_ip_prefix,
.format(t=datetime.datetime.now(),
n=PROGRAM_NAME,
p=os.getpid()))
tmpf.write("{c}\n".format(c=comment))
tmpf.write("define {n} =\n".format(n=variable_name))
tmpf.write("{s}[\n".format(s=4 * ' '))
# all entries of the array need a trailing comma except the last
# one. A single element array doesn't need a trailing comma.
tmpf.write(',\n'.join([' '*8 + n for n in prefixes]))
tmpf.write("\n{s}];\n".format(s=4 * ' '))
tmpf.write("define {n} = ".format(n=variable_name))
if len(prefixes) == 0:
tmpf.write("false;\n")
else:
tmpf.write("\n{s}[\n".format(s=4 * ' '))
tmpf.write(',\n'.join([' ' * 8 + n for n in prefixes]))
tmpf.write("\n{s}];\n".format(s=4 * ' '))
except OSError as error:
log.critical("failed to write temporary file %s: %s. This is a FATAL "
"error, this exiting main program", tm_file, error)
Expand Down
16 changes: 0 additions & 16 deletions contrib/puppet/anycast_healthchecker/manifests/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -55,20 +55,6 @@
# [*configuration_file*]
# Read settings for the daemon from
#
# [*dummy_ip_prefix*]
# An IP prefix in the form <IP>/<prefix length> which will be always available in
# the list defined by ``bird_variable`` to avoid having an empty list.
# The ``dummy_ip_prefix`` **must not** be used by any service or assigned to the
# interface set with ``interface`` or configured anywhere on the network as
# anycast-healthchecker **does not** perform any checks for it.
#
# [*dummy_ip6_prefix*]
# An IPv6 prefix in the form <IPv6>/<prefix length> which will be always
# available in the list defined by ``bird6_variable`` to avoid having an empty
# list. The ``dummy_ip6_prefix`` **must not** be used by any service or assigned
# to the interface set with ``interface`` or configured anywhere on the network as
# anycast-healthchecker **does not** perform any checks for it.
#
# [*group*]
# Set the UNIX group that anycast-healthchecker is executed.
# WARNING: Group must exist in the system.
Expand Down Expand Up @@ -167,8 +153,6 @@
$bird6_changes_counter = $::anycast_healthchecker::params::bird6_changes_counter,
$configuration_dir = $::anycast_healthchecker::params::configuration_dir,
$configuration_file = $::anycast_healthchecker::params::configuration_file,
$dummy_ip_prefix = $::anycast_healthchecker::params::dummy_ip_prefix,
$dummy_ip6_prefix = $::anycast_healthchecker::params::dummy_ip6_prefix,
$group = $::anycast_healthchecker::params::group,
$http_server = $::anycast_healthchecker::params::http_server,
$http_server_port = $::anycast_healthchecker::params::http_server_port,
Expand Down
2 changes: 0 additions & 2 deletions contrib/puppet/anycast_healthchecker/manifests/params.pp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
$bird6_changes_counter = 128
$configuration_dir = '/etc/anycast-healthchecker.d'
$configuration_file = '/etc/anycast-healthchecker.conf'
$dummy_ip_prefix = '10.189.200.255/32'
$dummy_ip6_prefix = '2001:db8::1/128'
$group = 'healthchecker'
$http_server = '127.0.0.1'
$http_server_port = 2813
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,13 @@ log_backups = <%= @log_backups %>
log_file = <%= @log_file %>
stderr_file = <%= @stderr_file %>
stdout_file = <%= @stdout_file %>
dummy_ip_prefix = <%= @dummy_ip_prefix %>
<%- if @ipv6 -%>
ipv6 = <%= @ipv6 %>
bird6_conf = <%= @bird6_conf %>
bird6_variable = <%= @bird6_variable %>
bird6_reconfigure_cmd = <%= @bird6_reconfigure_cmd %>
bird6_keep_changes = <%= @bird6_keep_changes %>
bird6_changes_counter = <%= @bird6_changes_counter %>
dummy_ip6_prefix = <%= @dummy_ip6_prefix %>
<%- end -%>
<%- if @json_logging -%>
json_logging = true
Expand Down
2 changes: 0 additions & 2 deletions debian/patches/anycast-healthchecker.conf.patch
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ index 35f08bc..bc9fea7 100644
-bird6_reconfigure_cmd = sudo /usr/sbin/birdc6 configure
+bird_reconfigure_cmd = /usr/sbin/birdc configure
+bird6_reconfigure_cmd = /usr/sbin/birdc6 configure
dummy_ip_prefix = 10.189.200.255/32
dummy_ip6_prefix = 2001:db8::1/128
bird_keep_changes = false
@@ -18,7 +18,7 @@ bird6_keep_changes = false
bird_changes_counter = 128
Expand Down
2 changes: 0 additions & 2 deletions local_run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,10 @@ bird_variable = ACAST_PS_ADVERTISE
bird_keep_changes = true
bird_changes_counter = 6
bird_reconfigure_cmd = /usr/bin/sudo /usr/sbin/birdc configure
dummy_ip_prefix = 10.189.200.255/32

ipv6 = true
bird6_conf = ${TEST_DIR}/var/lib/anycast-healthchecker/6/anycast-prefixes.conf
bird6_variable = ACAST6_PS_ADVERTISE
dummy_ip6_prefix = 2001:db8::1/128
bird6_reconfigure_cmd = sudo /usr/sbin/birdc6 configure
bird6_keep_changes = true
bird6_changes_counter = 6
Expand Down