summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzsdc <taras@vyos.io>2021-12-07 13:25:42 +0200
committerzsdc <taras@vyos.io>2021-12-07 14:26:22 +0200
commit1af618103f288d83c51dee3d20e49f06e02b1ac7 (patch)
tree6d700958e14d27ac0c5e5a48f3a37f43d6b79d37
parent76ac6e9885d587921ac6dc54a3bd056c5dc74b4d (diff)
downloadvyos-1x-1af618103f288d83c51dee3d20e49f06e02b1ac7.tar.gz
vyos-1x-1af618103f288d83c51dee3d20e49f06e02b1ac7.zip
FRR: T4020: Updated CLI options processing for FRR daemons
Instead of analyzing options for each daemon now we use a single template for the whole configuration file. This makes logic a bit less flexible, but much easier. Removed unnecessary check for returned by the `conf.get_config_dict(base)` config. Also, added the ability to disable `strip()` of file content while using `read_file()` what is necessary for proper comparing with updated content.
-rw-r--r--data/templates/frr/daemons.frr.tmpl50
-rw-r--r--python/vyos/util.py12
-rwxr-xr-xsrc/conf_mode/system_frr.py100
3 files changed, 67 insertions, 95 deletions
diff --git a/data/templates/frr/daemons.frr.tmpl b/data/templates/frr/daemons.frr.tmpl
new file mode 100644
index 000000000..089cdae3b
--- /dev/null
+++ b/data/templates/frr/daemons.frr.tmpl
@@ -0,0 +1,50 @@
+zebra=yes
+bgpd=yes
+ospfd=yes
+ospf6d=yes
+ripd=yes
+ripngd=yes
+isisd=yes
+pimd=no
+ldpd=yes
+nhrpd=no
+eigrpd=no
+babeld=no
+sharpd=no
+pbrd=no
+bfdd=yes
+staticd=yes
+
+vtysh_enable=yes
+zebra_options=" -s 90000000 --daemon -A 127.0.0.1
+{%- if irdp is defined %} -M irdp{% endif -%}
+{%- if snmp is defined and snmp.zebra is defined %} -M snmp{% endif -%}
+"
+bgpd_options=" --daemon -A 127.0.0.1
+{%- if bmp is defined %} -M bmp{% endif -%}
+{%- if snmp is defined and snmp.bgpd is defined %} -M snmp{% endif -%}
+"
+ospfd_options=" --daemon -A 127.0.0.1
+{%- if snmp is defined and snmp.ospfd is defined %} -M snmp{% endif -%}
+"
+ospf6d_options=" --daemon -A ::1
+{%- if snmp is defined and snmp.ospf6d is defined %} -M snmp{% endif -%}
+"
+ripd_options=" --daemon -A 127.0.0.1
+{%- if snmp is defined and snmp.ripd is defined %} -M snmp{% endif -%}
+"
+ripngd_options=" --daemon -A ::1"
+isisd_options=" --daemon -A 127.0.0.1"
+pimd_options=" --daemon -A 127.0.0.1"
+ldpd_options=" --daemon -A 127.0.0.1"
+nhrpd_options=" --daemon -A 127.0.0.1"
+eigrpd_options=" --daemon -A 127.0.0.1"
+babeld_options=" --daemon -A 127.0.0.1"
+sharpd_options=" --daemon -A 127.0.0.1"
+pbrd_options=" --daemon -A 127.0.0.1"
+staticd_options=" --daemon -A 127.0.0.1"
+bfdd_options=" --daemon -A 127.0.0.1"
+
+watchfrr_enable=no
+valgrind_enable=no
+
diff --git a/python/vyos/util.py b/python/vyos/util.py
index d8e83ab8d..ce5dc51f5 100644
--- a/python/vyos/util.py
+++ b/python/vyos/util.py
@@ -182,16 +182,20 @@ def call(command, flag='', shell=None, input=None, timeout=None, env=None,
return code
-def read_file(fname, defaultonfailure=None):
+def read_file(fname, defaultonfailure=None, strip_end=True):
"""
- read the content of a file, stripping any end characters (space, newlines)
+ read the content of a file, optionally stripping any end characters (space, newlines)
should defaultonfailure be not None, it is returned on failure to read
"""
try:
""" Read a file to string """
with open(fname, 'r') as f:
- data = f.read().strip()
- return data
+ data = f.read()
+
+ if strip_end:
+ return data.strip()
+ else:
+ return data
except Exception as e:
if defaultonfailure is not None:
return defaultonfailure
diff --git a/src/conf_mode/system_frr.py b/src/conf_mode/system_frr.py
index cc47aa5be..0d0b37e00 100755
--- a/src/conf_mode/system_frr.py
+++ b/src/conf_mode/system_frr.py
@@ -15,14 +15,13 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from pathlib import Path
-from re import compile as re_compile
-from re import M as re_M
from sys import exit
from vyos import ConfigError
from vyos import airbag
from vyos.config import Config
from vyos.logger import syslog
+from vyos.template import render_to_string
from vyos.util import read_file, write_file, run
airbag.enable()
@@ -38,31 +37,13 @@ def get_config(config=None):
conf = config
else:
conf = Config()
- base = ['system', 'frr']
- if not conf.exists(base):
- return {}
- frr_config = conf.get_config_dict(base)
+ base = ['system', 'frr']
+ frr_config = conf.get_config_dict(base, get_first_key=True)
return frr_config
-def daemons_config_parse(daemons_config):
- # create regex for parsing daemons options
- regex_daemon_config = re_compile(
- r'^(?P<daemon_name>\w+)_options="(?P<daemon_options>.*)"$', re_M)
- # create empty dict for config
- daemons_config_dict = {}
- # fill dictionary with actual config
- for daemon in regex_daemon_config.finditer(daemons_config):
- daemon_name = daemon.group('daemon_name')
- daemon_options = daemon.group('daemon_options')
- daemons_config_dict[daemon_name] = daemon_options
-
- # return daemons config
- return (daemons_config_dict)
-
-
def verify(frr_config):
# Nothing to verify here
pass
@@ -70,76 +51,13 @@ def verify(frr_config):
def generate(frr_config):
# read daemons config file
- daemons_config = read_file(config_file)
- daemons_config_current = daemons_config
- daemons_config_dict = daemons_config_parse(daemons_config)
-
- # configure SNMP integration
- frr_snmp = frr_config.get('frr', {}).get('snmp', {})
- # prepare regex for matching modules
- regex_snmp = re_compile(r'^.* -M snmp.*$')
- regex_bmp = re_compile(r'^.* -M bmp.*$')
- regex_irdp = re_compile(r'^.* -M irdp.*$')
- # check each daemon's config
- for (daemon_name, daemon_options) in daemons_config_dict.items():
- # check if SNMP integration is enabled in the config file
- snmp_enabled = regex_snmp.match(daemon_options)
- # check if BMP is enabled in the config file
- bmp_enabled = regex_bmp.match(daemon_options)
- # check if IRDP is enabled in the config file
- irdp_enabled = regex_irdp.match(daemon_options)
-
- # enable SNMP integration
- if daemon_name in frr_snmp and not snmp_enabled:
- daemon_options_new = f'{daemon_options} -M snmp'
- daemons_config = daemons_config.replace(
- f'{daemon_name}_options=\"{daemon_options}\"',
- f'{daemon_name}_options=\"{daemon_options_new}\"')
- daemon_options = daemon_options_new
- # disable SNMP integration
- if daemon_name not in frr_snmp and snmp_enabled:
- daemon_options_new = daemon_options.replace(' -M snmp', '')
- daemons_config = daemons_config.replace(
- f'{daemon_name}_options=\"{daemon_options}\"',
- f'{daemon_name}_options=\"{daemon_options_new}\"')
- daemon_options = daemon_options_new
-
- # enable BMP
- if daemon_name == 'bgpd' and 'bmp' in frr_config.get(
- 'frr', {}) and not bmp_enabled:
- daemon_options_new = f'{daemon_options} -M bmp'
- daemons_config = daemons_config.replace(
- f'{daemon_name}_options=\"{daemon_options}\"',
- f'{daemon_name}_options=\"{daemon_options_new}\"')
- daemon_options = daemon_options_new
- # disable BMP
- if daemon_name == 'bgpd' and 'bmp' not in frr_config.get(
- 'frr', {}) and bmp_enabled:
- daemon_options_new = daemon_options.replace(' -M bmp', '')
- daemons_config = daemons_config.replace(
- f'{daemon_name}_options=\"{daemon_options}\"',
- f'{daemon_name}_options=\"{daemon_options_new}\"')
- daemon_options = daemon_options_new
-
- # enable IRDP
- if daemon_name == 'zebra' and 'irdp' in frr_config.get(
- 'frr', {}) and not irdp_enabled:
- daemon_options_new = f'{daemon_options} -M irdp'
- daemons_config = daemons_config.replace(
- f'{daemon_name}_options=\"{daemon_options}\"',
- f'{daemon_name}_options=\"{daemon_options_new}\"')
- daemon_options = daemon_options_new
- # disable IRDP
- if daemon_name == 'zebra' and 'irdp' not in frr_config.get(
- 'frr', {}) and irdp_enabled:
- daemon_options_new = daemon_options.replace(' -M irdp', '')
- daemons_config = daemons_config.replace(
- f'{daemon_name}_options=\"{daemon_options}\"',
- f'{daemon_name}_options=\"{daemon_options_new}\"')
-
+ daemons_config_current = read_file(config_file, strip_end=False)
+ # generate new config file
+ daemons_config_new = render_to_string('frr/daemons.frr.tmpl', frr_config)
# update configuration file if this is necessary
- if daemons_config != daemons_config_current:
- write_file(config_file, daemons_config)
+ if daemons_config_new != daemons_config_current:
+ syslog.warning('FRR daemons configuration file need to be changed')
+ write_file(config_file, daemons_config_new)
frr_config['config_file_changed'] = True