summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--debian/control23
-rw-r--r--interface-definitions/cron.xml2
-rw-r--r--interface-definitions/dns-forwarding.xml2
-rw-r--r--interface-definitions/ntp.xml4
-rw-r--r--interface-definitions/ssh.xml65
-rw-r--r--op-mode-definitions/bandwidth-monitor.xml23
-rw-r--r--op-mode-definitions/traffic-dump.xml45
-rw-r--r--python/vyos/__init__.py1
-rw-r--r--python/vyos/base.py22
-rw-r--r--python/vyos/version.py4
-rwxr-xr-xscripts/build-command-op-templates61
-rwxr-xr-xsrc/conf-mode/vyos-config-bcast-relay.py2
-rwxr-xr-xsrc/conf-mode/vyos-config-dns-forwarding.py18
-rwxr-xr-xsrc/conf-mode/vyos-config-mdns-repeater.py2
-rwxr-xr-xsrc/conf-mode/vyos-config-ntp.py2
-rwxr-xr-xsrc/conf-mode/vyos-config-ssh.py82
-rwxr-xr-xsrc/conf-mode/vyos-update-crontab.py2
-rwxr-xr-xsrc/op-mode/vyos-list-dumpable-interfaces.py14
-rwxr-xr-xsrc/op-mode/vyos-list-interfaces.py8
-rwxr-xr-xsrc/op-mode/vyos-show-version.py2
21 files changed, 249 insertions, 136 deletions
diff --git a/Makefile b/Makefile
index c328d6a8d..8a75a91e4 100644
--- a/Makefile
+++ b/Makefile
@@ -26,6 +26,7 @@ op_mode_definitions:
rm -f $(OP_TMPL_DIR)/show/dns/node.def
rm -f $(OP_TMPL_DIR)/reset/node.def
rm -f $(OP_TMPL_DIR)/restart/node.def
+ rm -f $(OP_TMPL_DIR)/monitor/node.def
.PHONY: all
all: interface_definitions op_mode_definitions
diff --git a/debian/control b/debian/control
index 351715c07..c31c470e9 100644
--- a/debian/control
+++ b/debian/control
@@ -2,14 +2,27 @@ Source: vyos-1x
Section: contrib/net
Priority: extra
Maintainer: VyOS Package Maintainers <maintainers@vyos.net>
-Build-Depends: debhelper (>= 9), python3, python3-setuptools, quilt,
- python3-lxml
+Build-Depends: debhelper (>= 9),
+ quilt,
+ python3,
+ python3-setuptools,
+ quilt,
+ python3-lxml
Standards-Version: 3.9.6
Package: vyos-1x
Architecture: all
-Depends: python3, ${python3:Depends}, python3-netifaces,
- python3-jinja2, ipaddrcheck
- ${shlibs:Depends}, ${misc:Depends}
+Depends: python3,
+ ${python3:Depends},
+ python3-netifaces,
+ python3-jinja2,
+ python3-pystache,
+ ipaddrcheck,
+ tcpdump,
+ bmon,
+ hvinfo,
+ file,
+ ${shlibs:Depends},
+ ${misc:Depends}
Description: VyOS configuration scripts and data
VyOS configuration scripts, interface definitions, and everything
diff --git a/interface-definitions/cron.xml b/interface-definitions/cron.xml
index 8e4c1294a..65b95c5a4 100644
--- a/interface-definitions/cron.xml
+++ b/interface-definitions/cron.xml
@@ -45,7 +45,7 @@
<description>Execution interval in days</description>
</valueHelp>
<constraint>
- <regex>[1-9]([0-9]+)([mhd]{0,1})</regex>
+ <regex>[1-9]([0-9]*)([mhd]{0,1})</regex>
</constraint>
</properties>
</leafNode>
diff --git a/interface-definitions/dns-forwarding.xml b/interface-definitions/dns-forwarding.xml
index 81aa6063d..60b90c6a7 100644
--- a/interface-definitions/dns-forwarding.xml
+++ b/interface-definitions/dns-forwarding.xml
@@ -62,6 +62,7 @@
<leafNode name="ignore-hosts-file">
<properties>
<help>Do not use local /etc/hosts file in name resolution</help>
+ <valueless/>
</properties>
</leafNode>
<leafNode name="listen-on">
@@ -94,6 +95,7 @@
<leafNode name="system">
<properties>
<help>DNS forwarding to system nameservers</help>
+ <valueless/>
</properties>
</leafNode>
</children>
diff --git a/interface-definitions/ntp.xml b/interface-definitions/ntp.xml
index c6fd8aa14..d9930a262 100644
--- a/interface-definitions/ntp.xml
+++ b/interface-definitions/ntp.xml
@@ -19,21 +19,25 @@
<leafNode name="dynamic">
<properties>
<help>Allow server to be configured even if not reachable</help>
+ <valueless/>
</properties>
</leafNode>
<leafNode name="noselect">
<properties>
<help>Marks the server as unused</help>
+ <valueless/>
</properties>
</leafNode>
<leafNode name="preempt">
<properties>
<help>Specifies the association as preemptable rather than the default persistent</help>
+ <valueless/>
</properties>
</leafNode>
<leafNode name="prefer">
<properties>
<help>Marks the server as preferred</help>
+ <valueless/>
</properties>
</leafNode>
</children>
diff --git a/interface-definitions/ssh.xml b/interface-definitions/ssh.xml
index 7b2d0a3f9..dfae1d8ed 100644
--- a/interface-definitions/ssh.xml
+++ b/interface-definitions/ssh.xml
@@ -13,55 +13,71 @@
<children>
<node name="access-control">
<properties>
- <help>SSH user/group access controls. Directives are processed in this: deny-users, allow-users, deny-groups and allow-groups</help>
+ <help>SSH user/group access controls. Directives are processed in this: deny-users, allow-users, deny-groups and allow-groups</help>
</properties>
<children>
- <leafNode name="allow-groups">
- <properties>
- <help>Configure sshd_config access control for allowed groups</help>
- </properties>
- </leafNode>
- <leafNode name="allow-users">
- <properties>
- <help>Configure sshd_config access control for allowed users</help>
- </properties>
- </leafNode>
- <leafNode name="deny-groups">
- <properties>
- <help>Configure sshd_config access control for disallowed groups</help>
- </properties>
- </leafNode>
- <leafNode name="deny-users">
- <properties>
- <help>Configure sshd_config access control for disallowed users</help>
- </properties>
- </leafNode>
+ <node name="allow">
+ <children>
+ <leafNode name="group">
+ <properties>
+ <help>Login is allowed for users whose primary or supplementary group matches</help>
+ <multi/>
+ </properties>
+ </leafNode>
+ <leafNode name="user">
+ <properties>
+ <help>Login is allowed only for user names that match</help>
+ <multi/>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ <node name="deny">
+ <children>
+ <leafNode name="group">
+ <properties>
+ <help>Login is disallowed for users whose primary or supplementary group matches</help>
+ <multi/>
+ </properties>
+ </leafNode>
+ <leafNode name="user">
+ <properties>
+ <help>Login is disallowed for user names that match</help>
+ <multi/>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
</children>
</node>
<leafNode name="ciphers">
<properties>
- <help>Allowed ciphers</help>
+ <help>Specifies allowed Ciphers</help>
<completionHelp>
<script>ssh -Q cipher | tr '\n' ' '</script>
</completionHelp>
+ <multi/>
</properties>
</leafNode>
<leafNode name="disable-host-validation">
<properties>
<help>Don't validate the remote host name with DNS</help>
+ <valueless/>
</properties>
</leafNode>
<leafNode name="disable-password-authentication">
<properties>
<help>Don't allow unknown user to login with password</help>
+ <valueless/>
</properties>
</leafNode>
<leafNode name="key-exchange">
<properties>
- <help>Key exchange algorithms</help>
+ <help>Specifies available KEX (Key Exchange) algorithms</help>
<completionHelp>
<script>ssh -Q kex | tr '\n' ' '</script>
</completionHelp>
+ <multi/>
</properties>
</leafNode>
<leafNode name="listen-address">
@@ -109,10 +125,11 @@
</leafNode>
<leafNode name="mac">
<properties>
- <help>Allowed message authentication algorithms</help>
+ <help>Specifies available MAC (message authentication code) algorithms</help>
<completionHelp>
<script>ssh -Q mac | tr '\n' ' '</script>
</completionHelp>
+ <multi/>
</properties>
</leafNode>
<leafNode name="port">
diff --git a/op-mode-definitions/bandwidth-monitor.xml b/op-mode-definitions/bandwidth-monitor.xml
new file mode 100644
index 000000000..a6ddcfd4b
--- /dev/null
+++ b/op-mode-definitions/bandwidth-monitor.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ <node name="monitor">
+ <children>
+ <node name="bandwidth">
+ <properties>
+ <help>Monitor interface bandwidth in real time</help>
+ </properties>
+ <children>
+ <tagNode name="interface">
+ <command>bmon -p $4</command>
+ <properties>
+ <help>Monitor bandwidth usage on specified interface</help>
+ <completionHelp>
+ <script>${vyos_bindir}/vyos-list-interfaces.py</script>
+ </completionHelp>
+ </properties>
+ </tagNode>
+ </children>
+ </node>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/op-mode-definitions/traffic-dump.xml b/op-mode-definitions/traffic-dump.xml
new file mode 100644
index 000000000..be53f866b
--- /dev/null
+++ b/op-mode-definitions/traffic-dump.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ <node name="monitor">
+ <children>
+ <node name="traffic">
+ <properties>
+ <help>Monitor traffic dumps</help>
+ </properties>
+ <children>
+ <tagNode name="interface">
+ <command>tcpdump -i $4</command>
+ <properties>
+ <help>Monitor traffic dump from an interface</help>
+ <completionHelp>
+ <script>${vyos_bindir}/vyos-list-dumpable-interfaces.py</script>
+ </completionHelp>
+ </properties>
+ <children>
+ <tagNode name="filter">
+ <command>tcpdump -n -i $4 $6</command>
+ <properties>
+ <help>Monitor traffic matching filter conditions</help>
+ </properties>
+ </tagNode>
+ <tagNode name="save">
+ <command>tcpdump -n -i $4 -w $6</command>
+ <properties>
+ <help>Save traffic dump from an interface to a file</help>
+ </properties>
+ <children>
+ <tagNode name="filter">
+ <command>tcpdump -n -i $4 -w $6 $8</command>
+ <properties>
+ <help>Save a dump of traffic matching filter conditions to a file</help>
+ </properties>
+ </tagNode>
+ </children>
+ </tagNode>
+ </children>
+ </tagNode>
+ </children>
+ </node>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/python/vyos/__init__.py b/python/vyos/__init__.py
index e69de29bb..9b5ed21c9 100644
--- a/python/vyos/__init__.py
+++ b/python/vyos/__init__.py
@@ -0,0 +1 @@
+from .base import *
diff --git a/python/vyos/base.py b/python/vyos/base.py
new file mode 100644
index 000000000..6197ed074
--- /dev/null
+++ b/python/vyos/base.py
@@ -0,0 +1,22 @@
+# Copyright (c) 2018 VyOS maintainers and contributors
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the Software
+# is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+# OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+# IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+class ConfigError(Exception):
+ pass
diff --git a/python/vyos/version.py b/python/vyos/version.py
index b3eff3965..5d32d878d 100644
--- a/python/vyos/version.py
+++ b/python/vyos/version.py
@@ -19,10 +19,6 @@
import json
-class ConfigError(Exception):
- pass
-
-
def get_version_data(file='/opt/vyatta/etc/version.json'):
with open(file, 'r') as f:
version_data = json.load(f)
diff --git a/scripts/build-command-op-templates b/scripts/build-command-op-templates
index 72879fe74..865590c2c 100755
--- a/scripts/build-command-op-templates
+++ b/scripts/build-command-op-templates
@@ -93,7 +93,7 @@ def get_properties(p):
try:
props["help"] = p.find("help").text
except:
- pass
+ props["help"] = "No help available"
# Get the completion help strings
@@ -113,7 +113,7 @@ def get_properties(p):
for i in paths:
comp_exprs.append("/bin/cli-shell-api listNodes {0}".format(i.text))
for i in scripts:
- comp_exprs.append("sh -c \"{0}\"".format(i.text))
+ comp_exprs.append("{0}".format(i.text))
comp_help = " && ".join(comp_exprs)
props["comp_help"] = comp_help
except:
@@ -128,14 +128,6 @@ def make_node_def(props, command):
node_def = ""
- if "tag" in props:
- node_def += "tag:\n"
-
-
- if "type" in props:
- node_def += "type: {0}\n".format(props["type"])
-
-
if "help" in props:
node_def += "help: {0}\n".format(props["help"])
@@ -173,32 +165,45 @@ def process_node(n, tmpl_dir):
props = get_properties(props_elem)
- # Type should not be set for non-tag, non-leaf nodes
- if node_type != "node":
- props["type"] = "txt"
+ if node_type == "node":
+ if debug:
+ print("Processing node {}".format(name))
+
+ with open(os.path.join(make_path(my_tmpl_dir), "node.def"), "w") as f:
+ f.write(make_node_def(props, command))
+
+ if children is not None:
+ inner_nodes = children.iterfind("*")
+ for inner_n in inner_nodes:
+ process_node(inner_n, my_tmpl_dir)
if node_type == "tagNode":
- props["tag"] = "True"
-
+ if debug:
+ print("Processing tag node {}".format(name))
- with open(os.path.join(make_path(my_tmpl_dir), "node.def"), "w") as f:
- f.write(make_node_def(props, command))
+ os.makedirs(make_path(my_tmpl_dir), exist_ok=True)
+ with open(os.path.join(make_path(my_tmpl_dir), "node.def"), "w") as f:
+ f.write('help: {0}\0'.format(props['help']))
- if node_type == "node":
- inner_nodes = children.iterfind("*")
- for inner_n in inner_nodes:
- process_node(inner_n, my_tmpl_dir)
- if node_type == "tagNode":
my_tmpl_dir.append("node.tag")
- if debug:
- print("Created path for the tagNode:", end="")
os.makedirs(make_path(my_tmpl_dir), exist_ok=True)
- inner_nodes = children.iterfind("*")
- for inner_n in inner_nodes:
- process_node(inner_n, my_tmpl_dir)
+ if debug:
+ print("Created path for the tagNode: {}".format(make_path(my_tmpl_dir)), end="")
+
+ with open(os.path.join(make_path(my_tmpl_dir), "node.def"), "w") as f:
+ f.write(make_node_def(props, command))
+
+ if children is not None:
+ inner_nodes = children.iterfind("*")
+ for inner_n in inner_nodes:
+ process_node(inner_n, my_tmpl_dir)
else:
# This is a leaf node
- pass
+ if debug:
+ print("Processing leaf node {}".format(name))
+
+ with open(os.path.join(make_path(my_tmpl_dir), "node.def"), "w") as f:
+ f.write(make_node_def(props, command))
root = xml.getroot()
diff --git a/src/conf-mode/vyos-config-bcast-relay.py b/src/conf-mode/vyos-config-bcast-relay.py
index f60664051..785690d9c 100755
--- a/src/conf-mode/vyos-config-bcast-relay.py
+++ b/src/conf-mode/vyos-config-bcast-relay.py
@@ -23,7 +23,7 @@ import time
import subprocess
from vyos.config import Config
-from vyos.util import ConfigError
+from vyos import ConfigError
config_file = r'/etc/default/udp-broadcast-relay'
diff --git a/src/conf-mode/vyos-config-dns-forwarding.py b/src/conf-mode/vyos-config-dns-forwarding.py
index df273b321..be48cde60 100755
--- a/src/conf-mode/vyos-config-dns-forwarding.py
+++ b/src/conf-mode/vyos-config-dns-forwarding.py
@@ -23,7 +23,7 @@ import netifaces
import jinja2
from vyos.config import Config
-from vyos.util import ConfigError
+from vyos import ConfigError
config_file = r'/etc/powerdns/recursor.conf'
@@ -31,7 +31,6 @@ config_file = r'/etc/powerdns/recursor.conf'
# especially in the semicolon-separated lists of name servers.
# Please be careful if you edit the template.
config_tmpl = """
-
### Autogenerated by vyos-config-dns-forwarding.py ###
# Non-configurable defaults
@@ -47,19 +46,20 @@ max-cache-entries={{ cache_size }}
export-etc-hosts={{ export_hosts_file }}
# listen-on
-local-address= {{ listen_on | join(',') }}
+local-address={{ listen_on | join(',') }}
# domain ... server ...
{% if domains -%}
-{% for d in domains -%}
-forward-zones = {{ d.name }} = {{ d.servers | join(";") }}
-{% endfor -%}
+forward-zones={% for d in domains %}
+{{ d.name }}={{ d.servers | join(";") }}
+{%- if loop.first %}, {% endif %}
+{% endfor %}
{% endif %}
# name-server
-forward-zones-recurse=.= {{ name_servers | join(';') }}
+forward-zones-recurse=.={{ name_servers | join(';') }}
"""
@@ -113,7 +113,7 @@ def get_config():
if conf.exists('name-server'):
name_servers = conf.return_values('name-server')
- dns.setdefault('name_servers', name_servers)
+ dns['name_servers'] = dns['name_servers'] + name_servers
if conf.exists('system'):
conf.set_level('system')
@@ -185,7 +185,7 @@ def generate(dns):
if dns is None:
return None
- tmpl = jinja2.Template(config_tmpl)
+ tmpl = jinja2.Template(config_tmpl, trim_blocks=True)
config_text = tmpl.render(dns)
with open(config_file, 'w') as f:
diff --git a/src/conf-mode/vyos-config-mdns-repeater.py b/src/conf-mode/vyos-config-mdns-repeater.py
index 3b8ca26ad..e648fd64f 100755
--- a/src/conf-mode/vyos-config-mdns-repeater.py
+++ b/src/conf-mode/vyos-config-mdns-repeater.py
@@ -22,7 +22,7 @@ import netifaces
import time
from vyos.config import Config
-from vyos.util import ConfigError
+from vyos import ConfigError
config_file = r'/etc/default/mdns-repeater'
diff --git a/src/conf-mode/vyos-config-ntp.py b/src/conf-mode/vyos-config-ntp.py
index 061e8760e..8be12e44e 100755
--- a/src/conf-mode/vyos-config-ntp.py
+++ b/src/conf-mode/vyos-config-ntp.py
@@ -23,7 +23,7 @@ import jinja2
import ipaddress
from vyos.config import Config
-from vyos.util import ConfigError
+from vyos import ConfigError
config_file = r'/etc/ntp.conf'
diff --git a/src/conf-mode/vyos-config-ssh.py b/src/conf-mode/vyos-config-ssh.py
index 86b81366f..a4857bba9 100755
--- a/src/conf-mode/vyos-config-ssh.py
+++ b/src/conf-mode/vyos-config-ssh.py
@@ -22,7 +22,7 @@ import os
import jinja2
from vyos.config import Config
-from vyos.util import ConfigError
+from vyos import ConfigError
config_file = r'/etc/ssh/sshd_config'
@@ -87,7 +87,7 @@ ListenAddress {{ a }}
# Specifies the ciphers allowed. Multiple ciphers must be comma-separated.
#
# NOTE: As of now, there is no 'multi' node for 'ciphers', thus we have only one :/
-Ciphers {{ ciphers }}
+Ciphers {{ ciphers | join(",") }}
{% endif %}
{% if mac -%}
@@ -96,7 +96,7 @@ Ciphers {{ ciphers }}
# comma-separated.
#
# NOTE: As of now, there is no 'multi' node for 'mac', thus we have only one :/
-MACs {{ mac }}
+MACs {{ mac | join(",") }}
{% endif %}
{% if key_exchange -%}
@@ -104,7 +104,7 @@ MACs {{ mac }}
# be comma-separated.
#
# NOTE: As of now, there is no 'multi' node for 'key-exchange', thus we have only one :/
-KexAlgorithms {{ key_exchange }}
+KexAlgorithms {{ key_exchange | join(",") }}
{% endif %}
{% if allow_users -%}
@@ -152,58 +152,24 @@ def get_config():
else:
conf.set_level('service ssh')
- if conf.exists('access-control allow-users'):
- # Retrieve ',' separated list for allowed users and convert it to a list.
- # The current VyOS CLI implementation should be improved to rather use multi nodes
- # instead of a ',' separated input.
- allow_user = conf.return_value('access-control allow-users')
- tmp = allow_user.split(',')
- users = []
- for u in tmp:
- users.append(u)
-
- ssh.setdefault('allow_users', users)
-
- if conf.exists('access-control allow-groups'):
- # Retrieve ',' separated list for allowed groups and convert it to a list.
- # The current VyOS CLI implementation should be improved to rather use multi nodes
- # instead of a ',' separated input.
- allow_group = conf.return_value('access-control allow-groups')
- tmp = allow_group.split(',')
- groups = []
- for g in tmp:
- groups.append(g)
-
- ssh.setdefault('allow_groups', groups)
-
- if conf.exists('access-control deny-users'):
- # Retrieve ',' separated list for denied users and convert it to a list.
- # The current VyOS CLI implementation should be improved to rather use multi nodes
- # instead of a ',' separated input.
- deny_user = conf.return_value('access-control deny-users')
- tmp = deny_user.split(',')
- users = []
- for u in tmp:
- users.append(u)
-
- ssh.setdefault('deny_users', users)
-
- if conf.exists('access-control deny-groups'):
- # Retrieve ',' separated list for denied groups and convert it to a list.
- # The current VyOS CLI implementation should be improved to rather use multi nodes
- # instead of a ',' separated input.
- deny_group = conf.return_value('access-control deny-groups')
- tmp = deny_group.split(',')
- groups = []
- for g in tmp:
- groups.append(g)
-
- ssh.setdefault('deny_groups', groups)
+ if conf.exists('access-control allow user'):
+ allow_users = conf.return_values('access-control allow user')
+ ssh.setdefault('allow_users', allow_users)
+
+ if conf.exists('access-control allow group'):
+ allow_groups = conf.return_values('access-control allow group')
+ ssh.setdefault('allow_groups', allow_groups)
+
+ if conf.exists('access-control deny user'):
+ deny_users = conf.return_values('access-control deny user')
+ ssh.setdefault('deny_users', deny_users)
+
+ if conf.exists('access-control deny group'):
+ deny_groups = conf.return_values('access-control deny group')
+ ssh.setdefault('deny_groups', deny_groups)
if conf.exists('ciphers'):
- # TODO: OpenSSH supports having multiple Ciphers configured. VyOS CLI
- # yet has no multi node for this. See T632 in phabricator.
- ciphers = conf.return_value('ciphers')
+ ciphers = conf.return_values('ciphers')
ssh.setdefault('ciphers', ciphers)
if conf.exists('disable-host-validation'):
@@ -213,9 +179,7 @@ def get_config():
ssh['password_authentication'] = 'no'
if conf.exists('key-exchange'):
- # TODO: OpenSSH supports having multiple KEYX methods configured. VyOS CLI
- # yet has no multi node for this. See T632 in phabricator.
- kex = conf.return_value('key-exchange')
+ kex = conf.return_values('key-exchange')
ssh.setdefault('key_exchange', kex)
if conf.exists('listen-address'):
@@ -234,9 +198,7 @@ def get_config():
ssh['log_level'] = conf.return_value('loglevel')
if conf.exists('mac'):
- # TODO: OpenSSH supports having multiple MACs configured. VyOS CLI
- # yet has no multi node for this. See T632 in phabricator.
- mac = conf.return_value('mac')
+ mac = conf.return_values('mac')
ssh.setdefault('mac', mac)
if conf.exists('port'):
diff --git a/src/conf-mode/vyos-update-crontab.py b/src/conf-mode/vyos-update-crontab.py
index 2d15de8ea..c19b88007 100755
--- a/src/conf-mode/vyos-update-crontab.py
+++ b/src/conf-mode/vyos-update-crontab.py
@@ -21,7 +21,7 @@ import re
import sys
from vyos.config import Config
-from vyos.util import ConfigError
+from vyos import ConfigError
crontab_file = "/etc/cron.d/vyos-crontab"
diff --git a/src/op-mode/vyos-list-dumpable-interfaces.py b/src/op-mode/vyos-list-dumpable-interfaces.py
new file mode 100755
index 000000000..53ee89633
--- /dev/null
+++ b/src/op-mode/vyos-list-dumpable-interfaces.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python3
+
+# Extract the list of interfaces available for traffic dumps from tcpdump -D
+
+import re
+import subprocess
+
+if __name__ == '__main__':
+ out = subprocess.check_output(['/usr/sbin/tcpdump', '-D']).decode().strip()
+ out = out.split("\n")
+
+ intfs = " ".join(map(lambda s: re.search(r'\d+\.(\S+)\s', s).group(1), out))
+
+ print(intfs)
diff --git a/src/op-mode/vyos-list-interfaces.py b/src/op-mode/vyos-list-interfaces.py
new file mode 100755
index 000000000..59c9dffad
--- /dev/null
+++ b/src/op-mode/vyos-list-interfaces.py
@@ -0,0 +1,8 @@
+#!/usr/bin/env python3
+
+import netifaces
+
+if __name__ == '__main__':
+ interfaces = netifaces.interfaces()
+
+ print(" ".join(interfaces))
diff --git a/src/op-mode/vyos-show-version.py b/src/op-mode/vyos-show-version.py
index 0990dd648..ce3b3b54f 100755
--- a/src/op-mode/vyos-show-version.py
+++ b/src/op-mode/vyos-show-version.py
@@ -41,7 +41,7 @@ def read_file(name):
try:
with open (name, "r") as f:
data = f.read()
- return data.decode().strip()
+ return data.strip()
except:
# This works since we only read /sys/class/* stuff
# with this function