summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Poessinger <christian@poessinger.com>2020-07-19 10:51:00 +0200
committerChristian Poessinger <christian@poessinger.com>2020-07-19 10:51:00 +0200
commitdadb09fd14046720e7898c3cbad8c5def408db9d (patch)
treeaefae9962f7fdfe2969ab7483f64a1a6dbc90b4f
parentdaa810f81ce03cc0f51dfd810507d4b2c9ec0428 (diff)
downloadvyos-1x-dadb09fd14046720e7898c3cbad8c5def408db9d.tar.gz
vyos-1x-dadb09fd14046720e7898c3cbad8c5def408db9d.zip
broadcast-relay: T2712: migrate to get_config_dict()
Add additional verify() stage to check that the relaying interface actually exists on the system.
-rw-r--r--data/templates/bcast-relay/udp-broadcast-relay.tmpl2
-rwxr-xr-xsrc/conf_mode/bcast_relay.py135
2 files changed, 35 insertions, 102 deletions
diff --git a/data/templates/bcast-relay/udp-broadcast-relay.tmpl b/data/templates/bcast-relay/udp-broadcast-relay.tmpl
index 3d8c3fe94..d0c7d8bf9 100644
--- a/data/templates/bcast-relay/udp-broadcast-relay.tmpl
+++ b/data/templates/bcast-relay/udp-broadcast-relay.tmpl
@@ -4,4 +4,4 @@
{%- if description %}
# Comment: {{ description }}
{% endif %}
-DAEMON_ARGS="{% if address %}-s {{ address }} {% endif %}{{ id }} {{ port }} {{ interfaces | join(' ') }}"
+DAEMON_ARGS="{{ '-s ' + address if address is defined }} {{ instance }} {{ port }} {{ interface | join(' ') }}"
diff --git a/src/conf_mode/bcast_relay.py b/src/conf_mode/bcast_relay.py
index 5c7294296..a3e141a00 100755
--- a/src/conf_mode/bcast_relay.py
+++ b/src/conf_mode/bcast_relay.py
@@ -15,151 +15,84 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
-import fnmatch
+from glob import glob
+from netifaces import interfaces
from sys import exit
-from copy import deepcopy
from vyos.config import Config
-from vyos import ConfigError
from vyos.util import call
from vyos.template import render
-
+from vyos import ConfigError
from vyos import airbag
airbag.enable()
-config_file = r'/etc/default/udp-broadcast-relay'
-
-default_config_data = {
- 'disabled': False,
- 'instances': []
-}
+config_file_base = r'/etc/default/udp-broadcast-relay'
def get_config():
- relay = deepcopy(default_config_data)
conf = Config()
base = ['service', 'broadcast-relay']
- if not conf.exists(base):
- return None
- else:
- conf.set_level(base)
-
- # Service can be disabled by user
- if conf.exists('disable'):
- relay['disabled'] = True
- return relay
-
- # Parse configuration of each individual instance
- if conf.exists('id'):
- for id in conf.list_nodes('id'):
- conf.set_level(base + ['id', id])
- config = {
- 'id': id,
- 'disabled': False,
- 'address': '',
- 'description': '',
- 'interfaces': [],
- 'port': ''
- }
-
- # Check if individual broadcast relay service is disabled
- if conf.exists(['disable']):
- config['disabled'] = True
-
- # Source IP of forwarded packets, if empty original senders address is used
- if conf.exists(['address']):
- config['address'] = conf.return_value(['address'])
-
- # A description for each individual broadcast relay service
- if conf.exists(['description']):
- config['description'] = conf.return_value(['description'])
-
- # UDP port to listen on for broadcast frames
- if conf.exists(['port']):
- config['port'] = conf.return_value(['port'])
-
- # Network interfaces to listen on for broadcast frames to be relayed
- if conf.exists(['interface']):
- config['interfaces'] = conf.return_values(['interface'])
-
- relay['instances'].append(config)
-
+ relay = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)
return relay
def verify(relay):
- if relay is None:
- return None
-
- if relay['disabled']:
+ if not relay or 'disabled' in relay:
return None
- for r in relay['instances']:
+ for instance, config in relay.get('id', {}).items():
# we don't have to check this instance when it's disabled
- if r['disabled']:
+ if 'disabled' in config:
continue
# we certainly require a UDP port to listen to
- if not r['port']:
- raise ConfigError('UDP broadcast relay "{0}" requires a port number'.format(r['id']))
+ if 'port' not in config:
+ raise ConfigError(f'Port number mandatory for udp broadcast relay "{instance}"')
+ # if only oone interface is given it's a string -> move to list
+ if isinstance(config.get('interface', []), str):
+ config['interface'] = [ config['interface'] ]
# Relaying data without two interface is kinda senseless ...
- if len(r['interfaces']) < 2:
- raise ConfigError('UDP broadcast relay "id {0}" requires at least 2 interfaces'.format(r['id']))
+ if len(config.get('interface', [])) < 2:
+ raise ConfigError('At least two interfaces are required for udp broadcast relay "{instance}"')
- return None
+ for interface in config.get('interface', []):
+ if interface not in interfaces():
+ raise ConfigError('Interface "{interface}" does not exist!')
+ return None
def generate(relay):
- if relay is None:
+ if not relay or 'disabled' in relay:
return None
- config_dir = os.path.dirname(config_file)
- config_filename = os.path.basename(config_file)
- active_configs = []
-
- for config in fnmatch.filter(os.listdir(config_dir), config_filename + '*'):
- # determine prefix length to identify service instance
- prefix_len = len(config_filename)
- active_configs.append(config[prefix_len:])
-
- # sort our list
- active_configs.sort()
+ for config in glob(config_file_base + '*'):
+ os.remove(config)
- # delete old configuration files
- for id in active_configs[:]:
- if os.path.exists(config_file + id):
- os.unlink(config_file + id)
-
- # If the service is disabled, we can bail out here
- if relay['disabled']:
- print('Warning: UDP broadcast relay service will be deactivated because it is disabled')
- return None
-
- for r in relay['instances']:
- # Skip writing instance config when it's disabled
- if r['disabled']:
+ for instance, config in relay.get('id').items():
+ # we don't have to check this instance when it's disabled
+ if 'disabled' in config:
continue
- # configuration filename contains instance id
- file = config_file + str(r['id'])
- render(file, 'bcast-relay/udp-broadcast-relay.tmpl', r)
+ config['instance'] = instance
+ render(config_file_base + instance, 'bcast-relay/udp-broadcast-relay.tmpl', config)
return None
def apply(relay):
# first stop all running services
- call('systemctl stop udp-broadcast-relay@{1..99}.service')
+ call('systemctl stop udp-broadcast-relay@*.service')
- if (relay is None) or relay['disabled']:
+ if not relay or 'disable' in relay:
return None
# start only required service instances
- for r in relay['instances']:
- # Don't start individual instance when it's disabled
- if r['disabled']:
+ for instance, config in relay.get('id').items():
+ # we don't have to check this instance when it's disabled
+ if 'disabled' in config:
continue
- call('systemctl start udp-broadcast-relay@{0}.service'.format(r['id']))
+
+ call(f'systemctl start udp-broadcast-relay@{instance}.service')
return None