summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/interface-types.json17
-rwxr-xr-xdebian/rules5
-rw-r--r--interface-definitions/snmp.xml4
-rw-r--r--python/vyos/defaults.py3
-rw-r--r--python/vyos/interfaces.py30
-rw-r--r--python/vyos/util.py50
-rw-r--r--python/vyos/version.py7
-rwxr-xr-xsrc/completion/list_interfaces.py31
-rwxr-xr-xsrc/conf_mode/snmp.py31
-rwxr-xr-xsrc/op_mode/cpu_summary.py24
10 files changed, 190 insertions, 12 deletions
diff --git a/data/interface-types.json b/data/interface-types.json
new file mode 100644
index 000000000..c452122af
--- /dev/null
+++ b/data/interface-types.json
@@ -0,0 +1,17 @@
+{
+ "loopback": "lo",
+ "dummy": "dum",
+ "ethernet": "eth",
+ "bonding": "bond",
+ "bridge": "br",
+ "pseudo-ethernet": "peth",
+ "openvpn": "vtun",
+ "tunnel": "tun",
+ "vti": "vti",
+ "l2tpv3": "l2tpeth",
+ "vxlan": "vxlan",
+ "wireless": "wireless",
+ "wirelessmodem": "wlm",
+ "input": "ifb",
+ "pppoe": "pppoe"
+}
diff --git a/debian/rules b/debian/rules
index 5bb6b5371..d284471ec 100755
--- a/debian/rules
+++ b/debian/rules
@@ -4,6 +4,7 @@ DIR := debian/vyos-1x
VYOS_SBIN_DIR := usr/sbin/
VYOS_BIN_DIR := usr/bin/
VYOS_LIBEXEC_DIR := usr/libexec/vyos
+VYOS_DATA_DIR := /usr/share/vyos
VYOS_CFG_TMPL_DIR := /opt/vyatta/share/vyatta-cfg/templates
VYOS_OP_TMPL_DIR := /opt/vyatta/share/vyatta-op/templates
@@ -54,3 +55,7 @@ override_dh_auto_install:
# Install operational command definitions
mkdir -p $(DIR)/$(VYOS_OP_TMPL_DIR)
cp -r templates-op/* $(DIR)/$(VYOS_OP_TMPL_DIR)
+
+ # Install data files
+ mkdir -p $(DIR)/$(VYOS_DATA_DIR)
+ cp -r data/* $(DIR)/$(VYOS_DATA_DIR)
diff --git a/interface-definitions/snmp.xml b/interface-definitions/snmp.xml
index 7928de5d7..76885a02a 100644
--- a/interface-definitions/snmp.xml
+++ b/interface-definitions/snmp.xml
@@ -216,11 +216,11 @@
</valueHelp>
<valueHelp>
<format>auth</format>
- <description>Messages are authenticated but not encrypted (AuthNoPriv)</description>
+ <description>Messages are authenticated but not encrypted (authNoPriv)</description>
</valueHelp>
<valueHelp>
<format>priv</format>
- <description>Messages are authenticated and encrypted (AuthPriv)</description>
+ <description>Messages are authenticated and encrypted (authPriv)</description>
</valueHelp>
<constraint>
<regex>(noauth|auth|priv)</regex>
diff --git a/python/vyos/defaults.py b/python/vyos/defaults.py
new file mode 100644
index 000000000..43f222cc7
--- /dev/null
+++ b/python/vyos/defaults.py
@@ -0,0 +1,3 @@
+directories = {
+ "data": "/usr/share/vyos/"
+}
diff --git a/python/vyos/interfaces.py b/python/vyos/interfaces.py
new file mode 100644
index 000000000..0759aaa2b
--- /dev/null
+++ b/python/vyos/interfaces.py
@@ -0,0 +1,30 @@
+import re
+import json
+
+import netifaces
+
+
+intf_type_data_file = '/usr/share/vyos/interface-types.json'
+
+def list_interfaces():
+ interfaces = netifaces.interfaces()
+
+ # Remove "fake" interfaces associated with drivers
+ for i in ["dummy0", "ip6tnl0", "tunl0", "ip_vti0", "ip6_vti0"]:
+ try:
+ interfaces.remove(i)
+ except ValueError:
+ pass
+
+ return interfaces
+
+def list_interfaces_of_type(typ):
+ with open(intf_type_data_file, 'r') as f:
+ types_data = json.load(f)
+
+ all_intfs = list_interfaces()
+ if not (typ in types_data.keys()):
+ raise ValueError("Unknown interface type: {0}".format(typ))
+ else:
+ r = re.compile('^{0}\d+'.format(types_data[typ]))
+ return list(filter(lambda i: re.match(r, i), all_intfs))
diff --git a/python/vyos/util.py b/python/vyos/util.py
new file mode 100644
index 000000000..9a36ef84f
--- /dev/null
+++ b/python/vyos/util.py
@@ -0,0 +1,50 @@
+import re
+
+
+def colon_separated_to_dict(data_string, uniquekeys=False):
+ """ Converts a string containing newline-separated entries
+ of colon-separated key-value pairs into a dict.
+
+ Such files are common in Linux /proc filesystem
+
+ Args:
+ data_string (str): data string
+ uniquekeys (bool): whether to insist that keys are unique or not
+
+ Returns: dict
+
+ Raises:
+ ValueError: if uniquekeys=True and the data string has
+ duplicate keys.
+
+ Note:
+ If uniquekeys=True, then dict entries are always strings,
+ otherwise they are always lists of strings.
+ """
+ key_value_re = re.compile('([^:]+)\s*\:\s*(.*)')
+
+ data_raw = re.split('\n', data_string)
+
+ data = {}
+
+ for l in data_raw:
+ l = l.strip()
+ if l:
+ match = re.match(key_value_re, l)
+ if match:
+ key = match.groups()[0].strip()
+ value = match.groups()[1].strip()
+ if key in data.keys():
+ if uniquekeys:
+ raise ValueError("Data string has duplicate keys: {0}".format(key))
+ else:
+ data[key].append(value)
+ else:
+ if uniquekeys:
+ data[key] = value
+ else:
+ data[key] = [value]
+ else:
+ pass
+
+ return data
diff --git a/python/vyos/version.py b/python/vyos/version.py
index 5d32d878d..545d4e76b 100644
--- a/python/vyos/version.py
+++ b/python/vyos/version.py
@@ -17,9 +17,14 @@
# 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.
+import os
import json
-def get_version_data(file='/opt/vyatta/etc/version.json'):
+import vyos.defaults
+
+version_file = os.path.join(vyos.defaults.directories['data'], 'version.json')
+
+def get_version_data(file=version_file):
with open(file, 'r') as f:
version_data = json.load(f)
return version_data
diff --git a/src/completion/list_interfaces.py b/src/completion/list_interfaces.py
index 59c9dffad..a4968c52f 100755
--- a/src/completion/list_interfaces.py
+++ b/src/completion/list_interfaces.py
@@ -1,8 +1,31 @@
#!/usr/bin/env python3
-import netifaces
+import sys
+import argparse
-if __name__ == '__main__':
- interfaces = netifaces.interfaces()
+import vyos.interfaces
- print(" ".join(interfaces))
+
+parser = argparse.ArgumentParser()
+group = parser.add_mutually_exclusive_group()
+group.add_argument("-t", "--type", type=str, help="List interfaces of specific type")
+group.add_argument("-b", "--broadcast", action="store_true", help="List all broadcast interfaces")
+
+args = parser.parse_args()
+
+if args.type:
+ try:
+ interfaces = vyos.interfaces.list_interfaces_of_type(args.type)
+
+ except ValueError as e:
+ print(e, file=sys.stderr)
+ print("")
+elif args.broadcast:
+ eth = vyos.interfaces.list_interfaces_of_type("ethernet")
+ bridge = vyos.interfaces.list_interfaces_of_type("bridge")
+ bond = vyos.interfaces.list_interfaces_of_type("bonding")
+ interfaces = eth + bridge + bond
+else:
+ interfaces = vyos.interfaces.list_interfaces()
+
+print(" ".join(interfaces))
diff --git a/src/conf_mode/snmp.py b/src/conf_mode/snmp.py
index 7623206b4..863f7e2e2 100755
--- a/src/conf_mode/snmp.py
+++ b/src/conf_mode/snmp.py
@@ -18,6 +18,7 @@
import sys
import os
+import shutil
import stat
import pwd
import time
@@ -46,7 +47,6 @@ OIDs = {
'des' : '.1.3.6.1.6.3.10.1.2.2',
'none': '.1.3.6.1.6.3.10.1.2.1'
}
-
# SNMPS template - be careful if you edit the template.
client_config_tmpl = """
### Autogenerated by snmp.py ###
@@ -634,6 +634,9 @@ def verify(snmp):
if user['privPassword'] == '' and user['privMasterKey'] == '':
raise ConfigError('Must specify encrypted-key or plaintext-key for user privacy')
+ if user['privMasterKey'] and user['engineID'] == '':
+ raise ConfigError('Can not have "encrypted-key" without engineid')
+
if user['authPassword'] == '' and user['authMasterKey'] == '' and user['privTsmKey'] == '':
raise ConfigError('Must specify auth or tsm-key for user auth')
@@ -711,12 +714,30 @@ def generate(snmp):
def apply(snmp):
if snmp is not None:
- if not os.path.exists('/config/snmp/tls'):
- os.makedirs('/config/snmp/tls')
- os.chmod('/config/snmp/tls', stat.S_IWUSR | stat.S_IRUSR)
+ nonvolatiledir = '/config/snmp/tls'
+ volatiledir = '/etc/snmp/tls'
+ if not os.path.exists(nonvolatiledir):
+ os.makedirs(nonvolatiledir)
+ os.chmod(nonvolatiledir, stat.S_IWUSR | stat.S_IRUSR)
# get uid for user 'snmp'
snmp_uid = pwd.getpwnam('snmp').pw_uid
- os.chown('/config/snmp/tls', snmp_uid, -1)
+ os.chown(nonvolatiledir, snmp_uid, -1)
+
+ # move SNMP certificate files from volatile location to non volatile /config/snmp
+ if os.path.exists(volatiledir) and os.path.isdir(volatiledir):
+ files = os.listdir(volatiledir)
+ for f in files:
+ shutil.move(volatiledir + '/' + f, nonvolatiledir)
+ os.chmod(nonvolatiledir + '/' + f, stat.S_IWUSR | stat.S_IRUSR)
+
+ os.rmdir(volatiledir)
+ os.symlink(nonvolatiledir, volatiledir)
+
+ if os.path.islink(volatiledir):
+ link = os.readlink(volatiledir)
+ if link != nonvolatiledir:
+ os.unlink(volatiledir)
+ os.symlink(nonvolatiledir, volatiledir)
# start SNMP daemon
os.system("sudo systemctl restart snmpd.service")
diff --git a/src/op_mode/cpu_summary.py b/src/op_mode/cpu_summary.py
new file mode 100755
index 000000000..3da5835e9
--- /dev/null
+++ b/src/op_mode/cpu_summary.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python3
+
+import re
+
+from vyos.util import colon_separated_to_dict
+
+
+FILE_NAME = '/proc/cpuinfo'
+
+with open(FILE_NAME, 'r') as f:
+ data_raw = f.read()
+
+data = colon_separated_to_dict(data_raw)
+
+# Accumulate all data in a dict for future support for machine-readable output
+cpu_data = {}
+cpu_data['cpu_number'] = len(data['processor'])
+cpu_data['models'] = list(set(data['model name']))
+
+# Strip extra whitespace from CPU model names, /proc/cpuinfo is prone to that
+cpu_data['models'] = map(lambda s: re.sub('\s+', ' ', s), cpu_data['models'])
+
+print("CPU(s): {0}".format(cpu_data['cpu_number']))
+print("CPU model(s): {0}".format(",".join(cpu_data['models'])))