diff options
author | Christian Poessinger <christian@poessinger.com> | 2018-06-14 21:12:58 +0200 |
---|---|---|
committer | Christian Poessinger <christian@poessinger.com> | 2018-06-14 21:12:58 +0200 |
commit | e98c53f7c1ba846b3d27eceec1d7c2789c3a5b04 (patch) | |
tree | 11f095b28100eadb3052f5ac4d191e106a6e8096 | |
parent | 81db9345d117748a89059d2819b36b07ebdf708f (diff) | |
parent | a6c5fe6ea239fccb7769f9d9977f133161c58da4 (diff) | |
download | vyos-1x-e98c53f7c1ba846b3d27eceec1d7c2789c3a5b04.tar.gz vyos-1x-e98c53f7c1ba846b3d27eceec1d7c2789c3a5b04.zip |
Merge branch 'snmp-op-mode' into current
* snmp-op-mode:
T683: Initial version for SNMP op mode command definition in XML
-rw-r--r-- | op-mode-definitions/snmp.xml | 111 | ||||
-rwxr-xr-x | src/op_mode/snmp.py | 77 | ||||
-rwxr-xr-x | src/op_mode/snmp_ifmib.py | 128 | ||||
-rwxr-xr-x | src/op_mode/snmp_v3.py | 180 | ||||
-rwxr-xr-x | src/op_mode/snmp_v3_showcerts.sh | 8 |
5 files changed, 504 insertions, 0 deletions
diff --git a/op-mode-definitions/snmp.xml b/op-mode-definitions/snmp.xml new file mode 100644 index 000000000..a0a47da40 --- /dev/null +++ b/op-mode-definitions/snmp.xml @@ -0,0 +1,111 @@ +<?xml version="1.0"?> +<interfaceDefinition> + <node name="show"> + <children> + <node name="snmp"> + <properties> + <help>Show status of SNMP on localhost</help> + </properties> + <children> + <tagNode name="community"> + <properties> + <help>Show status of SNMP community</help> + <completionHelp> + <script>${vyos_op_scripts_dir}/snmp.py --allowed</script> + </completionHelp> + </properties> + <command>${vyos_op_scripts_dir}/snmp.py --community="$4"</command> + <children> + <tagNode name="host"> + <properties> + <help>Show status of SNMP on remote host</help> + </properties> + <command>${vyos_op_scripts_dir}/snmp.py --community="$4" --host "$6"</command> + </tagNode> + </children> + </tagNode> + <node name="mib"> + <properties> + <help>Show SNMP MIB information</help> + </properties> + <children> + <node name="ifmib"> + <properties> + <help>Show all SNMP interfaces MIB information</help> + </properties> + <command>${vyos_op_scripts_dir}/snmp_ifmib.py</command> + <children> + <tagNode name="ifAlias"> + <properties> + <help>Show SNMP ifAlias for specified interface</help> + <completionHelp> + <script>${vyos_completion_dir}/list_interfaces.py</script> + </completionHelp> + </properties> + <command>${vyos_op_scripts_dir}/snmp_ifmib.py --ifalias="$6"</command> + </tagNode> + <tagNode name="ifDescr"> + <properties> + <help>Show SNMP ifDescr for specified interface</help> + <completionHelp> + <script>${vyos_completion_dir}/list_interfaces.py</script> + </completionHelp> + </properties> + <command>${vyos_op_scripts_dir}/snmp_ifmib.py --ifdescr="$6"</command> + </tagNode> + <tagNode name="ifIndex"> + <properties> + <help>Show SNMP ifDescr for specified interface</help> + <completionHelp> + <script>${vyos_completion_dir}/list_interfaces.py</script> + </completionHelp> + </properties> + <command>${vyos_op_scripts_dir}/snmp_ifmib.py --ifindex="$6"</command> + </tagNode> + </children> + </node> + </children> + </node> + <node name="v3"> + <properties> + <help>Show SNMP v3 status on localhost</help> + </properties> + <command>${vyos_op_scripts_dir}/snmp_v3.py --all</command> + <children> + <leafNode name="certificates"> + <properties> + <help>Show TSM certificates</help> + </properties> + <command>${vyos_op_scripts_dir}/snmp_v3_showcerts.sh</command> + </leafNode> + <leafNode name="group"> + <properties> + <help>Show the list of configured groups</help> + </properties> + <command>${vyos_op_scripts_dir}/snmp_v3.py --group</command> + </leafNode> + <leafNode name="trap-target"> + <properties> + <help>Show the list of configured targets</help> + </properties> + <command>${vyos_op_scripts_dir}/snmp_v3.py --trap</command> + </leafNode> + <leafNode name="user"> + <properties> + <help>Show the list of configured users</help> + </properties> + <command>${vyos_op_scripts_dir}/snmp_v3.py --user</command> + </leafNode> + <leafNode name="view"> + <properties> + <help>Show the list of configured views</help> + </properties> + <command>${vyos_op_scripts_dir}/snmp_v3.py --view</command> + </leafNode> + </children> + </node> + </children> + </node> + </children> + </node> +</interfaceDefinition> diff --git a/src/op_mode/snmp.py b/src/op_mode/snmp.py new file mode 100755 index 000000000..e08441f0e --- /dev/null +++ b/src/op_mode/snmp.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2018 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/>. +# +# File: snmp.py +# Purpose: +# Show SNMP community/remote hosts +# Used by the "run show snmp community" commands. + +import os +import sys +import argparse + +from vyos.config import Config + +config_file_daemon = r'/etc/snmp/snmpd.conf' + +parser = argparse.ArgumentParser(description='Retrieve infomration from running SNMP daemon') +parser.add_argument('--allowed', action="store_true", help='Show available SNMP communities') +parser.add_argument('--community', action="store", help='Show status of given SNMP community', type=str) +parser.add_argument('--host', action="store", help='SNMP host to connect to', type=str, default='localhost') + +config = { + 'communities': [], +} + +def read_config(): + with open(config_file_daemon, 'r') as f: + for line in f: + # Only get configured SNMP communitie + if line.startswith('rocommunity') or line.startswith('rwcommunity'): + string = line.split(' ') + # append community to the output list only once + c = string[1] + if c not in config['communities']: + config['communities'].append(c) + +def show_all(): + if len(config['communities']) > 0: + print(' '.join(config['communities'])) + +def show_community(c, h): + print('Status of SNMP community {0} on {1}'.format(c, h), flush=True) + os.system('/usr/bin/snmpstatus -t1 -v1 -c {0} {1}'.format(c, h)) + +if __name__ == '__main__': + args = parser.parse_args() + + # Do nothing if service is not configured + c = Config() + if not c.exists_effective('service snmp'): + print("SNMP service is not configured") + sys.exit(0) + + read_config() + + if args.allowed: + show_all() + sys.exit(1) + elif args.community: + show_community(args.community, args.host) + sys.exit(1) + else: + parser.print_help() + sys.exit(1) diff --git a/src/op_mode/snmp_ifmib.py b/src/op_mode/snmp_ifmib.py new file mode 100755 index 000000000..9d56a950b --- /dev/null +++ b/src/op_mode/snmp_ifmib.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2018 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/>. +# +# File: snmp_ifmib.py +# Purpose: +# Show SNMP MIB information +# Used by the "run show snmp mib" commands. + +import sys +import argparse +import netifaces +import subprocess + +from vyos.config import Config + +parser = argparse.ArgumentParser(description='Retrieve SNMP interfaces information') +parser.add_argument('--ifindex', action='store', nargs='?', const='all', help='Show interface index') +parser.add_argument('--ifalias', action='store', nargs='?', const='all', help='Show interface aliase') +parser.add_argument('--ifdescr', action='store', nargs='?', const='all', help='Show interface description') + +def show_ifindex(i): + proc = subprocess.Popen(['/bin/ip', 'link', 'show', i], stdout=subprocess.PIPE) + (out, err) = proc.communicate() + # convert output to string + string = out.decode("utf-8") + + index = 'ifIndex = ' + string.split(':')[0] + return index.replace('\n', '') + +def show_ifalias(i): + proc = subprocess.Popen(['/bin/ip', 'link', 'show', i], stdout=subprocess.PIPE) + (out, err) = proc.communicate() + # convert output to string + string = out.decode("utf-8") + + if 'alias' in string: + alias = 'ifAlias = ' + string.split('alias')[1].lstrip() + else: + alias = 'ifAlias = ' + i + + return alias.replace('\n', '') + +def show_ifdescr(i): + ven_id = '' + dev_id = '' + + try: + with open(r'/sys/class/net/' + i + '/device/vendor', 'r') as f: + ven_id = f.read().replace('\n', '') + except FileNotFoundError: + pass + + try: + with open(r'/sys/class/net/' + i + '/device/device', 'r') as f: + dev_id = f.read().replace('\n', '') + except FileNotFoundError: + pass + + if ven_id == '' and dev_id == '': + ret = 'ifDescr = {0}'.format(i) + return ret + + device = str(ven_id) + ':' + str(dev_id) + proc = subprocess.Popen(['/usr/bin/lspci', '-mm', '-d', device], stdout=subprocess.PIPE) + (out, err) = proc.communicate() + + # convert output to string + string = out.decode("utf-8").split('"') + vendor = string[3] + device = string[5] + + ret = 'ifDescr = {0} {1}'.format(vendor, device) + return ret.replace('\n', '') + +if __name__ == '__main__': + args = parser.parse_args() + + # Do nothing if service is not configured + c = Config() + if not c.exists_effective('service snmp'): + print("SNMP service is not configured") + sys.exit(0) + + if args.ifindex: + if args.ifindex == 'all': + for i in netifaces.interfaces(): + print('{0}: {1}'.format(i, show_ifindex(i))) + else: + print('{0}: {1}'.format(args.ifindex, show_ifindex(args.ifindex))) + + elif args.ifalias: + if args.ifalias == 'all': + for i in netifaces.interfaces(): + print('{0}: {1}'.format(i, show_ifalias(i))) + else: + print('{0}: {1}'.format(args.ifalias, show_ifalias(args.ifalias))) + + elif args.ifdescr: + if args.ifdescr == 'all': + for i in netifaces.interfaces(): + print('{0}: {1}'.format(i, show_ifdescr(i))) + else: + print('{0}: {1}'.format(args.ifdescr, show_ifdescr(args.ifdescr))) + + else: + #eth0: ifIndex = 2 + # ifAlias = NET-MYBLL-MUCI-BACKBONE + # ifDescr = VMware VMXNET3 Ethernet Controller + #lo: ifIndex = 1 + for i in netifaces.interfaces(): + print('{0}:\t{1}'.format(i, show_ifindex(i))) + print('\t{0}'.format(show_ifalias(i))) + print('\t{0}'.format(show_ifdescr(i))) + + sys.exit(1) diff --git a/src/op_mode/snmp_v3.py b/src/op_mode/snmp_v3.py new file mode 100755 index 000000000..92601f15e --- /dev/null +++ b/src/op_mode/snmp_v3.py @@ -0,0 +1,180 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2018 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/>. +# +# File: snmp_v3.py +# Purpose: +# Show SNMP v3 information +# Used by the "run show snmp v3" commands. + +import sys +import jinja2 +import argparse + +from vyos.config import Config + +parser = argparse.ArgumentParser(description='Retrieve SNMP v3 information') +parser.add_argument('--all', action="store_true", help='Show all available information') +parser.add_argument('--group', action="store_true", help='Show the list of configured groups') +parser.add_argument('--trap', action="store_true", help='Show the list of configured targets') +parser.add_argument('--user', action="store_true", help='Show the list of configured users') +parser.add_argument('--view', action="store_true", help='Show the list of configured views') + +GROUP_OUTP_TMPL_SRC = """ +SNMPv3 Groups: + + Group View + ----- ---- + {% if group -%}{% for g in group -%} + {{ "%-20s" | format(g.name) }}{{ g.view }}({{ g.mode }}) + {% endfor %}{% endif %} +""" + +TRAPTGT_OUTP_TMPL_SRC = """ +SNMPv3 Trap-targets: + + Tpap-target Port Protocol Auth Priv Type EngineID User + ----------- ---- -------- ---- ---- ---- -------- ---- + {% if trap -%}{% for t in trap -%} + {{ "%-20s" | format(t.name) }} {{ t.port }} {{ t.proto }} {{ t.auth }} {{ t.priv }} {{ t.type }} {{ "%-32s" | format(t.engID) }} {{ t.user }} + {% endfor %}{% endif %} +""" + +USER_OUTP_TMPL_SRC = """ +SNMPv3 Users: + + User Auth Priv Mode Group + ---- ---- ---- ---- ----- + {% if user -%}{% for u in user -%} + {{ "%-20s" | format(u.name) }}{{ u.auth }} {{ u.priv }} {{ u.mode }} {{ u.group }} + {% endfor %}{% endif %} +""" + +VIEW_OUTP_TMPL_SRC = """ +SNMPv3 Views: + {% if view -%}{% for v in view %} + View : {{ v.name }} + OIDs : .{{ v.oids | join("\n .")}} + {% endfor %}{% endif %} +""" + +if __name__ == '__main__': + args = parser.parse_args() + + # Do nothing if service is not configured + c = Config() + if not c.exists_effective('service snmp v3'): + print("SNMP v3 is not configured") + sys.exit(0) + + data = { + 'group': [], + 'trap': [], + 'user': [], + 'view': [] + } + + if c.exists_effective('service snmp v3 group'): + for g in c.list_effective_nodes('service snmp v3 group'): + group = { + 'name': g, + 'mode': '', + 'view': '' + } + group['mode'] = c.return_effective_value('service snmp v3 group {0} mode'.format(g)) + group['view'] = c.return_effective_value('service snmp v3 group {0} view'.format(g)) + + data['group'].append(group) + + if c.exists_effective('service snmp v3 user'): + for u in c.list_effective_nodes('service snmp v3 user'): + user = { + 'name' : u, + 'mode' : '', + 'auth' : '', + 'priv' : '', + 'group': '' + } + user['mode'] = c.return_effective_value('service snmp v3 user {0} mode'.format(u)) + user['auth'] = c.return_effective_value('service snmp v3 user {0} auth type'.format(u)) + user['priv'] = c.return_effective_value('service snmp v3 user {0} privacy type'.format(u)) + user['group'] = c.return_effective_value('service snmp v3 user {0} group'.format(u)) + + data['user'].append(user) + + if c.exists_effective('service snmp v3 view'): + for v in c.list_effective_nodes('service snmp v3 view'): + view = { + 'name': v, + 'oids': [] + } + view['oids'] = c.list_effective_nodes('service snmp v3 view {0} oid'.format(v)) + + data['view'].append(view) + + if c.exists_effective('service snmp v3 trap-target'): + for t in c.list_effective_nodes('service snmp v3 trap-target'): + trap = { + 'name' : t, + 'port' : '', + 'proto': '', + 'auth' : '', + 'priv' : '', + 'type' : '', + 'engID': '', + 'user' : '' + } + trap['port'] = c.return_effective_value('service snmp v3 trap-target {0} port'.format(t)) + trap['proto'] = c.return_effective_value('service snmp v3 trap-target {0} protocol'.format(t)) + trap['auth'] = c.return_effective_value('service snmp v3 trap-target {0} auth type'.format(t)) + trap['priv'] = c.return_effective_value('service snmp v3 trap-target {0} privacy type'.format(t)) + trap['type'] = c.return_effective_value('service snmp v3 trap-target {0} type'.format(t)) + trap['engID'] = c.return_effective_value('service snmp v3 trap-target {0} engineid'.format(t)) + trap['user'] = c.return_effective_value('service snmp v3 trap-target {0} user'.format(t)) + + data['trap'].append(trap) + + print(data) + if args.all: + # Special case, print all templates ! + tmpl = jinja2.Template(GROUP_OUTP_TMPL_SRC) + print(tmpl.render(data)) + tmpl = jinja2.Template(TRAPTGT_OUTP_TMPL_SRC) + print(tmpl.render(data)) + tmpl = jinja2.Template(USER_OUTP_TMPL_SRC) + print(tmpl.render(data)) + tmpl = jinja2.Template(VIEW_OUTP_TMPL_SRC) + print(tmpl.render(data)) + + elif args.group: + tmpl = jinja2.Template(GROUP_OUTP_TMPL_SRC) + print(tmpl.render(data)) + + elif args.trap: + tmpl = jinja2.Template(TRAPTGT_OUTP_TMPL_SRC) + print(tmpl.render(data)) + + elif args.user: + tmpl = jinja2.Template(USER_OUTP_TMPL_SRC) + print(tmpl.render(data)) + + elif args.view: + tmpl = jinja2.Template(VIEW_OUTP_TMPL_SRC) + print(tmpl.render(data)) + + else: + parser.print_help() + + sys.exit(1) diff --git a/src/op_mode/snmp_v3_showcerts.sh b/src/op_mode/snmp_v3_showcerts.sh new file mode 100755 index 000000000..015b2e662 --- /dev/null +++ b/src/op_mode/snmp_v3_showcerts.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +files=`sudo ls /etc/snmp/tls/certs/ 2> /dev/null`; +if [ -n "$files" ]; then + sudo /usr/bin/net-snmp-cert showcerts --subject --fingerprint +else + echo "You don't have any certificates. Put it in '/etc/snmp/tls/certs/' folder." +fi |