diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/conf_mode/bcast_relay.py | 3 | ||||
-rwxr-xr-x | src/conf_mode/dhcpv6_server.py | 26 | ||||
-rwxr-xr-x | src/conf_mode/dns_forwarding.py | 16 | ||||
-rwxr-xr-x | src/conf_mode/intel_qat.py | 2 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-bonding.py | 6 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-bridge.py | 23 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-openvpn.py | 3 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-tunnel.py | 3 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-wireless.py | 8 | ||||
-rwxr-xr-x | src/conf_mode/protocols_mpls.py | 42 | ||||
-rwxr-xr-x | src/conf_mode/service_pppoe-server.py | 101 | ||||
-rwxr-xr-x | src/conf_mode/system-login.py | 4 | ||||
-rwxr-xr-x | src/conf_mode/system-syslog.py | 6 | ||||
-rwxr-xr-x | src/conf_mode/system-timezone.py | 1 | ||||
-rwxr-xr-x | src/conf_mode/tftp_server.py | 72 | ||||
-rwxr-xr-x | src/conf_mode/vpn_sstp.py | 346 | ||||
-rwxr-xr-x | src/migration-scripts/pppoe-server/1-to-2 | 37 | ||||
-rwxr-xr-x | src/migration-scripts/pppoe-server/2-to-3 | 117 | ||||
-rwxr-xr-x | src/migration-scripts/pppoe-server/3-to-4 | 104 | ||||
-rwxr-xr-x | src/services/vyos-configd | 6 |
20 files changed, 330 insertions, 596 deletions
diff --git a/src/conf_mode/bcast_relay.py b/src/conf_mode/bcast_relay.py index 4a47b9246..78daeb6be 100755 --- a/src/conf_mode/bcast_relay.py +++ b/src/conf_mode/bcast_relay.py @@ -78,7 +78,8 @@ def generate(relay): continue config['instance'] = instance - render(config_file_base + instance, 'bcast-relay/udp-broadcast-relay.tmpl', config) + render(config_file_base + instance, 'bcast-relay/udp-broadcast-relay.tmpl', + config, trim_blocks=True) return None diff --git a/src/conf_mode/dhcpv6_server.py b/src/conf_mode/dhcpv6_server.py index 4ce4cada1..1777d4db7 100755 --- a/src/conf_mode/dhcpv6_server.py +++ b/src/conf_mode/dhcpv6_server.py @@ -65,6 +65,7 @@ def get_config(config=None): config = { 'name': network, 'disabled': False, + 'common': {}, 'subnet': [] } @@ -72,6 +73,31 @@ def get_config(config=None): if conf.exists(['disable']): config['disabled'] = True + # Common options shared among subnets. These can be overridden if + # the same option is specified on a per-subnet or per-host + # basis. These are the only options that can be handed out to + # stateless clients via an information-request message. + if conf.exists(['common-options']): + conf.set_level(base + ['shared-network-name', network, 'common-options']) + + # How often stateless clients should refresh their information. This is + # mostly taken as a hint by clients, and only if they request it. + # (if not specified, the server does not supply this to the client) + if conf.exists(['info-refresh-time']): + config['common']['info_refresh_time'] = conf.return_value(['info-refresh-time']) + + # The domain-search option specifies a 'search list' of Domain Names to be used + # by the client to locate not-fully-qualified domain names. + if conf.exists(['domain-search']): + config['common']['domain_search'] = conf.return_values(['domain-search']) + + # Specifies a list of Domain Name System name servers available to the client. + # Servers should be listed in order of preference. + if conf.exists(['name-server']): + config['common']['dns_server'] = conf.return_values(['name-server']) + + conf.set_level(base + ['shared-network-name', network]) + # check for multiple subnet configurations in a shared network if conf.exists(['subnet']): for net in conf.list_nodes(['subnet']): diff --git a/src/conf_mode/dns_forwarding.py b/src/conf_mode/dns_forwarding.py index 5101c1e79..2187b3c73 100755 --- a/src/conf_mode/dns_forwarding.py +++ b/src/conf_mode/dns_forwarding.py @@ -26,6 +26,7 @@ from vyos.util import chown from vyos.util import vyos_dict_search from vyos.template import render from vyos.xml import defaults +from vyos.validate import is_ipv6 from vyos import ConfigError from vyos import airbag @@ -65,6 +66,21 @@ def get_config(config=None): if conf.exists(base_nameservers_dhcp): dns.update({'system_name_server_dhcp': conf.return_values(base_nameservers_dhcp)}) + # Split the source_address property into separate IPv4 and IPv6 lists + # NOTE: In future versions of pdns-recursor (> 4.4.0), this logic can be removed + # as both IPv4 and IPv6 addresses can be specified in a single setting. + source_address_v4 = [] + source_address_v6 = [] + + for source_address in dns['source_address']: + if is_ipv6(source_address): + source_address_v6.append(source_address) + else: + source_address_v4.append(source_address) + + dns.update({'source_address_v4': source_address_v4}) + dns.update({'source_address_v6': source_address_v6}) + return dns def verify(dns): diff --git a/src/conf_mode/intel_qat.py b/src/conf_mode/intel_qat.py index 86dbccaf0..ab98cbc03 100755 --- a/src/conf_mode/intel_qat.py +++ b/src/conf_mode/intel_qat.py @@ -67,7 +67,7 @@ def verify(qat): output, err = popen('lspci -nn', decode='utf-8') if not err: data = re.findall( - '(8086:19e2)|(8086:37c8)|(8086:0435)|(8086:6f54)', output) + '(8086:19e2)|(8086:37c8)|(8086:0435)|(8086:6f54)|(8086:1f18)', output) # If QAT devices found if not data: raise ConfigError('No QAT acceleration device found') diff --git a/src/conf_mode/interfaces-bonding.py b/src/conf_mode/interfaces-bonding.py index 9763620ac..ea9bd54d4 100755 --- a/src/conf_mode/interfaces-bonding.py +++ b/src/conf_mode/interfaces-bonding.py @@ -109,7 +109,7 @@ def get_config(config=None): # Check if member interface is already member of a bond tmp = is_member(conf, interface, 'bonding') - if tmp and tmp != bond['ifname']: + if tmp and bond['ifname'] not in tmp: interface_config.update({'is_bond_member' : tmp}) # Check if member interface is used as source-interface on another interface @@ -162,11 +162,11 @@ def verify(bond): raise ConfigError(error_msg + 'it does not exist!') if 'is_bridge_member' in interface_config: - tmp = interface_config['is_bridge_member'] + tmp = next(iter(interface_config['is_bridge_member'])) raise ConfigError(error_msg + f'it is already a member of bridge "{tmp}"!') if 'is_bond_member' in interface_config: - tmp = interface_config['is_bond_member'] + tmp = next(iter(interface_config['is_bond_member'])) raise ConfigError(error_msg + f'it is already a member of bond "{tmp}"!') if 'is_source_interface' in interface_config: diff --git a/src/conf_mode/interfaces-bridge.py b/src/conf_mode/interfaces-bridge.py index 485decb17..4aeb8fc67 100755 --- a/src/conf_mode/interfaces-bridge.py +++ b/src/conf_mode/interfaces-bridge.py @@ -24,6 +24,7 @@ from vyos.configdict import get_interface_dict from vyos.configdict import node_changed from vyos.configdict import is_member from vyos.configdict import is_source_interface +from vyos.configdict import dict_merge from vyos.configverify import verify_dhcpv6 from vyos.configverify import verify_vrf from vyos.ifconfig import BridgeIf @@ -69,25 +70,26 @@ def get_config(config=None): # the default dictionary is not properly paged into the dict (see T2665) # thus we will ammend it ourself default_member_values = defaults(base + ['member', 'interface']) - for interface, interface_config in bridge['member']['interface'].items(): - interface_config.update(default_member_values) + for interface in bridge['member']['interface']: + bridge['member']['interface'][interface] = dict_merge( + default_member_values, bridge['member']['interface'][interface]) # Check if member interface is already member of another bridge tmp = is_member(conf, interface, 'bridge') - if tmp and tmp != bridge['ifname']: - interface_config.update({'is_bridge_member' : tmp}) + if tmp and bridge['ifname'] not in tmp: + bridge['member']['interface'][interface].update({'is_bridge_member' : tmp}) # Check if member interface is already member of a bond tmp = is_member(conf, interface, 'bonding') - if tmp: interface_config.update({'is_bond_member' : tmp}) + if tmp: bridge['member']['interface'][interface].update({'is_bond_member' : tmp}) # Check if member interface is used as source-interface on another interface tmp = is_source_interface(conf, interface) - if tmp: interface_config.update({'is_source_interface' : tmp}) + if tmp: bridge['member']['interface'][interface].update({'is_source_interface' : tmp}) # Bridge members must not have an assigned address tmp = has_address_configured(conf, interface) - if tmp: interface_config.update({'has_address' : ''}) + if tmp: bridge['member']['interface'][interface].update({'has_address' : ''}) return bridge @@ -105,15 +107,12 @@ def verify(bridge): if interface == 'lo': raise ConfigError('Loopback interface "lo" can not be added to a bridge') - if interface not in interfaces(): - raise ConfigError(error_msg + 'it does not exist!') - if 'is_bridge_member' in interface_config: - tmp = interface_config['is_bridge_member'] + tmp = next(iter(interface_config['is_bridge_member'])) raise ConfigError(error_msg + f'it is already a member of bridge "{tmp}"!') if 'is_bond_member' in interface_config: - tmp = interface_config['is_bond_member'] + tmp = next(iter(interface_config['is_bond_member'])) raise ConfigError(error_msg + f'it is already a member of bond "{tmp}"!') if 'is_source_interface' in interface_config: diff --git a/src/conf_mode/interfaces-openvpn.py b/src/conf_mode/interfaces-openvpn.py index 518dbdc0e..f2b580c6f 100755 --- a/src/conf_mode/interfaces-openvpn.py +++ b/src/conf_mode/interfaces-openvpn.py @@ -208,7 +208,8 @@ def get_config(config=None): openvpn['auth_user_pass_file'] = f"/run/openvpn/{openvpn['intf']}.pw" # check if interface is member of a bridge - openvpn['is_bridge_member'] = is_member(conf, openvpn['intf'], 'bridge') + tmp = is_member(conf, openvpn['intf'], 'bridge') + if tmp: openvpn['is_bridge_member'] = next(iter(tmp)) # Check if interface instance has been removed if not conf.exists('interfaces openvpn ' + openvpn['intf']): diff --git a/src/conf_mode/interfaces-tunnel.py b/src/conf_mode/interfaces-tunnel.py index f1d885b15..5561514bd 100755 --- a/src/conf_mode/interfaces-tunnel.py +++ b/src/conf_mode/interfaces-tunnel.py @@ -462,7 +462,8 @@ def get_config(config=None): options['tunnel'] = {} # check for bridges - options['bridge'] = is_member(config, ifname, 'bridge') + tmp = is_member(config, ifname, 'bridge') + if tmp: options['bridge'] = next(iter(tmp)) options['interfaces'] = interfaces() for name in ct: diff --git a/src/conf_mode/interfaces-wireless.py b/src/conf_mode/interfaces-wireless.py index ad8aee168..c1770771e 100755 --- a/src/conf_mode/interfaces-wireless.py +++ b/src/conf_mode/interfaces-wireless.py @@ -76,6 +76,14 @@ def get_config(config=None): base = ['interfaces', 'wireless'] wifi = get_interface_dict(conf, base) + + # Cleanup "delete" default values when required user selectable values are + # not defined at all + tmp = conf.get_config_dict([], key_mangling=('-', '_'), get_first_key=True) + if not (vyos_dict_search('security.wpa.passphrase', tmp) or + vyos_dict_search('security.wpa.radius', tmp)): + del wifi['security']['wpa'] + # defaults include RADIUS server specifics per TAG node which need to be # added to individual RADIUS servers instead - so we can simply delete them if vyos_dict_search('security.wpa.radius.server.port', wifi): diff --git a/src/conf_mode/protocols_mpls.py b/src/conf_mode/protocols_mpls.py index e515490d0..904d219e2 100755 --- a/src/conf_mode/protocols_mpls.py +++ b/src/conf_mode/protocols_mpls.py @@ -43,7 +43,12 @@ def get_config(config=None): 'd_transp_ipv4' : None, 'd_transp_ipv6' : None, 'hello_holdtime' : None, - 'hello_interval' : None + 'hello_interval' : None, + 'ses_ipv4_hold' : None, + 'ses_ipv6_hold' : None, + 'export_ipv4_exp' : False, + 'export_ipv6_exp' : False + }, 'ldp' : { 'interfaces' : [], @@ -51,7 +56,12 @@ def get_config(config=None): 'd_transp_ipv4' : None, 'd_transp_ipv6' : None, 'hello_holdtime' : None, - 'hello_interval' : None + 'hello_interval' : None, + 'ses_ipv4_hold' : None, + 'ses_ipv6_hold' : None, + 'export_ipv4_exp' : False, + 'export_ipv6_exp' : False + } } if not (conf.exists('protocols mpls') or conf.exists_effective('protocols mpls')): @@ -82,6 +92,20 @@ def get_config(config=None): if conf.exists('discovery hello-interval'): mpls_conf['ldp']['hello_interval'] = conf.return_value('discovery hello-interval') + # Get session-ipv4-holdtime + if conf.exists_effective('discovery session-ipv4-holdtime'): + mpls_conf['old_ldp']['ses_ipv4_hold'] = conf.return_effective_value('discovery session-ipv4-holdtime') + + if conf.exists('discovery session-ipv4-holdtime'): + mpls_conf['ldp']['ses_ipv4_hold'] = conf.return_value('discovery session-ipv4-holdtime') + + # Get session-ipv6-holdtime + if conf.exists_effective('discovery session-ipv6-holdtime'): + mpls_conf['old_ldp']['ses_ipv6_hold'] = conf.return_effective_value('discovery session-ipv6-holdtime') + + if conf.exists('discovery session-ipv6-holdtime'): + mpls_conf['ldp']['ses_ipv6_hold'] = conf.return_value('discovery session-ipv6-holdtime') + # Get discovery transport-ipv4-address if conf.exists_effective('discovery transport-ipv4-address'): mpls_conf['old_ldp']['d_transp_ipv4'] = conf.return_effective_value('discovery transport-ipv4-address') @@ -96,6 +120,20 @@ def get_config(config=None): if conf.exists('discovery transport-ipv6-address'): mpls_conf['ldp']['d_transp_ipv6'] = conf.return_value('discovery transport-ipv6-address') + # Get export ipv4 explicit-null + if conf.exists_effective('export ipv4 explicit-null'): + mpls_conf['old_ldp']['export_ipv4_exp'] = True + + if conf.exists('export ipv4 explicit-null'): + mpls_conf['ldp']['export_ipv4_exp'] = True + + # Get export ipv6 explicit-null + if conf.exists_effective('export ipv6 explicit-null'): + mpls_conf['old_ldp']['export_ipv6_exp'] = True + + if conf.exists('export ipv6 explicit-null'): + mpls_conf['ldp']['export_ipv6_exp'] = True + # Get interfaces if conf.exists_effective('interface'): mpls_conf['old_ldp']['interfaces'] = conf.return_effective_values('interface') diff --git a/src/conf_mode/service_pppoe-server.py b/src/conf_mode/service_pppoe-server.py index 445311391..a520120f8 100755 --- a/src/conf_mode/service_pppoe-server.py +++ b/src/conf_mode/service_pppoe-server.py @@ -19,13 +19,11 @@ import os from sys import exit from vyos.config import Config -from vyos.configdict import dict_merge -from vyos.validate import is_ipv4 +from vyos.configdict import get_accel_dict +from vyos.configverify import verify_accel_ppp_base_service from vyos.template import render from vyos.util import call -from vyos.util import get_half_cpus from vyos.util import vyos_dict_search -from vyos.xml import defaults from vyos import ConfigError from vyos import airbag airbag.enable() @@ -42,108 +40,22 @@ def get_config(config=None): if not conf.exists(base): return None - pppoe = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True) - # We have gathered the dict representation of the CLI, but there are default - # options which we need to update into the dictionary retrived. - default_values = defaults(base) - - # defaults include RADIUS server specifics per TAG node which need to be - # added to individual RADIUS servers instead - so we can simply delete them - if vyos_dict_search('authentication.radius.server', default_values): - del default_values['authentication']['radius']['server'] - # defaults include static-ip address per TAG node which need to be added to - # individual local users instead - so we can simply delete them - if vyos_dict_search('authentication.local_users.username', default_values): - del default_values['authentication']['local_users']['username'] - - pppoe = dict_merge(default_values, pppoe) - - # set CPUs cores to process requests - pppoe.update({'thread_count' : get_half_cpus()}) - # we need to store the path to the secrets file - pppoe.update({'chap_secrets_file' : pppoe_chap_secrets}) - - # We can only have two IPv4 and three IPv6 nameservers - also they are - # configured in a different way in the configuration, this is why we split - # the configuration - if 'name_server' in pppoe: - ns_v4 = [] - ns_v6 = [] - for ns in pppoe['name_server']: - if is_ipv4(ns): ns_v4.append(ns) - else: ns_v6.append(ns) - - pppoe.update({'name_server_ipv4' : ns_v4, 'name_server_ipv6' : ns_v6}) - del pppoe['name_server'] - - # Add individual RADIUS server default values - if vyos_dict_search('authentication.radius.server', pppoe): - default_values = defaults(base + ['authentication', 'radius', 'server']) - - for server in vyos_dict_search('authentication.radius.server', pppoe): - pppoe['authentication']['radius']['server'][server] = dict_merge( - default_values, pppoe['authentication']['radius']['server'][server]) - - # Add individual local-user default values - if vyos_dict_search('authentication.local_users.username', pppoe): - default_values = defaults(base + ['authentication', 'local_users', 'username']) - - for username in vyos_dict_search('authentication.local_users.username', pppoe): - pppoe['authentication']['local_users']['username'][username] = dict_merge( - default_values, pppoe['authentication']['local_users']['username'][username]) - + # retrieve common dictionary keys + pppoe = get_accel_dict(conf, base, pppoe_chap_secrets) return pppoe - def verify(pppoe): if not pppoe: return None - # vertify auth settings - if vyos_dict_search('authentication.mode', pppoe) == 'local': - if not vyos_dict_search('authentication.local_users', pppoe): - raise ConfigError('PPPoE local auth mode requires local users to be configured!') - - for user in vyos_dict_search('authentication.local_users.username', pppoe): - user_config = pppoe['authentication']['local_users']['username'][user] - - if 'password' not in user_config: - raise ConfigError(f'Password required for local user "{user}"') - - if 'rate_limit' in user_config: - # if up/download is set, check that both have a value - if not {'upload', 'download'} <= set(user_config['rate_limit']): - raise ConfigError(f'User "{user}" has rate-limit configured for only one ' \ - 'direction but both upload and download must be given!') - - elif vyos_dict_search('authentication.mode', pppoe) == 'radius': - if not vyos_dict_search('authentication.radius.server', pppoe): - raise ConfigError('RADIUS authentication requires at least one server') - - for server in vyos_dict_search('authentication.radius.server', pppoe): - radius_config = pppoe['authentication']['radius']['server'][server] - if 'key' not in radius_config: - raise ConfigError(f'Missing RADIUS secret key for server "{server}"') + verify_accel_ppp_base_service(pppoe) if 'wins_server' in pppoe and len(pppoe['wins_server']) > 2: raise ConfigError('Not more then two IPv4 WINS name-servers can be configured') - if 'name_server_ipv4' in pppoe: - if len(pppoe['name_server_ipv4']) > 2: - raise ConfigError('Not more then two IPv4 DNS name-servers ' \ - 'can be configured') - - if 'name_server_ipv6' in pppoe: - if len(pppoe['name_server_ipv6']) > 3: - raise ConfigError('Not more then three IPv6 DNS name-servers ' \ - 'can be configured') - if 'interface' not in pppoe: raise ConfigError('At least one listen interface must be defined!') - if 'gateway_address' not in pppoe: - raise ConfigError('PPPoE server requires gateway-address to be configured!') - # local ippool and gateway settings config checks if not (vyos_dict_search('client_ip_pool.subnet', pppoe) or (vyos_dict_search('client_ip_pool.start', pppoe) and @@ -164,7 +76,8 @@ def generate(pppoe): render(pppoe_conf, 'accel-ppp/pppoe.config.tmpl', pppoe, trim_blocks=True) if vyos_dict_search('authentication.mode', pppoe) == 'local': - render(pppoe_chap_secrets, 'accel-ppp/chap-secrets.pppoe.tmpl', pppoe, trim_blocks=True, permission=0o640) + render(pppoe_chap_secrets, 'accel-ppp/chap-secrets.config_dict.tmpl', + pppoe, trim_blocks=True, permission=0o640) else: if os.path.exists(pppoe_chap_secrets): os.unlink(pppoe_chap_secrets) diff --git a/src/conf_mode/system-login.py b/src/conf_mode/system-login.py index 2aca199f9..2c0bbd4f7 100755 --- a/src/conf_mode/system-login.py +++ b/src/conf_mode/system-login.py @@ -233,8 +233,8 @@ def generate(login): env = os.environ.copy() env['vyos_libexec_dir'] = '/usr/libexec/vyos' - call("/opt/vyatta/sbin/my_set system login user '{name}' " - "authentication plaintext-password '{password_plaintext}'" + call("/opt/vyatta/sbin/my_delete system login user '{name}' " + "authentication plaintext-password" .format(**user), env=env) call("/opt/vyatta/sbin/my_set system login user '{name}' " diff --git a/src/conf_mode/system-syslog.py b/src/conf_mode/system-syslog.py index d29109c41..b1daf7a82 100755 --- a/src/conf_mode/system-syslog.py +++ b/src/conf_mode/system-syslog.py @@ -146,6 +146,12 @@ def get_config(config=None): config_data['hosts'][rhost][ 'port'] = c.return_value(['host', rhost, 'port']) + # set system syslog host x.x.x.x format octet-counted + if c.exists('host ' + rhost + ' format octet-counted'): + config_data['hosts'][rhost]['oct_count'] = True + else: + config_data['hosts'][rhost]['oct_count'] = False + # set system syslog user if c.exists('user'): usrs = c.list_nodes('user') diff --git a/src/conf_mode/system-timezone.py b/src/conf_mode/system-timezone.py index 4d9f017a6..3d98ba774 100755 --- a/src/conf_mode/system-timezone.py +++ b/src/conf_mode/system-timezone.py @@ -48,6 +48,7 @@ def generate(tz): def apply(tz): call('/usr/bin/timedatectl set-timezone {}'.format(tz['name'])) + call('systemctl restart rsyslog') if __name__ == '__main__': try: diff --git a/src/conf_mode/tftp_server.py b/src/conf_mode/tftp_server.py index ad5ee9c33..cac95afe2 100755 --- a/src/conf_mode/tftp_server.py +++ b/src/conf_mode/tftp_server.py @@ -23,64 +23,52 @@ from glob import glob from sys import exit from vyos.config import Config -from vyos.validate import is_ipv4, is_addr_assigned -from vyos import ConfigError -from vyos.util import call +from vyos.configdict import dict_merge from vyos.template import render - +from vyos.util import call +from vyos.util import chmod_755 +from vyos.validate import is_ipv4 +from vyos.validate import is_addr_assigned +from vyos.xml import defaults +from vyos import ConfigError from vyos import airbag airbag.enable() config_file = r'/etc/default/tftpd' -default_config_data = { - 'directory': '', - 'allow_upload': False, - 'port': '69', - 'listen': [] -} - def get_config(config=None): - tftpd = deepcopy(default_config_data) if config: conf = config else: conf = Config() + base = ['service', 'tftp-server'] if not conf.exists(base): return None - else: - conf.set_level(base) - - if conf.exists(['directory']): - tftpd['directory'] = conf.return_value(['directory']) - - if conf.exists(['allow-upload']): - tftpd['allow_upload'] = True - - if conf.exists(['port']): - tftpd['port'] = conf.return_value(['port']) - - if conf.exists(['listen-address']): - tftpd['listen'] = conf.return_values(['listen-address']) + tftpd = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True) + # We have gathered the dict representation of the CLI, but there are default + # options which we need to update into the dictionary retrived. + default_values = defaults(base) + tftpd = dict_merge(default_values, tftpd) return tftpd def verify(tftpd): # bail out early - looks like removal from running config - if tftpd is None: + if not tftpd: return None # Configuring allowed clients without a server makes no sense - if not tftpd['directory']: + if 'directory' not in tftpd: raise ConfigError('TFTP root directory must be configured!') - if not tftpd['listen']: + if 'listen_address' not in tftpd: raise ConfigError('TFTP server listen address must be configured!') - for addr in tftpd['listen']: - if not is_addr_assigned(addr): - print('WARNING: TFTP server listen address {0} not assigned to any interface!'.format(addr)) + for address in tftpd['listen_address']: + if not is_addr_assigned(address): + print(f'WARNING: TFTP server listen address "{address}" not ' \ + 'assigned to any interface!') return None @@ -95,23 +83,23 @@ def generate(tftpd): return None idx = 0 - for listen in tftpd['listen']: + for address in tftpd['listen_address']: config = deepcopy(tftpd) - if is_ipv4(listen): - config['listen'] = [listen + ":" + tftpd['port'] + " -4"] + port = tftpd['port'] + if is_ipv4(address): + config['listen_address'] = f'{address}:{port} -4' else: - config['listen'] = ["[" + listen + "]" + tftpd['port'] + " -6"] + config['listen_address'] = f'[{address}]:{port} -6' file = config_file + str(idx) - render(file, 'tftp-server/default.tmpl', config) - + render(file, 'tftp-server/default.tmpl', config, trim_blocks=True) idx = idx + 1 return None def apply(tftpd): # stop all services first - then we will decide - call('systemctl stop tftpd@{0..20}.service') + call('systemctl stop tftpd@*.service') # bail out early - e.g. service deletion if tftpd is None: @@ -120,7 +108,7 @@ def apply(tftpd): tftp_root = tftpd['directory'] if not os.path.exists(tftp_root): os.makedirs(tftp_root) - os.chmod(tftp_root, stat.S_IRUSR|stat.S_IWUSR|stat.S_IXUSR|stat.S_IRGRP|stat.S_IXGRP|stat.S_IROTH|stat.S_IXOTH) + chmod_755(tftp_root) # get UNIX uid for user 'tftp' tftp_uid = pwd.getpwnam('tftp').pw_uid @@ -135,8 +123,8 @@ def apply(tftpd): os.chown(tftp_root, tftp_uid, tftp_gid) idx = 0 - for listen in tftpd['listen']: - call('systemctl restart tftpd@{0}.service'.format(idx)) + for address in tftpd['listen_address']: + call(f'systemctl restart tftpd@{idx}.service') idx = idx + 1 return None diff --git a/src/conf_mode/vpn_sstp.py b/src/conf_mode/vpn_sstp.py index 3eece1922..2597ba42f 100755 --- a/src/conf_mode/vpn_sstp.py +++ b/src/conf_mode/vpn_sstp.py @@ -16,340 +16,66 @@ import os -from time import sleep from sys import exit -from copy import deepcopy -from stat import S_IRUSR, S_IWUSR, S_IRGRP from vyos.config import Config +from vyos.configdict import get_accel_dict +from vyos.configverify import verify_accel_ppp_base_service from vyos.template import render -from vyos.util import call, run, get_half_cpus -from vyos.validate import is_ipv4 +from vyos.util import call +from vyos.util import vyos_dict_search from vyos import ConfigError - from vyos import airbag airbag.enable() sstp_conf = '/run/accel-pppd/sstp.conf' sstp_chap_secrets = '/run/accel-pppd/sstp.chap-secrets' -default_config_data = { - 'local_users' : [], - 'auth_mode' : 'local', - 'auth_proto' : ['auth_mschap_v2'], - 'chap_secrets_file': sstp_chap_secrets, # used in Jinja2 template - 'client_ip_pool' : [], - 'client_ipv6_pool': [], - 'client_ipv6_delegate_prefix': [], - 'client_gateway': '', - 'dnsv4' : [], - 'dnsv6' : [], - 'radius_server' : [], - 'radius_acct_tmo' : '3', - 'radius_max_try' : '3', - 'radius_timeout' : '3', - 'radius_nas_id' : '', - 'radius_nas_ip' : '', - 'radius_source_address' : '', - 'radius_shaper_attr' : '', - 'radius_shaper_vendor': '', - 'radius_dynamic_author' : '', - 'ssl_ca' : '', - 'ssl_cert' : '', - 'ssl_key' : '', - 'mtu' : '', - 'ppp_mppe' : 'prefer', - 'ppp_echo_failure' : '', - 'ppp_echo_interval' : '', - 'ppp_echo_timeout' : '', - 'thread_cnt' : get_half_cpus() -} - def get_config(config=None): - sstp = deepcopy(default_config_data) - base_path = ['vpn', 'sstp'] if config: conf = config else: conf = Config() - if not conf.exists(base_path): + base = ['vpn', 'sstp'] + if not conf.exists(base): return None - conf.set_level(base_path) - - if conf.exists(['authentication', 'mode']): - sstp['auth_mode'] = conf.return_value(['authentication', 'mode']) - - # - # local auth - if conf.exists(['authentication', 'local-users']): - for username in conf.list_nodes(['authentication', 'local-users', 'username']): - user = { - 'name' : username, - 'password' : '', - 'state' : 'enabled', - 'ip' : '*', - 'upload' : None, - 'download' : None - } - - conf.set_level(base_path + ['authentication', 'local-users', 'username', username]) - - if conf.exists(['password']): - user['password'] = conf.return_value(['password']) - - if conf.exists(['disable']): - user['state'] = 'disable' - - if conf.exists(['static-ip']): - user['ip'] = conf.return_value(['static-ip']) - - if conf.exists(['rate-limit', 'download']): - user['download'] = conf.return_value(['rate-limit', 'download']) - - if conf.exists(['rate-limit', 'upload']): - user['upload'] = conf.return_value(['rate-limit', 'upload']) - - sstp['local_users'].append(user) - - # - # RADIUS auth and settings - conf.set_level(base_path + ['authentication', 'radius']) - if conf.exists(['server']): - for server in conf.list_nodes(['server']): - radius = { - 'server' : server, - 'key' : '', - 'fail_time' : 0, - 'port' : '1812', - 'acct_port' : '1813' - } - - conf.set_level(base_path + ['authentication', 'radius', 'server', server]) - - if conf.exists(['fail-time']): - radius['fail_time'] = conf.return_value(['fail-time']) - - if conf.exists(['port']): - radius['port'] = conf.return_value(['port']) - - if conf.exists(['acct-port']): - radius['acct_port'] = conf.return_value(['acct-port']) - - if conf.exists(['key']): - radius['key'] = conf.return_value(['key']) - - if not conf.exists(['disable']): - sstp['radius_server'].append(radius) - - # - # advanced radius-setting - conf.set_level(base_path + ['authentication', 'radius']) - - if conf.exists(['acct-timeout']): - sstp['radius_acct_tmo'] = conf.return_value(['acct-timeout']) - - if conf.exists(['max-try']): - sstp['radius_max_try'] = conf.return_value(['max-try']) - - if conf.exists(['timeout']): - sstp['radius_timeout'] = conf.return_value(['timeout']) - - if conf.exists(['nas-identifier']): - sstp['radius_nas_id'] = conf.return_value(['nas-identifier']) - - if conf.exists(['nas-ip-address']): - sstp['radius_nas_ip'] = conf.return_value(['nas-ip-address']) - - if conf.exists(['source-address']): - sstp['radius_source_address'] = conf.return_value(['source-address']) - - # Dynamic Authorization Extensions (DOA)/Change Of Authentication (COA) - if conf.exists(['dynamic-author']): - dae = { - 'port' : '1700', - 'server' : '', - 'key' : '' - } - - if conf.exists(['dynamic-author', 'server']): - dae['server'] = conf.return_value(['dynamic-author', 'server']) - - if conf.exists(['dynamic-author', 'port']): - dae['port'] = conf.return_value(['dynamic-author', 'port']) - - if conf.exists(['dynamic-author', 'key']): - dae['key'] = conf.return_value(['dynamic-author', 'key']) - - sstp['radius_dynamic_author'] = dae - - if conf.exists(['rate-limit', 'enable']): - sstp['radius_shaper_attr'] = 'Filter-Id' - c_attr = ['rate-limit', 'enable', 'attribute'] - if conf.exists(c_attr): - sstp['radius_shaper_attr'] = conf.return_value(c_attr) - - c_vendor = ['rate-limit', 'enable', 'vendor'] - if conf.exists(c_vendor): - sstp['radius_shaper_vendor'] = conf.return_value(c_vendor) - - # - # authentication protocols - conf.set_level(base_path + ['authentication']) - if conf.exists(['protocols']): - # clear default list content, now populate with actual CLI values - sstp['auth_proto'] = [] - auth_mods = { - 'pap': 'auth_pap', - 'chap': 'auth_chap_md5', - 'mschap': 'auth_mschap_v1', - 'mschap-v2': 'auth_mschap_v2' - } - - for proto in conf.return_values(['protocols']): - sstp['auth_proto'].append(auth_mods[proto]) - - # - # read in SSL certs - conf.set_level(base_path + ['ssl']) - if conf.exists(['ca-cert-file']): - sstp['ssl_ca'] = conf.return_value(['ca-cert-file']) - - if conf.exists(['cert-file']): - sstp['ssl_cert'] = conf.return_value(['cert-file']) - - if conf.exists(['key-file']): - sstp['ssl_key'] = conf.return_value(['key-file']) - - - # - # read in client IPv4 pool - conf.set_level(base_path + ['client-ip-pool']) - if conf.exists(['subnet']): - sstp['client_ip_pool'] = conf.return_values(['subnet']) - - # - # read in client IPv6 pool - conf.set_level(base_path + ['client-ipv6-pool']) - if conf.exists(['prefix']): - for prefix in conf.list_nodes(['prefix']): - tmp = { - 'prefix': prefix, - 'mask': '64' - } - - if conf.exists(['prefix', prefix, 'mask']): - tmp['mask'] = conf.return_value(['prefix', prefix, 'mask']) - - sstp['client_ipv6_pool'].append(tmp) - - if conf.exists(['delegate']): - for prefix in conf.list_nodes(['delegate']): - tmp = { - 'prefix': prefix, - 'mask': '' - } - - if conf.exists(['delegate', prefix, 'delegation-prefix']): - tmp['mask'] = conf.return_value(['delegate', prefix, 'delegation-prefix']) - - sstp['client_ipv6_delegate_prefix'].append(tmp) - - # - # read in network settings - conf.set_level(base_path) - if conf.exists(['gateway-address']): - sstp['client_gateway'] = conf.return_value(['gateway-address']) - - if conf.exists(['name-server']): - for name_server in conf.return_values(['name-server']): - if is_ipv4(name_server): - sstp['dnsv4'].append(name_server) - else: - sstp['dnsv6'].append(name_server) - - if conf.exists(['mtu']): - sstp['mtu'] = conf.return_value(['mtu']) - - # - # read in PPP stuff - conf.set_level(base_path + ['ppp-options']) - if conf.exists('mppe'): - sstp['ppp_mppe'] = conf.return_value(['mppe']) - - if conf.exists(['lcp-echo-failure']): - sstp['ppp_echo_failure'] = conf.return_value(['lcp-echo-failure']) - - if conf.exists(['lcp-echo-interval']): - sstp['ppp_echo_interval'] = conf.return_value(['lcp-echo-interval']) - - if conf.exists(['lcp-echo-timeout']): - sstp['ppp_echo_timeout'] = conf.return_value(['lcp-echo-timeout']) - + # retrieve common dictionary keys + sstp = get_accel_dict(conf, base, sstp_chap_secrets) return sstp - def verify(sstp): - if sstp is None: + if not sstp: return None - # vertify auth settings - if sstp['auth_mode'] == 'local': - if not sstp['local_users']: - raise ConfigError('SSTP local auth mode requires local users to be configured!') - - for user in sstp['local_users']: - username = user['name'] - if not user['password']: - raise ConfigError(f'Password required for local user "{username}"') - - # if up/download is set, check that both have a value - if user['upload'] and not user['download']: - raise ConfigError(f'Download speed value required for local user "{username}"') - - if user['download'] and not user['upload']: - raise ConfigError(f'Upload speed value required for local user "{username}"') - - if not sstp['client_ip_pool']: - raise ConfigError('Client IP subnet required') - - if not sstp['client_gateway']: - raise ConfigError('Client gateway IP address required') - - if len(sstp['dnsv4']) > 2: - raise ConfigError('Not more then two IPv4 DNS name-servers can be configured') + verify_accel_ppp_base_service(sstp) - # check ipv6 - if sstp['client_ipv6_delegate_prefix'] and not sstp['client_ipv6_pool']: - raise ConfigError('IPv6 prefix delegation requires client-ipv6-pool prefix') + if not sstp['client_ip_pool']: + raise ConfigError('Client IP subnet required') - for prefix in sstp['client_ipv6_delegate_prefix']: - if not prefix['mask']: - raise ConfigError('Delegation-prefix required for individual delegated networks') - - if not sstp['ssl_ca'] or not sstp['ssl_cert'] or not sstp['ssl_key']: - raise ConfigError('One or more SSL certificates missing') - - if not os.path.exists(sstp['ssl_ca']): - file = sstp['ssl_ca'] - raise ConfigError(f'SSL CA certificate file "{file}" does not exist') - - if not os.path.exists(sstp['ssl_cert']): - file = sstp['ssl_cert'] - raise ConfigError(f'SSL public key file "{file}" does not exist') - - if not os.path.exists(sstp['ssl_key']): - file = sstp['ssl_key'] - raise ConfigError(f'SSL private key file "{file}" does not exist') + # + # SSL certificate checks + # + tmp = vyos_dict_search('ssl.ca_cert_file', sstp) + if not tmp: + raise ConfigError(f'SSL CA certificate file required!') + else: + if not os.path.isfile(tmp): + raise ConfigError(f'SSL CA certificate "{tmp}" does not exist!') - if sstp['auth_mode'] == 'radius': - if len(sstp['radius_server']) == 0: - raise ConfigError('RADIUS authentication requires at least one server') + tmp = vyos_dict_search('ssl.cert_file', sstp) + if not tmp: + raise ConfigError(f'SSL public key file required!') + else: + if not os.path.isfile(tmp): + raise ConfigError(f'SSL public key "{tmp}" does not exist!') - for radius in sstp['radius_server']: - if not radius['key']: - server = radius['server'] - raise ConfigError(f'Missing RADIUS secret key for server "{ server }"') + tmp = vyos_dict_search('ssl.key_file', sstp) + if not tmp: + raise ConfigError(f'SSL private key file required!') + else: + if not os.path.isfile(tmp): + raise ConfigError(f'SSL private key "{tmp}" does not exist!') def generate(sstp): if not sstp: @@ -358,9 +84,9 @@ def generate(sstp): # accel-cmd reload doesn't work so any change results in a restart of the daemon render(sstp_conf, 'accel-ppp/sstp.config.tmpl', sstp, trim_blocks=True) - if sstp['local_users']: - render(sstp_chap_secrets, 'accel-ppp/chap-secrets.tmpl', sstp, trim_blocks=True) - os.chmod(sstp_chap_secrets, S_IRUSR | S_IWUSR | S_IRGRP) + if vyos_dict_search('authentication.mode', sstp) == 'local': + render(sstp_chap_secrets, 'accel-ppp/chap-secrets.config_dict.tmpl', + sstp, trim_blocks=True, permission=0o640) else: if os.path.exists(sstp_chap_secrets): os.unlink(sstp_chap_secrets) diff --git a/src/migration-scripts/pppoe-server/1-to-2 b/src/migration-scripts/pppoe-server/1-to-2 index 7cae3b5bc..902efb86b 100755 --- a/src/migration-scripts/pppoe-server/1-to-2 +++ b/src/migration-scripts/pppoe-server/1-to-2 @@ -14,7 +14,9 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -# Convert "service pppoe-server interface ethX" to: "service pppoe-server interface ethX {}" +# change mppe node to a leaf node with value prefer + +import os from sys import argv, exit from vyos.configtree import ConfigTree @@ -28,21 +30,32 @@ file_name = argv[1] with open(file_name, 'r') as f: config_file = f.read() -ctree = ConfigTree(config_file) -cbase = ['service', 'pppoe-server','interface'] - -if not ctree.exists(cbase): +config = ConfigTree(config_file) +base = ['service', 'pppoe-server'] +if not config.exists(base): + # Nothing to do exit(0) else: - nics = ctree.return_values(cbase) - # convert leafNode to a tagNode - ctree.set(cbase) - ctree.set_tag(cbase) - for nic in nics: - ctree.set(cbase + [nic]) + mppe_base = base + ['ppp-options', 'mppe'] + if config.exists(mppe_base): + # get current values + tmp = config.list_nodes(mppe_base) + # drop node(s) first ... + config.delete(mppe_base) + + print(tmp) + # set new value based on preference + if 'require' in tmp: + config.set(mppe_base, value='require') + elif 'prefer' in tmp: + config.set(mppe_base, value='prefer') + elif 'deny' in tmp: + config.set(mppe_base, value='deny') try: - open(file_name,'w').write(ctree.to_string()) + with open(file_name, 'w') as f: + f.write(config.to_string()) except OSError as e: print("Failed to save the modified config: {}".format(e)) exit(1) + diff --git a/src/migration-scripts/pppoe-server/2-to-3 b/src/migration-scripts/pppoe-server/2-to-3 index 5f9730a41..7cae3b5bc 100755 --- a/src/migration-scripts/pppoe-server/2-to-3 +++ b/src/migration-scripts/pppoe-server/2-to-3 @@ -14,9 +14,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -# - remove primary/secondary identifier from nameserver - -import os +# Convert "service pppoe-server interface ethX" to: "service pppoe-server interface ethX {}" from sys import argv, exit from vyos.configtree import ConfigTree @@ -30,112 +28,21 @@ file_name = argv[1] with open(file_name, 'r') as f: config_file = f.read() -config = ConfigTree(config_file) -base = ['service', 'pppoe-server'] -if not config.exists(base): - # Nothing to do +ctree = ConfigTree(config_file) +cbase = ['service', 'pppoe-server','interface'] + +if not ctree.exists(cbase): exit(0) else: - - # Migrate IPv4 DNS servers - dns_base = base + ['dns-servers'] - if config.exists(dns_base): - for server in ['server-1', 'server-2']: - if config.exists(dns_base + [server]): - dns = config.return_value(dns_base + [server]) - config.set(base + ['name-server'], value=dns, replace=False) - - config.delete(dns_base) - - # Migrate IPv6 DNS servers - dns_base = base + ['dnsv6-servers'] - if config.exists(dns_base): - for server in ['server-1', 'server-2', 'server-3']: - if config.exists(dns_base + [server]): - dns = config.return_value(dns_base + [server]) - config.set(base + ['name-server'], value=dns, replace=False) - - config.delete(dns_base) - - # Migrate IPv4 WINS servers - wins_base = base + ['wins-servers'] - if config.exists(wins_base): - for server in ['server-1', 'server-2']: - if config.exists(wins_base + [server]): - wins = config.return_value(wins_base + [server]) - config.set(base + ['wins-server'], value=wins, replace=False) - - config.delete(wins_base) - - # Migrate radius-settings node to RADIUS and use this as base for the - # later migration of the RADIUS servers - this will save a lot of code - radius_settings = base + ['authentication', 'radius-settings'] - if config.exists(radius_settings): - config.rename(radius_settings, 'radius') - - # Migrate RADIUS dynamic author / change of authorisation server - dae_old = base + ['authentication', 'radius', 'dae-server'] - if config.exists(dae_old): - config.rename(dae_old, 'dynamic-author') - dae_new = base + ['authentication', 'radius', 'dynamic-author'] - - if config.exists(dae_new + ['ip-address']): - config.rename(dae_new + ['ip-address'], 'server') - - if config.exists(dae_new + ['secret']): - config.rename(dae_new + ['secret'], 'key') - - # Migrate RADIUS server - radius_server = base + ['authentication', 'radius-server'] - if config.exists(radius_server): - new_base = base + ['authentication', 'radius', 'server'] - config.set(new_base) - config.set_tag(new_base) - for server in config.list_nodes(radius_server): - old_base = radius_server + [server] - config.copy(old_base, new_base + [server]) - - # migrate key - if config.exists(new_base + [server, 'secret']): - config.rename(new_base + [server, 'secret'], 'key') - - # remove old req-limit node - if config.exists(new_base + [server, 'req-limit']): - config.delete(new_base + [server, 'req-limit']) - - config.delete(radius_server) - - # Migrate IPv6 prefixes - ipv6_base = base + ['client-ipv6-pool'] - if config.exists(ipv6_base + ['prefix']): - prefix_old = config.return_values(ipv6_base + ['prefix']) - # delete old prefix CLI nodes - config.delete(ipv6_base + ['prefix']) - # create ned prefix tag node - config.set(ipv6_base + ['prefix']) - config.set_tag(ipv6_base + ['prefix']) - - for p in prefix_old: - prefix = p.split(',')[0] - mask = p.split(',')[1] - config.set(ipv6_base + ['prefix', prefix, 'mask'], value=mask) - - if config.exists(ipv6_base + ['delegate-prefix']): - prefix_old = config.return_values(ipv6_base + ['delegate-prefix']) - # delete old delegate prefix CLI nodes - config.delete(ipv6_base + ['delegate-prefix']) - # create ned delegation tag node - config.set(ipv6_base + ['delegate']) - config.set_tag(ipv6_base + ['delegate']) - - for p in prefix_old: - prefix = p.split(',')[0] - mask = p.split(',')[1] - config.set(ipv6_base + ['delegate', prefix, 'delegation-prefix'], value=mask) + nics = ctree.return_values(cbase) + # convert leafNode to a tagNode + ctree.set(cbase) + ctree.set_tag(cbase) + for nic in nics: + ctree.set(cbase + [nic]) try: - with open(file_name, 'w') as f: - f.write(config.to_string()) + open(file_name,'w').write(ctree.to_string()) except OSError as e: print("Failed to save the modified config: {}".format(e)) exit(1) diff --git a/src/migration-scripts/pppoe-server/3-to-4 b/src/migration-scripts/pppoe-server/3-to-4 index 6709d5f86..5f9730a41 100755 --- a/src/migration-scripts/pppoe-server/3-to-4 +++ b/src/migration-scripts/pppoe-server/3-to-4 @@ -14,7 +14,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -# change mppe node to a leaf node with value prefer +# - remove primary/secondary identifier from nameserver import os @@ -36,12 +36,102 @@ if not config.exists(base): # Nothing to do exit(0) else: - mppe_base = base + ['ppp-options', 'mppe'] - if config.exists(mppe_base): - # drop node first ... - config.delete(mppe_base) - # ... and set new default - config.set(mppe_base, value='prefer') + + # Migrate IPv4 DNS servers + dns_base = base + ['dns-servers'] + if config.exists(dns_base): + for server in ['server-1', 'server-2']: + if config.exists(dns_base + [server]): + dns = config.return_value(dns_base + [server]) + config.set(base + ['name-server'], value=dns, replace=False) + + config.delete(dns_base) + + # Migrate IPv6 DNS servers + dns_base = base + ['dnsv6-servers'] + if config.exists(dns_base): + for server in ['server-1', 'server-2', 'server-3']: + if config.exists(dns_base + [server]): + dns = config.return_value(dns_base + [server]) + config.set(base + ['name-server'], value=dns, replace=False) + + config.delete(dns_base) + + # Migrate IPv4 WINS servers + wins_base = base + ['wins-servers'] + if config.exists(wins_base): + for server in ['server-1', 'server-2']: + if config.exists(wins_base + [server]): + wins = config.return_value(wins_base + [server]) + config.set(base + ['wins-server'], value=wins, replace=False) + + config.delete(wins_base) + + # Migrate radius-settings node to RADIUS and use this as base for the + # later migration of the RADIUS servers - this will save a lot of code + radius_settings = base + ['authentication', 'radius-settings'] + if config.exists(radius_settings): + config.rename(radius_settings, 'radius') + + # Migrate RADIUS dynamic author / change of authorisation server + dae_old = base + ['authentication', 'radius', 'dae-server'] + if config.exists(dae_old): + config.rename(dae_old, 'dynamic-author') + dae_new = base + ['authentication', 'radius', 'dynamic-author'] + + if config.exists(dae_new + ['ip-address']): + config.rename(dae_new + ['ip-address'], 'server') + + if config.exists(dae_new + ['secret']): + config.rename(dae_new + ['secret'], 'key') + + # Migrate RADIUS server + radius_server = base + ['authentication', 'radius-server'] + if config.exists(radius_server): + new_base = base + ['authentication', 'radius', 'server'] + config.set(new_base) + config.set_tag(new_base) + for server in config.list_nodes(radius_server): + old_base = radius_server + [server] + config.copy(old_base, new_base + [server]) + + # migrate key + if config.exists(new_base + [server, 'secret']): + config.rename(new_base + [server, 'secret'], 'key') + + # remove old req-limit node + if config.exists(new_base + [server, 'req-limit']): + config.delete(new_base + [server, 'req-limit']) + + config.delete(radius_server) + + # Migrate IPv6 prefixes + ipv6_base = base + ['client-ipv6-pool'] + if config.exists(ipv6_base + ['prefix']): + prefix_old = config.return_values(ipv6_base + ['prefix']) + # delete old prefix CLI nodes + config.delete(ipv6_base + ['prefix']) + # create ned prefix tag node + config.set(ipv6_base + ['prefix']) + config.set_tag(ipv6_base + ['prefix']) + + for p in prefix_old: + prefix = p.split(',')[0] + mask = p.split(',')[1] + config.set(ipv6_base + ['prefix', prefix, 'mask'], value=mask) + + if config.exists(ipv6_base + ['delegate-prefix']): + prefix_old = config.return_values(ipv6_base + ['delegate-prefix']) + # delete old delegate prefix CLI nodes + config.delete(ipv6_base + ['delegate-prefix']) + # create ned delegation tag node + config.set(ipv6_base + ['delegate']) + config.set_tag(ipv6_base + ['delegate']) + + for p in prefix_old: + prefix = p.split(',')[0] + mask = p.split(',')[1] + config.set(ipv6_base + ['delegate', prefix, 'delegation-prefix'], value=mask) try: with open(file_name, 'w') as f: diff --git a/src/services/vyos-configd b/src/services/vyos-configd index 671a89036..5b1ab1f1f 100755 --- a/src/services/vyos-configd +++ b/src/services/vyos-configd @@ -136,7 +136,7 @@ def initialization(socket): session_string = '' # check first for resent init msg, in case of client timeout while True: - msg = socket.recv().decode() + msg = socket.recv().decode("utf-8", "ignore") try: message = json.loads(msg) if message["type"] == "init": @@ -149,10 +149,10 @@ def initialization(socket): active_string = msg resp = "active" socket.send(resp.encode()) - session_string = socket.recv().decode() + session_string = socket.recv().decode("utf-8", "ignore") resp = "session" socket.send(resp.encode()) - pid_string = socket.recv().decode() + pid_string = socket.recv().decode("utf-8", "ignore") resp = "pid" socket.send(resp.encode()) |