From 3cacaf94f05fe92d5eda1574a07e5fd49881d97d Mon Sep 17 00:00:00 2001 From: zsdc Date: Fri, 25 Oct 2019 23:28:47 +0300 Subject: [XML templates] T1772: Add escaping of `\` symbol in `` --- scripts/build-command-templates | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build-command-templates b/scripts/build-command-templates index ba80eadb2..4fcdb8ade 100755 --- a/scripts/build-command-templates +++ b/scripts/build-command-templates @@ -125,7 +125,7 @@ def get_properties(p): regexes = [] regex_elements = vce.findall("regex") if regex_elements is not None: - regexes = list(map(lambda e: e.text.strip(), regex_elements)) + regexes = list(map(lambda e: e.text.strip().replace('\\','\\\\'), regex_elements)) if "" in regexes: print("Warning: empty regex, node will be accepting any value") -- cgit v1.2.3 From 2673f4790e19531fba719810a3a38e1917e57214 Mon Sep 17 00:00:00 2001 From: Daniil Baturin Date: Sun, 27 Oct 2019 15:22:49 +0100 Subject: T1773: add a script for converting the config to JSON. It also exposes those functions in vyos.configtree --- python/vyos/configtree.py | 14 ++++++++++++++ src/utils/vyos-config-to-json | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100755 src/utils/vyos-config-to-json diff --git a/python/vyos/configtree.py b/python/vyos/configtree.py index 8832a5a63..77cffe90b 100644 --- a/python/vyos/configtree.py +++ b/python/vyos/configtree.py @@ -105,6 +105,14 @@ class ConfigTree(object): self.__to_commands.argtypes = [c_void_p] self.__to_commands.restype = c_char_p + self.__to_json = self.__lib.to_json + self.__to_json.argtypes = [c_void_p] + self.__to_json.restype = c_char_p + + self.__to_json_ast = self.__lib.to_json_ast + self.__to_json_ast.argtypes = [c_void_p] + self.__to_json_ast.restype = c_char_p + self.__set_add_value = self.__lib.set_add_value self.__set_add_value.argtypes = [c_void_p, c_char_p, c_char_p] self.__set_add_value.restype = c_int @@ -184,6 +192,12 @@ class ConfigTree(object): def to_commands(self): return self.__to_commands(self.__config).decode() + def to_json(self): + return self.__to_json(self.__config).decode() + + def to_json_ast(self): + return self.__to_json_ast(self.__config).decode() + def set(self, path, value=None, replace=True): """Set new entry in VyOS configuration. path: configuration path e.g. 'system dns forwarding listen-address' diff --git a/src/utils/vyos-config-to-json b/src/utils/vyos-config-to-json new file mode 100755 index 000000000..e03fd6a59 --- /dev/null +++ b/src/utils/vyos-config-to-json @@ -0,0 +1,40 @@ +#!/usr/bin/python3 + +import sys +import json + +from signal import signal, SIGPIPE, SIG_DFL +from vyos.configtree import ConfigTree + +signal(SIGPIPE,SIG_DFL) + +config_string = None +if (len(sys.argv) == 1): + # If no argument given, act as a pipe + config_string = sys.stdin.read() +else: + file_name = sys.argv[1] + try: + with open(file_name, 'r') as f: + config_string = f.read() + except OSError as e: + print("Could not read config file {0}: {1}".format(file_name, e), file=sys.stderr) + +# This script is usually called with the output of "cli-shell-api showCfg", which does not +# escape backslashes. "ConfigTree()" expects escaped backslashes when parsing a config +# string (and also prints them itself). Therefore this script would fail. +# Manually escape backslashes here to handle backslashes in any configuration strings +# properly. The alternative would be to modify the output of "cli-shell-api showCfg", +# but that may be break other things who rely on that specific output. +config_string = config_string.replace("\\", "\\\\") + +try: + config = ConfigTree(config_string) + json_str = config.to_json() + # Pretty print + json_str = json.dumps(json.loads(json_str), indent=4, sort_keys=True) +except ValueError as e: + print("Could not parse the config file: {0}".format(e), file=sys.stderr) + sys.exit(1) + +print(json_str) -- cgit v1.2.3 From abecba2332d6b6756cf83ba2d87fcbf3640f0c18 Mon Sep 17 00:00:00 2001 From: Daniil Baturin Date: Sun, 27 Oct 2019 16:29:11 +0100 Subject: Replace the try and wait for segfault approach with explicit inSession check. --- python/vyos/config.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/python/vyos/config.py b/python/vyos/config.py index 3a340b2da..ee1adb289 100644 --- a/python/vyos/config.py +++ b/python/vyos/config.py @@ -104,12 +104,10 @@ class Config(object): running_config_text = f.read() # Session config ("active") only exists in conf mode. - # Trying to obtain it from op mode will cause a fatal cli-shell-api error. - # If that happens, we assume that a script is running from op mode and use the running config - # for the "session config" variable as well. - try: + # In op mode, we'll just use the same running config for both active and session configs. + if self.in_session(): session_config_text = self._run([self._cli_shell_api, '--show-working-only', '--show-show-defaults', 'showConfig']) - except VyOSError: + else: session_config_text = running_config_text self._session_config = vyos.configtree.ConfigTree(session_config_text) -- cgit v1.2.3 From a5d800400aaf9d1df61feb79c3626d37d0a3015d Mon Sep 17 00:00:00 2001 From: Daniil Baturin Date: Sun, 27 Oct 2019 16:38:55 +0100 Subject: Allow list arguments in the vyos.config show_config() function. --- python/vyos/config.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/python/vyos/config.py b/python/vyos/config.py index ee1adb289..5c2fc7285 100644 --- a/python/vyos/config.py +++ b/python/vyos/config.py @@ -222,7 +222,7 @@ class Config(object): except VyOSError: return False - def show_config(self, path='', default=None): + def show_config(self, path=[], default=None): """ Args: path (str): Configuration tree path, or empty @@ -231,6 +231,8 @@ class Config(object): Returns: str: working configuration """ + if isinstance(path, list): + path = " ".join(path) try: out = self._run(self._make_command('showConfig', path)) return out -- cgit v1.2.3 From 6564f5cef43f63cdcd70f05bca2222af48d63e59 Mon Sep 17 00:00:00 2001 From: kroy Date: Sun, 27 Oct 2019 10:39:03 -0500 Subject: T1759: Merging interface.py into ifconfig.py --- op-mode-definitions/wireguard.xml | 2 +- python/vyos/ifconfig.py | 98 ++++++++++++++++++++++++- python/vyos/interface.py | 150 -------------------------------------- src/op_mode/wireguard.py | 6 +- 4 files changed, 101 insertions(+), 155 deletions(-) delete mode 100644 python/vyos/interface.py diff --git a/op-mode-definitions/wireguard.xml b/op-mode-definitions/wireguard.xml index e52d0ad76..1795fb820 100644 --- a/op-mode-definitions/wireguard.xml +++ b/op-mode-definitions/wireguard.xml @@ -73,7 +73,7 @@ - sudo ${vyos_op_scripts_dir}/wireguard.py "$4" + sudo ${vyos_op_scripts_dir}/wireguard.py --showinterface "$4" diff --git a/python/vyos/ifconfig.py b/python/vyos/ifconfig.py index 3470b3aa6..aa2891ef3 100644 --- a/python/vyos/ifconfig.py +++ b/python/vyos/ifconfig.py @@ -17,12 +17,20 @@ import os import re import jinja2 import json +import glob +import time from vyos.validate import * +import vyos.interface +from vyos.config import Config from ipaddress import IPv4Network, IPv6Address from netifaces import ifaddresses, AF_INET, AF_INET6 from subprocess import Popen, PIPE, STDOUT from time import sleep +from os.path import isfile +from tabulate import tabulate +from hurry.filesize import size,alternative +from datetime import timedelta dhclient_base = r'/var/lib/dhcp/dhclient_' dhcp_cfg = """ @@ -671,6 +679,31 @@ class Interface: if os.path.isfile(self._dhcpv6_lease_file): os.remove(self._dhcpv6_lease_file) + def op_show_interface_stats(self): + stats = self.get_interface_stats() + rx = [['bytes','packets','errors','dropped','overrun','mcast'],[stats['rx_bytes'],stats['rx_packets'],stats['rx_errors'],stats['rx_dropped'],stats['rx_over_errors'],stats['multicast']]] + tx = [['bytes','packets','errors','dropped','carrier','collisions'],[stats['tx_bytes'],stats['tx_packets'],stats['tx_errors'],stats['tx_dropped'],stats['tx_carrier_errors'],stats['collisions']]] + output = "RX: \n" + output += tabulate(rx,headers="firstrow",numalign="right",tablefmt="plain") + output += "\n\nTX: \n" + output += tabulate(tx,headers="firstrow",numalign="right",tablefmt="plain") + print(' '.join(('\n'+output.lstrip()).splitlines(True))) + + def get_interface_stats(self): + interface_stats = dict() + devices = [f for f in glob.glob("/sys/class/net/**/statistics")] + for dev_path in devices: + metrics = [f for f in glob.glob(dev_path +"/**")] + dev = re.findall(r"/sys/class/net/(.*)/statistics",dev_path)[0] + dev_dict = dict() + for metric_path in metrics: + metric = metric_path.replace(dev_path+"/","") + if isfile(metric_path): + data = open(metric_path, 'r').read()[:-1] + dev_dict[metric] = int(data) + interface_stats[dev] = dev_dict + + return interface_stats[self._ifname] class LoopbackIf(Interface): @@ -1371,7 +1404,6 @@ class BondIf(VLANIf): return self._write_sysfs('/sys/class/net/{}/bonding/mode' .format(self._ifname), mode) - class WireGuardIf(Interface): """ Wireguard interface class, contains a comnfig dictionary since @@ -1447,6 +1479,70 @@ class WireGuardIf(Interface): cmd = "wg set {0} peer {1} remove".format( self._ifname, str(peerkey)) return self._cmd(cmd) + + def op_show_interface(self): + wgdump = vyos.interfaces.wireguard_dump().get(self._ifname,None) + + c = Config() + c.set_level(["interfaces","wireguard",self._ifname]) + description = c.return_effective_value(["description"]) + ips = c.return_effective_values(["address"]) + + print ("interface: {}".format(self._ifname)) + if (description): + print (" description: {}".format(description)) + + if (ips): + print (" address: {}".format(", ".join(ips))) + print (" public key: {}".format(wgdump['public_key'])) + print (" private key: (hidden)") + print (" listening port: {}".format(wgdump['listen_port'])) + print () + + for peer in c.list_effective_nodes(["peer"]): + if wgdump['peers']: + pubkey = c.return_effective_value(["peer",peer,"pubkey"]) + if pubkey in wgdump['peers']: + wgpeer = wgdump['peers'][pubkey] + + print (" peer: {}".format(peer)) + print (" public key: {}".format(pubkey)) + + """ figure out if the tunnel is recently active or not """ + status = "inactive" + if (wgpeer['latest_handshake'] is None): + """ no handshake ever """ + status = "inactive" + else: + if int(wgpeer['latest_handshake']) > 0: + delta = timedelta(seconds=int(time.time() - wgpeer['latest_handshake'])) + print (" latest handshake: {}".format(delta)) + if (time.time() - int(wgpeer['latest_handshake']) < (60*5)): + """ Five minutes and the tunnel is still active """ + status = "active" + else: + """ it's been longer than 5 minutes """ + status = "inactive" + elif int(wgpeer['latest_handshake']) == 0: + """ no handshake ever """ + status = "inactive" + print (" status: {}".format(status)) + + if wgpeer['endpoint'] is not None: + print (" endpoint: {}".format(wgpeer['endpoint'])) + + if wgpeer['allowed_ips'] is not None: + print (" allowed ips: {}".format(",".join(wgpeer['allowed_ips']).replace(",",", "))) + + if wgpeer['transfer_rx'] > 0 or wgpeer['transfer_tx'] > 0: + rx_size =size(wgpeer['transfer_rx'],system=alternative) + tx_size =size(wgpeer['transfer_tx'],system=alternative) + print (" transfer: {} received, {} sent".format(rx_size,tx_size)) + + if wgpeer['persistent_keepalive'] is not None: + print (" persistent keepalive: every {} seconds".format(wgpeer['persistent_keepalive'])) + print() + super().op_show_interface_stats() class VXLANIf(Interface, ): diff --git a/python/vyos/interface.py b/python/vyos/interface.py deleted file mode 100644 index cc726e5cc..000000000 --- a/python/vyos/interface.py +++ /dev/null @@ -1,150 +0,0 @@ -# Copyright 2019 VyOS maintainers and contributors -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library 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 -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library. If not, see . - -import vyos -from vyos.config import Config -import vyos.interfaces -import vyos.ioctl -from vyos.iflag import IFlag - -import re -import json - -import subprocess -import time -from datetime import timedelta -import glob -from os.path import isfile -from tabulate import tabulate -from hurry.filesize import size,alternative - -class Interface(): - - intf = None - intf_type = None - valid = False - flags = None - - def __init__(self,intf): - self.intf = intf - self.intf_type = vyos.interfaces.get_type_of_interface(self.intf) - self.valid = (self.intf in vyos.interfaces.list_interfaces()) - if (self.valid): - self.flags = vyos.ioctl.get_interface_flags(intf) - - def up(self): - """ return whether interface is up or not """ - return self.flags & IFlag.IFF_UP - - def print_interface(self): - - if not self.valid: - print("Invalid interface [{}]".format(self.intf)) - return - - if (self.intf_type == 'wireguard'): - self.print_wireguard_interface() - - self.print_interface_stats() - - def print_interface_stats(self): - stats = self.get_interface_stats() - rx = [['bytes','packets','errors','dropped','overrun','mcast'],[stats['rx_bytes'],stats['rx_packets'],stats['rx_errors'],stats['rx_dropped'],stats['rx_over_errors'],stats['multicast']]] - tx = [['bytes','packets','errors','dropped','carrier','collisions'],[stats['tx_bytes'],stats['tx_packets'],stats['tx_errors'],stats['tx_dropped'],stats['tx_carrier_errors'],stats['collisions']]] - output = "RX: \n" - output += tabulate(rx,headers="firstrow",numalign="right",tablefmt="plain") - output += "\n\nTX: \n" - output += tabulate(tx,headers="firstrow",numalign="right",tablefmt="plain") - print(' '.join(('\n'+output.lstrip()).splitlines(True))) - - def get_interface_stats(self): - interface_stats = dict() - devices = [f for f in glob.glob("/sys/class/net/**/statistics")] - for dev_path in devices: - metrics = [f for f in glob.glob(dev_path +"/**")] - dev = re.findall(r"/sys/class/net/(.*)/statistics",dev_path)[0] - dev_dict = dict() - for metric_path in metrics: - metric = metric_path.replace(dev_path+"/","") - if isfile(metric_path): - data = open(metric_path, 'r').read()[:-1] - dev_dict[metric] = int(data) - interface_stats[dev] = dev_dict - - return interface_stats[self.intf] - - def print_wireguard_interface(self): - - wgdump = vyos.interfaces.wireguard_dump().get(self.intf,None) - - c = Config() - c.set_level("interfaces wireguard {}".format(self.intf)) - description = c.return_effective_value("description") - ips = c.return_effective_values("address") - - print ("interface: {}".format(self.intf)) - if (description): - print (" description: {}".format(description)) - - if (ips): - print (" address: {}".format(", ".join(ips))) - print (" public key: {}".format(wgdump['public_key'])) - print (" private key: (hidden)") - print (" listening port: {}".format(wgdump['listen_port'])) - print () - - for peer in c.list_effective_nodes(' peer'): - if wgdump['peers']: - pubkey = c.return_effective_value("peer {} pubkey".format(peer)) - if pubkey in wgdump['peers']: - wgpeer = wgdump['peers'][pubkey] - - print (" peer: {}".format(peer)) - print (" public key: {}".format(pubkey)) - - """ figure out if the tunnel is recently active or not """ - status = "inactive" - if (wgpeer['latest_handshake'] is None): - """ no handshake ever """ - status = "inactive" - else: - if int(wgpeer['latest_handshake']) > 0: - delta = timedelta(seconds=int(time.time() - wgpeer['latest_handshake'])) - print (" latest handshake: {}".format(delta)) - if (time.time() - int(wgpeer['latest_handshake']) < (60*5)): - """ Five minutes and the tunnel is still active """ - status = "active" - else: - """ it's been longer than 5 minutes """ - status = "inactive" - elif int(wgpeer['latest_handshake']) == 0: - """ no handshake ever """ - status = "inactive" - print (" status: {}".format(status)) - - if wgpeer['endpoint'] is not None: - print (" endpoint: {}".format(wgpeer['endpoint'])) - - if wgpeer['allowed_ips'] is not None: - print (" allowed ips: {}".format(",".join(wgpeer['allowed_ips']).replace(",",", "))) - - if wgpeer['transfer_rx'] > 0 or wgpeer['transfer_tx'] > 0: - rx_size =size(wgpeer['transfer_rx'],system=alternative) - tx_size =size(wgpeer['transfer_tx'],system=alternative) - print (" transfer: {} received, {} sent".format(rx_size,tx_size)) - - if wgpeer['persistent_keepalive'] is not None: - print (" persistent keepalive: every {} seconds".format(wgpeer['persistent_keepalive'])) - print() diff --git a/src/op_mode/wireguard.py b/src/op_mode/wireguard.py index 6860aa3ea..38c061cf4 100755 --- a/src/op_mode/wireguard.py +++ b/src/op_mode/wireguard.py @@ -24,7 +24,7 @@ import subprocess import syslog as sl import re -from vyos.interface import Interface +from vyos.ifconfig import WireGuardIf from vyos import ConfigError from vyos.config import Config @@ -150,8 +150,8 @@ if __name__ == '__main__': if args.listkdir: list_key_dirs() if args.showinterface: - intf = Interface(args.showinterface) - intf.print_interface() + intf = WireGuardIf(args.showinterface) + intf.op_show_interface() if args.delkdir: if args.location: del_key_dir(args.location) -- cgit v1.2.3 From ad9bbd9edff6a057ba0c4d2a8984e2184345ca71 Mon Sep 17 00:00:00 2001 From: Daniil Baturin Date: Sun, 27 Oct 2019 17:10:30 +0100 Subject: T1773, T1774: add a show config operation with JSON and raw options. --- src/services/vyos-http-api-server | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/services/vyos-http-api-server b/src/services/vyos-http-api-server index 04c44c2be..571ec1258 100755 --- a/src/services/vyos-http-api-server +++ b/src/services/vyos-http-api-server @@ -207,11 +207,21 @@ def get_value(): elif op == 'exists': res = config.exists(path) elif op == 'showConfig': - config_format = 'raw' + config_format = 'json' if 'configFormat' in command: config_format = command['configFormat'] - res = session.show_config(command['path'], format=config_format) + res = session.show_config(path=command['path']) + if config_format == 'json': + config_tree = vyos.configtree.ConfigTree(res) + res = json.loads(config_tree.to_json()) + elif config_format == 'json_ast': + config_tree = vyos.configtree.ConfigTree(res) + res = json.loads(config_tree.to_json_ast()) + elif config_format == 'raw': + pass + else: + return error(400, "\"{0}\" is not a valid config format") else: return error(400, "\"{0}\" is not a valid operation".format(op)) except VyOSError as e: -- cgit v1.2.3 From 1c7b0ab60cb987ef4596758074ba6f824b01158e Mon Sep 17 00:00:00 2001 From: kroy Date: Sun, 27 Oct 2019 11:56:11 -0500 Subject: T1759: Fixing dependency bug from previous commit --- python/vyos/ifconfig.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/vyos/ifconfig.py b/python/vyos/ifconfig.py index aa2891ef3..df86e3c93 100644 --- a/python/vyos/ifconfig.py +++ b/python/vyos/ifconfig.py @@ -20,8 +20,8 @@ import json import glob import time +import vyos.interfaces from vyos.validate import * -import vyos.interface from vyos.config import Config from ipaddress import IPv4Network, IPv6Address from netifaces import ifaddresses, AF_INET, AF_INET6 -- cgit v1.2.3 From b86f1d702e3b67774d3a2eec1f9fa83108711798 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 27 Oct 2019 23:04:59 +0100 Subject: snmp: T1738: cleanup import statements --- src/conf_mode/snmp.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/conf_mode/snmp.py b/src/conf_mode/snmp.py index 74c17fff6..5a0c679c5 100755 --- a/src/conf_mode/snmp.py +++ b/src/conf_mode/snmp.py @@ -16,19 +16,17 @@ import sys import os -import shutil import stat import pwd -import time - import jinja2 -import random -import binascii import re import vyos.version import vyos.validate +from binascii import hexlify +from shutil import move +from time import sleep from vyos.config import Config from vyos import ConfigError @@ -257,10 +255,10 @@ def get_config(): version_data = vyos.version.get_version_data() snmp['version'] = version_data['version'] - # create an internal snmpv3 user of the form 'vyattaxxxxxxxxxxxxxxxx' + # create an internal snmpv3 user of the form 'vyosxxxxxxxxxxxxxxxx' # os.urandom(8) returns 8 bytes of random data - snmp['vyos_user'] = 'vyatta' + binascii.hexlify(os.urandom(8)).decode('utf-8') - snmp['vyos_user_pass'] = binascii.hexlify(os.urandom(16)).decode('utf-8') + snmp['vyos_user'] = 'vyos' + hexlify(os.urandom(8)).decode('utf-8') + snmp['vyos_user_pass'] = hexlify(os.urandom(16)).decode('utf-8') if conf.exists('community'): for name in conf.list_nodes('community'): @@ -723,7 +721,7 @@ def apply(snmp): if os.path.exists(volatiledir) and os.path.isdir(volatiledir): files = os.listdir(volatiledir) for f in files: - shutil.move(volatiledir + '/' + f, nonvolatiledir) + move(volatiledir + '/' + f, nonvolatiledir) os.chmod(nonvolatiledir + '/' + f, stat.S_IWUSR | stat.S_IRUSR) os.rmdir(volatiledir) @@ -744,7 +742,7 @@ def apply(snmp): snmpReady = False while not snmpReady: while not os.path.exists(config_file_user): - time.sleep(1) + sleep(1) with open(config_file_user, 'r') as f: for line in f: -- cgit v1.2.3 From ed642ff5e958c6ef43dee5ef684fb5ccf85ad8cf Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 27 Oct 2019 23:12:10 +0100 Subject: snmp: fix verify() bail out early order --- src/conf_mode/snmp.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/conf_mode/snmp.py b/src/conf_mode/snmp.py index 5a0c679c5..f2cc8bf17 100755 --- a/src/conf_mode/snmp.py +++ b/src/conf_mode/snmp.py @@ -549,10 +549,6 @@ def verify(snmp): else: os.chmod(snmp['script_ext'][ext], 0o555) - # bail out early if SNMP v3 is not configured - if not snmp['v3_enabled']: - return None - for listen in snmp['listen_address']: addr = listen[0] port = listen[1] @@ -571,6 +567,10 @@ def verify(snmp): else: print('WARNING: SNMP listen address {0} not configured!'.format(addr)) + # bail out early if SNMP v3 is not configured + if not snmp['v3_enabled']: + return None + if 'v3_groups' in snmp.keys(): for group in snmp['v3_groups']: # -- cgit v1.2.3 From 7021b97dad29d2e2509a0f5b7024eb506d04b62b Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 27 Oct 2019 23:21:59 +0100 Subject: snmp: fix verify() indent on script extensions --- src/conf_mode/snmp.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/conf_mode/snmp.py b/src/conf_mode/snmp.py index f2cc8bf17..f796e9978 100755 --- a/src/conf_mode/snmp.py +++ b/src/conf_mode/snmp.py @@ -543,11 +543,11 @@ def verify(snmp): ### check if the configured script actually exist under /config/user-data if snmp['script_ext']: - for ext in snmp['script_ext']: - if not os.path.isfile(snmp['script_ext'][ext]): - print ("WARNING: script: " + snmp['script_ext'][ext] + " doesn\'t exist") - else: - os.chmod(snmp['script_ext'][ext], 0o555) + for ext in snmp['script_ext']: + if not os.path.isfile(snmp['script_ext'][ext]): + print ("WARNING: script: " + snmp['script_ext'][ext] + " doesn\'t exist") + else: + os.chmod(snmp['script_ext'][ext], 0o555) for listen in snmp['listen_address']: addr = listen[0] -- cgit v1.2.3 From ebcb19b5b9a1ae57b3b0f902d6fb0259fe2ed209 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 27 Oct 2019 23:29:14 +0100 Subject: snmp: use proper stat literals on chmod() --- src/conf_mode/snmp.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/conf_mode/snmp.py b/src/conf_mode/snmp.py index f796e9978..a8c604bdd 100755 --- a/src/conf_mode/snmp.py +++ b/src/conf_mode/snmp.py @@ -27,6 +27,7 @@ import vyos.validate from binascii import hexlify from shutil import move from time import sleep +from stat import S_IRWXU,S_IXGRP,S_IXOTH from vyos.config import Config from vyos import ConfigError @@ -545,9 +546,9 @@ def verify(snmp): if snmp['script_ext']: for ext in snmp['script_ext']: if not os.path.isfile(snmp['script_ext'][ext]): - print ("WARNING: script: " + snmp['script_ext'][ext] + " doesn\'t exist") + print ("WARNING: script: {} doesn't exist".format(snmp['script_ext'][ext])) else: - os.chmod(snmp['script_ext'][ext], 0o555) + os.chmod(snmp['script_ext'][ext], S_IRWXU|S_IXGRP|S_IXOTH) for listen in snmp['listen_address']: addr = listen[0] -- cgit v1.2.3 From 8d57656ae0417af0f28ec2fac476b86e72dde110 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 27 Oct 2019 23:56:23 +0100 Subject: snmp: make script extension code more readable --- src/conf_mode/snmp.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/conf_mode/snmp.py b/src/conf_mode/snmp.py index a8c604bdd..b64cccbfa 100755 --- a/src/conf_mode/snmp.py +++ b/src/conf_mode/snmp.py @@ -202,7 +202,7 @@ group {{ u.group }} usm {{ u.name }} {% if script_ext %} # extension scripts {%- for ext in script_ext|sort %} -extend\t{{ext}}\t{{script_ext[ext]}} +extend {{ ext.name }} {{ ext.script }} {%- endfor %} {% endif %} """ @@ -238,7 +238,7 @@ default_config_data = { 'v3_traps': [], 'v3_users': [], 'v3_views': [], - 'script_ext': {} + 'script_ext': [] } def rmfile(file): @@ -347,9 +347,13 @@ def get_config(): # 'set service snmp script-extensions' # if conf.exists('script-extensions'): - for extname in conf.list_nodes('script-extensions extension-name'): - snmp['script_ext'][extname] = '/config/user-data/' + conf.return_value('script-extensions extension-name ' + extname + ' script') + for extname in conf.list_nodes('script-extensions extension-name'): + extension = { + 'name': extname, + 'script' : conf.return_value('script-extensions extension-name {} script'.format(extname)) + } + snmp['script_ext'].append(extension) ######################################################################### # ____ _ _ __ __ ____ _____ # @@ -545,10 +549,10 @@ def verify(snmp): ### check if the configured script actually exist under /config/user-data if snmp['script_ext']: for ext in snmp['script_ext']: - if not os.path.isfile(snmp['script_ext'][ext]): - print ("WARNING: script: {} doesn't exist".format(snmp['script_ext'][ext])) + if not os.path.isfile(ext['script']): + print ("WARNING: script: {} doesn't exist".format(ext['script'])) else: - os.chmod(snmp['script_ext'][ext], S_IRWXU|S_IXGRP|S_IXOTH) + os.chmod(ext['script'], S_IRWXU|S_IXGRP|S_IXOTH) for listen in snmp['listen_address']: addr = listen[0] -- cgit v1.2.3 From aac75107bc9988ecb599265da029827ff09bf713 Mon Sep 17 00:00:00 2001 From: Daniil Baturin Date: Mon, 28 Oct 2019 15:01:52 +0100 Subject: Add a function for retrieving config dicts. --- python/vyos/config.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/python/vyos/config.py b/python/vyos/config.py index 5c2fc7285..13b2c107e 100644 --- a/python/vyos/config.py +++ b/python/vyos/config.py @@ -65,6 +65,7 @@ In operational mode, all functions return values from the running config. import os import re +import json import subprocess import vyos.configtree @@ -225,7 +226,7 @@ class Config(object): def show_config(self, path=[], default=None): """ Args: - path (str): Configuration tree path, or empty + path (str list): Configuration tree path, or empty default (str): Default value to return Returns: @@ -239,6 +240,16 @@ class Config(object): except VyOSError: return(default) + def get_config_dict(self, path=[], effective=False): + """ + Args: path (str list): Configuration tree path, can be empty + Returns: a dict representation of the config + """ + res = self.show_config(self._make_path(path)) + config_tree = vyos.configtree.ConfigTree(res) + config_dict = json.loads(config_tree.to_json()) + return config_dict + def is_multi(self, path): """ Args: -- cgit v1.2.3 From 8ae02a738df9746ad648a9611ae03e62b5af9e5d Mon Sep 17 00:00:00 2001 From: zsdc Date: Mon, 28 Oct 2019 17:41:15 +0200 Subject: [XML templates] T1772: Changed old hacks to proper regex, according to the fix --- interface-definitions/https.xml | 2 +- interface-definitions/interfaces-bonding.xml | 2 +- interface-definitions/snmp.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/interface-definitions/https.xml b/interface-definitions/https.xml index 2fb3bf082..403d4ecb0 100644 --- a/interface-definitions/https.xml +++ b/interface-definitions/https.xml @@ -27,7 +27,7 @@ - ^\\*$ + ^\*$ diff --git a/interface-definitions/interfaces-bonding.xml b/interface-definitions/interfaces-bonding.xml index c71482d9c..ba1acfff6 100644 --- a/interface-definitions/interfaces-bonding.xml +++ b/interface-definitions/interfaces-bonding.xml @@ -159,7 +159,7 @@ combine IP address and port to make hash - (layer2\\+3|layer3\\+4|layer2) + (layer2\+3|layer3\+4|layer2) hash-policy must be layer2 layer2+3 or layer3+4 diff --git a/interface-definitions/snmp.xml b/interface-definitions/snmp.xml index 1634bfb64..c5f424e6f 100644 --- a/interface-definitions/snmp.xml +++ b/interface-definitions/snmp.xml @@ -604,7 +604,7 @@ Specifies the oid - ^[0-9]+(\\.[0-9]+)*$ + ^[0-9]+(\.[0-9]+)*$ OID must start from a number @@ -618,7 +618,7 @@ Defines a bit-mask that is indicating which subidentifiers of the associated subtree OID should be regarded as significant - ^[0-9a-f]{2}([\\.:][0-9a-f]{2})*$ + ^[0-9a-f]{2}([\.:][0-9a-f]{2})*$ MASK is a list of hex octets, separated by '.' or ':' -- cgit v1.2.3 From 7fc2a5c31f748bc821dd7d0c4856d707618e68c1 Mon Sep 17 00:00:00 2001 From: kroy Date: Wed, 30 Oct 2019 17:12:23 -0500 Subject: [conf completion]: T1779: Add tunnels to completion --- src/completion/list_interfaces.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/completion/list_interfaces.py b/src/completion/list_interfaces.py index 5e444ef78..84d17f89f 100755 --- a/src/completion/list_interfaces.py +++ b/src/completion/list_interfaces.py @@ -34,7 +34,8 @@ elif args.bridgeable: openvpn = vyos.interfaces.list_interfaces_of_type("openvpn") vxlan = vyos.interfaces.list_interfaces_of_type("vxlan") wireless = vyos.interfaces.list_interfaces_of_type("wireless") - interfaces = eth + bond + l2tpv3 + openvpn + vxlan + wireless + tunnel = vyos.interfaces.list_interfaces_of_type("tunnel") + interfaces = eth + bond + l2tpv3 + openvpn + vxlan + wireless + tunnel elif args.bondable: eth = vyos.interfaces.list_interfaces_of_type("ethernet") -- cgit v1.2.3