#!/usr/bin/env python3 # # Copyright (C) 2017 VyOS maintainers and contributors # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 or later as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # import sys import os import fnmatch import subprocess from vyos.config import Config from vyos import ConfigError config_file = r'/etc/default/udp-broadcast-relay' def get_config(): conf = Config() conf.set_level("service broadcast-relay id") relay_id = conf.list_nodes("") relays = [] for id in relay_id: interface_list = [] address = conf.return_value("{0} address".format(id)) description = conf.return_value("{0} description".format(id)) port = conf.return_value("{0} port".format(id)) # split the interface name listing and form a list if conf.exists("{0} interface".format(id)): intfs_names = [] intfs_names = conf.return_values("{0} interface".format(id)) for name in intfs_names: interface_list.append(name) relay = { "id": id, "address": address, "description": description, "interfaces" : interface_list, "port": port } relays.append(relay) return relays def verify(relays): for relay in relays: if not relay["port"]: raise ConfigError("UDP broadcast relay 'id {0}' requires a port number".format(relay["id"])) if len(relay["interfaces"]) < 2: raise ConfigError("UDP broadcast relay 'id {0}' requires at least 2 interfaces".format(relay["id"])) return None def generate(relays): config_header = '### Autogenerated by bcast_relay.py ###\n' 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 id in active_configs[:]: os.unlink(config_file + id) for relay in relays: file = config_file + str(relay["id"]) interfaces = ' '.join(str(intf) for intf in relay["interfaces"]) config_args = 'DAEMON_ARGS="{0} {1}"\n'.format(relay["port"], interfaces) f = open(file, 'w') f.write(config_header) if relay["description"]: f.write('# ' + relay["description"] + '\n') f.write(config_args) f.close() return None def apply(relays): # first stop all running services cmd = "sudo systemctl stop udp-broadcast-relay@{1..99}" os.system(cmd) # start only required service instances for relay in relays: cmd = "sudo systemctl start udp-broadcast-relay@{0}".format(relay["id"]) os.system(cmd) return None if __name__ == '__main__': try: c = get_config() verify(c) generate(c) apply(c) except ConfigError as e: print(e) sys.exit(1)