summaryrefslogtreecommitdiff
path: root/src/conf_mode
diff options
context:
space:
mode:
Diffstat (limited to 'src/conf_mode')
-rwxr-xr-xsrc/conf_mode/interfaces-pseudo-ethernet.py9
-rwxr-xr-xsrc/conf_mode/ntp.py58
-rwxr-xr-xsrc/conf_mode/service_console-server.py109
-rwxr-xr-xsrc/conf_mode/service_router-advert.py19
-rwxr-xr-xsrc/conf_mode/snmp.py31
-rwxr-xr-xsrc/conf_mode/ssh.py10
-rwxr-xr-xsrc/conf_mode/system-login.py7
-rwxr-xr-xsrc/conf_mode/system-syslog.py51
-rwxr-xr-xsrc/conf_mode/system_console.py13
-rwxr-xr-xsrc/conf_mode/vpn_l2tp.py2
10 files changed, 233 insertions, 76 deletions
diff --git a/src/conf_mode/interfaces-pseudo-ethernet.py b/src/conf_mode/interfaces-pseudo-ethernet.py
index b142688f6..70710e97c 100755
--- a/src/conf_mode/interfaces-pseudo-ethernet.py
+++ b/src/conf_mode/interfaces-pseudo-ethernet.py
@@ -46,17 +46,18 @@ default_config_data = {
}
def get_config():
+ peth = deepcopy(default_config_data)
+ conf = Config()
+
# determine tagNode instance
if 'VYOS_TAGNODE_VALUE' not in os.environ:
raise ConfigError('Interface (VYOS_TAGNODE_VALUE) not specified')
- ifname = os.environ['VYOS_TAGNODE_VALUE']
- conf = Config()
+ peth['intf'] = os.environ['VYOS_TAGNODE_VALUE']
# Check if interface has been removed
- cfg_base = ['interfaces', 'pseudo-ethernet', ifname]
+ cfg_base = ['interfaces', 'pseudo-ethernet', peth['intf']]
if not conf.exists(cfg_base):
- peth = deepcopy(default_config_data)
peth['deleted'] = True
return peth
diff --git a/src/conf_mode/ntp.py b/src/conf_mode/ntp.py
index a66fddc61..9180998aa 100755
--- a/src/conf_mode/ntp.py
+++ b/src/conf_mode/ntp.py
@@ -18,6 +18,7 @@ import os
from copy import deepcopy
from ipaddress import ip_network
+from netifaces import interfaces
from sys import exit
from vyos.config import Config
@@ -29,23 +30,27 @@ from vyos import airbag
airbag.enable()
config_file = r'/etc/ntp.conf'
+systemd_override = r'/etc/systemd/system/ntp.service.d/override.conf'
default_config_data = {
'servers': [],
'allowed_networks': [],
- 'listen_address': []
+ 'listen_address': [],
+ 'vrf': ''
}
def get_config():
ntp = deepcopy(default_config_data)
conf = Config()
- if not conf.exists('system ntp'):
+ base = ['system', 'ntp']
+ if not conf.exists(base):
return None
else:
- conf.set_level('system ntp')
+ conf.set_level(base)
- if conf.exists('allow-clients address'):
- networks = conf.return_values('allow-clients address')
+ node = ['allow-clients', 'address']
+ if conf.exists(node):
+ networks = conf.return_values(node)
for n in networks:
addr = ip_network(n)
net = {
@@ -56,11 +61,13 @@ def get_config():
ntp['allowed_networks'].append(net)
- if conf.exists('listen-address'):
- ntp['listen_address'] = conf.return_values('listen-address')
+ node = ['listen-address']
+ if conf.exists(node):
+ ntp['listen_address'] = conf.return_values(node)
- if conf.exists('server'):
- for node in conf.list_nodes('server'):
+ node = ['server']
+ if conf.exists(node):
+ for node in conf.list_nodes(node):
options = []
server = {
"name": node,
@@ -76,41 +83,50 @@ def get_config():
server['options'] = options
ntp['servers'].append(server)
+ node = ['vrf']
+ if conf.exists(node):
+ ntp['vrf'] = conf.return_value(node)
+
return ntp
def verify(ntp):
# bail out early - looks like removal from running config
- if ntp is None:
+ if not ntp:
return None
# Configuring allowed clients without a server makes no sense
if len(ntp['allowed_networks']) and not len(ntp['servers']):
raise ConfigError('NTP server not configured')
- for n in ntp['allowed_networks']:
- try:
- addr = ip_network( n['network'] )
- break
- except ValueError:
- raise ConfigError("{0} does not appear to be a valid IPv4 or IPv6 network, check host bits!".format(n['network']))
+ if ntp['vrf'] and ntp['vrf'] not in interfaces():
+ raise ConfigError('VRF "{vrf}" does not exist'.format(**ntp))
return None
def generate(ntp):
# bail out early - looks like removal from running config
- if ntp is None:
+ if not ntp:
return None
render(config_file, 'ntp/ntp.conf.tmpl', ntp)
+ render(systemd_override, 'ntp/override.conf.tmpl', ntp, trim_blocks=True)
+
return None
def apply(ntp):
- if ntp is not None:
- call('systemctl restart ntp.service')
- else:
+ if not ntp:
# NTP support is removed in the commit
call('systemctl stop ntp.service')
- os.unlink(config_file)
+ if os.path.exists(config_file):
+ os.unlink(config_file)
+ if os.path.isfile(systemd_override):
+ os.unlink(systemd_override)
+
+ # Reload systemd manager configuration
+ call('systemctl daemon-reload')
+
+ if ntp:
+ call('systemctl restart ntp.service')
return None
diff --git a/src/conf_mode/service_console-server.py b/src/conf_mode/service_console-server.py
new file mode 100755
index 000000000..7f6967983
--- /dev/null
+++ b/src/conf_mode/service_console-server.py
@@ -0,0 +1,109 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2018-2020 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 <http://www.gnu.org/licenses/>.
+
+import os
+
+from sys import exit
+
+from vyos.config import Config
+from vyos.configdict import dict_merge
+from vyos.template import render
+from vyos.util import call
+from vyos import ConfigError
+
+config_file = r'/run/conserver/conserver.cf'
+
+# Default values are necessary until the implementation of T2588 is completed
+default_values = {
+ 'data_bits': '8',
+ 'parity': 'none',
+ 'stop_bits': '1'
+}
+
+def get_config():
+ conf = Config()
+ base = ['service', 'console-server']
+
+ if not conf.exists(base):
+ return None
+
+ # Retrieve CLI representation as dictionary
+ proxy = conf.get_config_dict(base, key_mangling=('-', '_'))
+ # The retrieved dictionary will look something like this:
+ #
+ # {'device': {'usb0b2.4p1.0': {'speed': '9600'},
+ # 'usb0b2.4p1.1': {'data_bits': '8',
+ # 'parity': 'none',
+ # 'speed': '115200',
+ # 'stop_bits': '2'}}}
+
+ # We have gathered the dict representation of the CLI, but there are default
+ # options which we need to update into the dictionary retrived.
+ for device in proxy['device'].keys():
+ tmp = dict_merge(default_values, proxy['device'][device])
+ proxy['device'][device] = tmp
+
+ return proxy
+
+def verify(proxy):
+ if not proxy:
+ return None
+
+ for device in proxy['device']:
+ keys = proxy['device'][device].keys()
+ if 'speed' not in keys:
+ raise ConfigError(f'Serial port speed must be defined for "{tmp}"!')
+
+ if 'ssh' in keys:
+ ssh_keys = proxy['device'][device]['ssh'].keys()
+ if 'port' not in ssh_keys:
+ raise ConfigError(f'SSH port must be defined for "{tmp}"!')
+
+ return None
+
+def generate(proxy):
+ if not proxy:
+ return None
+
+ render(config_file, 'conserver/conserver.conf.tmpl', proxy)
+ return None
+
+def apply(proxy):
+ call('systemctl stop dropbear@*.service conserver-server.service')
+
+ if not proxy:
+ if os.path.isfile(config_file):
+ os.unlink(config_file)
+ return None
+
+ call('systemctl restart conserver-server.service')
+
+ for device in proxy['device']:
+ if 'ssh' in proxy['device'][device].keys():
+ port = proxy['device'][device]['ssh']['port']
+ call(f'systemctl restart dropbear@{device}.service')
+
+ return None
+
+if __name__ == '__main__':
+ try:
+ c = get_config()
+ verify(c)
+ generate(c)
+ apply(c)
+ except ConfigError as e:
+ print(e)
+ exit(1)
diff --git a/src/conf_mode/service_router-advert.py b/src/conf_mode/service_router-advert.py
index da7019e2c..ef6148ebd 100755
--- a/src/conf_mode/service_router-advert.py
+++ b/src/conf_mode/service_router-advert.py
@@ -27,7 +27,7 @@ from vyos.template import render
from vyos import airbag
airbag.enable()
-config_file = r'/etc/radvd.conf'
+config_file = r'/run/radvd/radvd.conf'
default_config_data = {
'interfaces': []
@@ -66,8 +66,8 @@ def get_config():
if conf.exists(['hop-limit']):
intf['hop_limit'] = conf.return_value(['hop-limit'])
- if conf.exists(['default-lifetim']):
- intf['default_lifetime'] = conf.return_value(['default-lifetim'])
+ if conf.exists(['default-lifetime']):
+ intf['default_lifetime'] = conf.return_value(['default-lifetime'])
if conf.exists(['default-preference']):
intf['default_preference'] = conf.return_value(['default-preference'])
@@ -107,8 +107,8 @@ def get_config():
'prefix' : prefix,
'autonomous_flag' : 'on',
'on_link' : 'on',
- 'preferred_lifetime': '14400',
- 'valid_lifetime' : '2592000'
+ 'preferred_lifetime': 14400,
+ 'valid_lifetime' : 2592000
}
@@ -122,10 +122,10 @@ def get_config():
tmp['on_link'] = 'off'
if conf.exists(['preferred-lifetime']):
- tmp['preferred_lifetime'] = conf.return_value(['preferred-lifetime'])
+ tmp['preferred_lifetime'] = int(conf.return_value(['preferred-lifetime']))
if conf.exists(['valid-lifetime']):
- tmp['valid_lifetime'] = conf.return_value(['valid-lifetime'])
+ tmp['valid_lifetime'] = int(conf.return_value(['valid-lifetime']))
intf['prefixes'].append(tmp)
@@ -134,6 +134,11 @@ def get_config():
return rtradv
def verify(rtradv):
+ for interface in rtradv['interfaces']:
+ for prefix in interface['prefixes']:
+ if not (prefix['valid_lifetime'] > prefix['preferred_lifetime']):
+ raise ConfigError('Prefix valid-lifetime must be greater then preferred-lifetime')
+
return None
def generate(rtradv):
diff --git a/src/conf_mode/snmp.py b/src/conf_mode/snmp.py
index 2b6140f41..eb0d20654 100755
--- a/src/conf_mode/snmp.py
+++ b/src/conf_mode/snmp.py
@@ -17,8 +17,8 @@
import os
from binascii import hexlify
+from netifaces import interfaces
from time import sleep
-from stat import S_IRWXU, S_IXGRP, S_IXOTH, S_IROTH, S_IRGRP
from sys import exit
from vyos.config import Config
@@ -36,6 +36,7 @@ config_file_daemon = r'/etc/snmp/snmpd.conf'
config_file_access = r'/usr/share/snmp/snmpd.conf'
config_file_user = r'/var/lib/snmp/snmpd.conf'
default_script_dir = r'/config/user-data/'
+systemd_override = r'/etc/systemd/system/snmpd.service.d/override.conf'
# SNMP OIDs used to mark auth/priv type
OIDs = {
@@ -66,7 +67,8 @@ default_config_data = {
'v3_traps': [],
'v3_users': [],
'v3_views': [],
- 'script_ext': []
+ 'script_ext': [],
+ 'vrf': ''
}
def rmfile(file):
@@ -174,9 +176,6 @@ def get_config():
snmp['trap_targets'].append(trap_tgt)
- #
- # 'set service snmp script-extensions'
- #
if conf.exists('script-extensions'):
for extname in conf.list_nodes('script-extensions extension-name'):
conf_script = conf.return_value('script-extensions extension-name {} script'.format(extname))
@@ -191,6 +190,10 @@ def get_config():
snmp['script_ext'].append(extension)
+ if conf.exists('vrf'):
+ snmp['vrf'] = conf.return_value('vrf')
+
+
#########################################################################
# ____ _ _ __ __ ____ _____ #
# / ___|| \ | | \/ | _ \ __ _|___ / #
@@ -393,7 +396,7 @@ def verify(snmp):
if not os.path.isfile(ext['script']):
print ("WARNING: script: {} doesn't exist".format(ext['script']))
else:
- os.chmod(ext['script'], S_IRWXU | S_IXGRP | S_IXOTH | S_IROTH | S_IRGRP)
+ chmod_755(ext['script'])
for listen in snmp['listen_address']:
addr = listen[0]
@@ -413,6 +416,9 @@ def verify(snmp):
else:
print('WARNING: SNMP listen address {0} not configured!'.format(addr))
+ if snmp['vrf'] and snmp['vrf'] not in interfaces():
+ raise ConfigError('VRF "{vrf}" does not exist'.format(**snmp))
+
# bail out early if SNMP v3 is not configured
if not snmp['v3_enabled']:
return None
@@ -512,11 +518,14 @@ def generate(snmp):
# This is even save if service is going to be removed
call('systemctl stop snmpd.service')
config_files = [config_file_client, config_file_daemon, config_file_access,
- config_file_user]
+ config_file_user, systemd_override]
for file in config_files:
rmfile(file)
- if snmp is None:
+ # Reload systemd manager configuration
+ call('systemctl daemon-reload')
+
+ if not snmp:
return None
# Write client config file
@@ -527,13 +536,17 @@ def generate(snmp):
render(config_file_access, 'snmp/usr.snmpd.conf.tmpl', snmp)
# Write access rights config file
render(config_file_user, 'snmp/var.snmpd.conf.tmpl', snmp)
+ # Write daemon configuration file
+ render(systemd_override, 'snmp/override.conf.tmpl', snmp)
return None
def apply(snmp):
- if snmp is None:
+ if not snmp:
return None
+ # Reload systemd manager configuration
+ call('systemctl daemon-reload')
# start SNMP daemon
call("systemctl restart snmpd.service")
diff --git a/src/conf_mode/ssh.py b/src/conf_mode/ssh.py
index 5a0ae059b..43fa2ff39 100755
--- a/src/conf_mode/ssh.py
+++ b/src/conf_mode/ssh.py
@@ -31,7 +31,7 @@ config_file = r'/etc/ssh/sshd_config'
systemd_override = r'/etc/systemd/system/ssh.service.d/override.conf'
default_config_data = {
- 'port' : '22',
+ 'port' : ['22'],
'log_level': 'INFO',
'password_authentication': 'yes',
'host_validation': 'yes',
@@ -137,9 +137,11 @@ def apply(ssh):
os.unlink(config_file)
if os.path.isfile(systemd_override):
os.unlink(systemd_override)
- else:
- # Reload systemd manager configuration
- call('systemctl daemon-reload')
+
+ # Reload systemd manager configuration
+ call('systemctl daemon-reload')
+
+ if ssh:
call('systemctl restart ssh.service')
return None
diff --git a/src/conf_mode/system-login.py b/src/conf_mode/system-login.py
index 5990c3777..93d4cc679 100755
--- a/src/conf_mode/system-login.py
+++ b/src/conf_mode/system-login.py
@@ -144,7 +144,8 @@ def get_config():
'disabled': False,
'key': '',
'port': '1812',
- 'timeout': '2'
+ 'timeout': '2',
+ 'priority': 255
}
conf.set_level(base_level + ['radius', 'server', server])
@@ -164,6 +165,10 @@ def get_config():
if conf.exists(['timeout']):
server_cfg['timeout'] = conf.return_value(['timeout'])
+ # Check if RADIUS server has priority
+ if conf.exists(['priority']):
+ server_cfg['priority'] = int(conf.return_value(['priority']))
+
# Append individual RADIUS server configuration to global server list
login['radius_server'].append(server_cfg)
diff --git a/src/conf_mode/system-syslog.py b/src/conf_mode/system-syslog.py
index 8b20e1135..cfc1ca55f 100755
--- a/src/conf_mode/system-syslog.py
+++ b/src/conf_mode/system-syslog.py
@@ -162,32 +162,31 @@ def generate_selectors(c, config_node):
# protocols and security are being mapped here
# for backward compatibility with old configs
# security and protocol mappings can be removed later
- if c.is_tag(config_node):
- nodes = c.list_nodes(config_node)
- selectors = ""
- for node in nodes:
- lvl = c.return_value(config_node + ' ' + node + ' level')
- if lvl == None:
- lvl = "err"
- if lvl == 'all':
- lvl = '*'
- if node == 'all' and node != nodes[-1]:
- selectors += "*." + lvl + ";"
- elif node == 'all':
- selectors += "*." + lvl
- elif node != nodes[-1]:
- if node == 'protocols':
- node = 'local7'
- if node == 'security':
- node = 'auth'
- selectors += node + "." + lvl + ";"
- else:
- if node == 'protocols':
- node = 'local7'
- if node == 'security':
- node = 'auth'
- selectors += node + "." + lvl
- return selectors
+ nodes = c.list_nodes(config_node)
+ selectors = ""
+ for node in nodes:
+ lvl = c.return_value(config_node + ' ' + node + ' level')
+ if lvl == None:
+ lvl = "err"
+ if lvl == 'all':
+ lvl = '*'
+ if node == 'all' and node != nodes[-1]:
+ selectors += "*." + lvl + ";"
+ elif node == 'all':
+ selectors += "*." + lvl
+ elif node != nodes[-1]:
+ if node == 'protocols':
+ node = 'local7'
+ if node == 'security':
+ node = 'auth'
+ selectors += node + "." + lvl + ";"
+ else:
+ if node == 'protocols':
+ node = 'local7'
+ if node == 'security':
+ node = 'auth'
+ selectors += node + "." + lvl
+ return selectors
def generate(c):
diff --git a/src/conf_mode/system_console.py b/src/conf_mode/system_console.py
index 0831232fb..034cbee63 100755
--- a/src/conf_mode/system_console.py
+++ b/src/conf_mode/system_console.py
@@ -74,12 +74,15 @@ def generate(console):
call(f'systemctl stop {basename}')
os.unlink(os.path.join(root, basename))
+ if not console:
+ return None
+
for device in console['device'].keys():
config_file = base_dir + f'/serial-getty@{device}.service'
- render(config_file, 'getty/serial-getty.service.tmpl', console['device'][device])
+ getty_wants_symlink = base_dir + f'/getty.target.wants/serial-getty@{device}.service'
- # Reload systemd manager configuration
- call('systemctl daemon-reload')
+ render(config_file, 'getty/serial-getty.service.tmpl', console['device'][device])
+ os.symlink(config_file, getty_wants_symlink)
# GRUB
# For existing serial line change speed (if necessary)
@@ -107,6 +110,10 @@ def generate(console):
def apply(console):
# reset screen blanking
call('/usr/bin/setterm -blank 0 -powersave off -powerdown 0 -term linux </dev/tty1 >/dev/tty1 2>&1')
+
+ # Reload systemd manager configuration
+ call('systemctl daemon-reload')
+
if not console:
return None
diff --git a/src/conf_mode/vpn_l2tp.py b/src/conf_mode/vpn_l2tp.py
index febe8c3b7..7e40be32a 100755
--- a/src/conf_mode/vpn_l2tp.py
+++ b/src/conf_mode/vpn_l2tp.py
@@ -278,7 +278,7 @@ def get_config():
l2tp['lns_shared_secret'] = conf.return_value(['lns', 'shared-secret'])
if conf.exists(['ccp-disable']):
- l2tp[['ccp_disable']] = True
+ l2tp['ccp_disable'] = True
# PPP options
if conf.exists(['idle']):