summaryrefslogtreecommitdiff
path: root/src/conf_mode/snmp.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/conf_mode/snmp.py')
-rwxr-xr-xsrc/conf_mode/snmp.py225
1 files changed, 37 insertions, 188 deletions
diff --git a/src/conf_mode/snmp.py b/src/conf_mode/snmp.py
index ac94afb1a..4a69e8742 100755
--- a/src/conf_mode/snmp.py
+++ b/src/conf_mode/snmp.py
@@ -15,18 +15,20 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
-import jinja2
-
-import vyos.version
-import vyos.validate
from binascii import hexlify
from time import sleep
from stat import S_IRWXU, S_IXGRP, S_IXOTH, S_IROTH, S_IRGRP
from sys import exit
+from jinja2 import FileSystemLoader, Environment
from vyos.config import Config
+from vyos.defaults import directories as vyos_data_dir
+from vyos.validate import is_ipv4, is_addr_assigned
+from vyos.version import get_version_data
from vyos import ConfigError
+from vyos.util import call
+
config_file_client = r'/etc/snmp/snmp.conf'
config_file_daemon = r'/etc/snmp/snmpd.conf'
@@ -43,171 +45,10 @@ OIDs = {
'none': '.1.3.6.1.6.3.10.1.2.1'
}
-# SNMP template (/etc/snmp/snmp.conf) - be careful if you edit the template.
-client_config_tmpl = """
-### Autogenerated by snmp.py ###
-{% if trap_source -%}
-clientaddr {{ trap_source }}
-{% endif %}
-
-"""
-
-# SNMP template (/usr/share/snmp/snmpd.conf) - be careful if you edit the template.
-access_config_tmpl = """
-### Autogenerated by snmp.py ###
-{%- for u in v3_users %}
-{{ u.mode }}user {{ u.name }}
-{%- endfor %}
-
-rwuser {{ vyos_user }}
-
-"""
-
-# SNMP template (/var/lib/snmp/snmpd.conf) - be careful if you edit the template.
-user_config_tmpl = """
-### Autogenerated by snmp.py ###
-# user
-{%- for u in v3_users %}
-{%- if u.authOID == 'none' %}
-createUser {{ u.name }}
-{%- elif u.authPassword %}
-createUser {{ u.name }} {{ u.authProtocol | upper }} "{{ u.authPassword }}" {{ u.privProtocol | upper }} {{ u.privPassword }}
-{%- else %}
-usmUser 1 3 {{ v3_engineid }} "{{ u.name }}" "{{ u.name }}" NULL {{ u.authOID }} {{ u.authMasterKey }} {{ u.privOID }} {{ u.privMasterKey }} 0x
-{%- endif %}
-{%- endfor %}
-
-createUser {{ vyos_user }} MD5 "{{ vyos_user_pass }}" DES
-{%- if v3_engineid %}
-oldEngineID {{ v3_engineid }}
-{%- endif %}
-"""
-
-# SNMP template (/etc/snmp/snmpd.conf) - be careful if you edit the template.
-daemon_config_tmpl = """
-### Autogenerated by snmp.py ###
-
-# non configurable defaults
-sysObjectID 1.3.6.1.4.1.44641
-sysServices 14
-master agentx
-agentXPerms 0777 0777
-pass .1.3.6.1.2.1.31.1.1.1.18 /opt/vyatta/sbin/if-mib-alias
-smuxpeer .1.3.6.1.2.1.83
-smuxpeer .1.3.6.1.2.1.157
-smuxsocket localhost
-
-# linkUp/Down configure the Event MIB tables to monitor
-# the ifTable for network interfaces being taken up or down
-# for making internal queries to retrieve any necessary information
-iquerySecName {{ vyos_user }}
-
-# Modified from the default linkUpDownNotification
-# to include more OIDs and poll more frequently
-notificationEvent linkUpTrap linkUp ifIndex ifDescr ifType ifAdminStatus ifOperStatus
-notificationEvent linkDownTrap linkDown ifIndex ifDescr ifType ifAdminStatus ifOperStatus
-monitor -r 10 -e linkUpTrap "Generate linkUp" ifOperStatus != 2
-monitor -r 10 -e linkDownTrap "Generate linkDown" ifOperStatus == 2
-
-########################
-# configurable section #
-########################
-
-# Default system description is VyOS version
-sysDescr VyOS {{ version }}
-
-{% if description %}
-# Description
-SysDescr {{ description }}
-{%- endif %}
-
-# Listen
-agentaddress unix:/run/snmpd.socket{% if listen_on %}{% for li in listen_on %},{{ li }}{% endfor %}{% else %},udp:161,udp6:161{% endif %}
-
-# SNMP communities
-{%- for c in communities %}
-
-{%- if c.network_v4 %}
-{%- for network in c.network_v4 %}
-{{ c.authorization }}community {{ c.name }} {{ network }}
-{%- endfor %}
-{%- elif not c.has_source %}
-{{ c.authorization }}community {{ c.name }}
-{%- endif %}
-
-{%- if c.network_v6 %}
-{%- for network in c.network_v6 %}
-{{ c.authorization }}community6 {{ c.name }} {{ network }}
-{%- endfor %}
-{%- elif not c.has_source %}
-{{ c.authorization }}community6 {{ c.name }}
-{%- endif %}
-
-{%- endfor %}
-
-{% if contact %}
-# system contact information
-SysContact {{ contact }}
-{%- endif %}
-
-{% if location %}
-# system location information
-SysLocation {{ location }}
-{%- endif %}
-
-{% if smux_peers -%}
-# additional smux peers
-{%- for sp in smux_peers %}
-smuxpeer {{ sp }}
-{%- endfor %}
-{%- endif %}
-
-{% if trap_targets -%}
-# if there is a problem - tell someone!
-{%- for t in trap_targets %}
-trap2sink {{ t.target }}{% if t.port -%}:{{ t.port }}{% endif %} {{ t.community }}
-{%- endfor %}
-{%- endif %}
-
-{%- if v3_enabled %}
-#
-# SNMPv3 stuff goes here
-#
-# views
-{%- for v in v3_views %}
-{%- for oid in v.oids %}
-view {{ v.name }} included .{{ oid.oid }}
-{%- endfor %}
-{%- endfor %}
-
-# access
-# context sec.model sec.level match read write notif
-{%- for g in v3_groups %}
-access {{ g.name }} "" usm {{ g.seclevel }} exact {{ g.view }} {% if g.mode == 'ro' %}none{% else %}{{ g.view }}{% endif %} none
-{%- endfor %}
-
-# trap-target
-{%- for t in v3_traps %}
-trapsess -v 3 {{ '-Ci' if t.type == 'inform' }} -e {{ v3_engineid }} -u {{ t.secName }} -l {{ t.secLevel }} -a {{ t.authProtocol }} {% if t.authPassword %}-A {{ t.authPassword }}{% elif t.authMasterKey %}-3m {{ t.authMasterKey }}{% endif %} -x {{ t.privProtocol }} {% if t.privPassword %}-X {{ t.privPassword }}{% elif t.privMasterKey %}-3M {{ t.privMasterKey }}{% endif %} {{ t.ipProto }}:{{ t.ipAddr }}:{{ t.ipPort }}
-{%- endfor %}
-
-# group
-{%- for u in v3_users %}
-group {{ u.group }} usm {{ u.name }}
-{% endfor %}
-{%- endif %}
-
-{% if script_ext %}
-# extension scripts
-{%- for ext in script_ext|sort(attribute='name') %}
-extend {{ ext.name }} {{ ext.script }}
-{%- endfor %}
-{% endif %}
-"""
-
default_config_data = {
'listen_on': [],
'listen_address': [],
+ 'ipv6_enabled': 'True',
'communities': [],
'smux_peers': [],
'location' : '',
@@ -237,9 +78,12 @@ def get_config():
if not conf.exists('service snmp'):
return None
else:
+ if conf.exists('system ipv6 disable'):
+ snmp['ipv6_enabled'] = False
+
conf.set_level('service snmp')
- version_data = vyos.version.get_version_data()
+ version_data = get_version_data()
snmp['version'] = version_data['version']
# create an internal snmpv3 user of the form 'vyosxxxxxxxxxxxxxxxx'
@@ -263,7 +107,7 @@ def get_config():
# Subnet of SNMP client(s) allowed to contact system
if conf.exists('community {0} network'.format(name)):
for addr in conf.return_values('community {0} network'.format(name)):
- if vyos.validate.is_ipv4(addr):
+ if is_ipv4(addr):
community['network_v4'].append(addr)
else:
community['network_v6'].append(addr)
@@ -271,7 +115,7 @@ def get_config():
# IP address of SNMP client allowed to contact system
if conf.exists('community {0} client'.format(name)):
for addr in conf.return_values('community {0} client'.format(name)):
- if vyos.validate.is_ipv4(addr):
+ if is_ipv4(addr):
community['network_v4'].append(addr)
else:
community['network_v6'].append(addr)
@@ -554,16 +398,16 @@ def verify(snmp):
addr = listen[0]
port = listen[1]
- if vyos.validate.is_ipv4(addr):
+ if is_ipv4(addr):
# example: udp:127.0.0.1:161
listen = 'udp:' + addr + ':' + port
- else:
+ elif snmp['ipv6_enabled']:
# example: udp6:[::1]:161
listen = 'udp6:' + '[' + addr + ']' + ':' + port
# We only wan't to configure addresses that exist on the system.
# Hint the user if they don't exist
- if vyos.validate.is_addr_assigned(addr):
+ if is_addr_assigned(addr):
snmp['listen_on'].append(listen)
else:
print('WARNING: SNMP listen address {0} not configured!'.format(addr))
@@ -665,35 +509,40 @@ def generate(snmp):
#
# As we are manipulating the snmpd user database we have to stop it first!
# This is even save if service is going to be removed
- os.system("systemctl stop snmpd.service")
- rmfile(config_file_client)
- rmfile(config_file_daemon)
- rmfile(config_file_access)
- rmfile(config_file_user)
+ call('systemctl stop snmpd.service')
+ config_files = [config_file_client, config_file_daemon, config_file_access,
+ config_file_user]
+ for file in config_files:
+ rmfile(file)
if snmp is None:
return None
+ # Prepare Jinja2 template loader from files
+ tmpl_path = os.path.join(vyos_data_dir['data'], 'templates', 'snmp')
+ fs_loader = FileSystemLoader(tmpl_path)
+ env = Environment(loader=fs_loader)
+
# Write client config file
- tmpl = jinja2.Template(client_config_tmpl)
+ tmpl = env.get_template('etc.snmp.conf.tmpl')
config_text = tmpl.render(snmp)
with open(config_file_client, 'w') as f:
f.write(config_text)
# Write server config file
- tmpl = jinja2.Template(daemon_config_tmpl)
+ tmpl = env.get_template('etc.snmpd.conf.tmpl')
config_text = tmpl.render(snmp)
with open(config_file_daemon, 'w') as f:
f.write(config_text)
# Write access rights config file
- tmpl = jinja2.Template(access_config_tmpl)
+ tmpl = env.get_template('usr.snmpd.conf.tmpl')
config_text = tmpl.render(snmp)
with open(config_file_access, 'w') as f:
f.write(config_text)
# Write access rights config file
- tmpl = jinja2.Template(user_config_tmpl)
+ tmpl = env.get_template('var.snmpd.conf.tmpl')
config_text = tmpl.render(snmp)
with open(config_file_user, 'w') as f:
f.write(config_text)
@@ -705,7 +554,7 @@ def apply(snmp):
return None
# start SNMP daemon
- os.system("systemctl restart snmpd.service")
+ call("systemctl restart snmpd.service")
# Passwords are not available immediately in the configuration file,
# after daemon startup - we wait until they have been processed by
@@ -746,15 +595,15 @@ def apply(snmp):
# Now update the running configuration
#
- # Currently when executing os.system() the environment does not
+ # Currently when executing call() the environment does not
# have the vyos_libexec_dir variable set, see Phabricator T685.
- os.system('/opt/vyatta/sbin/my_set service snmp v3 user "{0}" auth encrypted-key "{1}" > /dev/null'.format(cfg['user'], cfg['auth_pw']))
- os.system('/opt/vyatta/sbin/my_set service snmp v3 user "{0}" privacy encrypted-key "{1}" > /dev/null'.format(cfg['user'], cfg['priv_pw']))
- os.system('/opt/vyatta/sbin/my_delete service snmp v3 user "{0}" auth plaintext-key > /dev/null'.format(cfg['user']))
- os.system('/opt/vyatta/sbin/my_delete service snmp v3 user "{0}" privacy plaintext-key > /dev/null'.format(cfg['user']))
+ call('/opt/vyatta/sbin/my_set service snmp v3 user "{0}" auth encrypted-key "{1}" > /dev/null'.format(cfg['user'], cfg['auth_pw']))
+ call('/opt/vyatta/sbin/my_set service snmp v3 user "{0}" privacy encrypted-key "{1}" > /dev/null'.format(cfg['user'], cfg['priv_pw']))
+ call('/opt/vyatta/sbin/my_delete service snmp v3 user "{0}" auth plaintext-key > /dev/null'.format(cfg['user']))
+ call('/opt/vyatta/sbin/my_delete service snmp v3 user "{0}" privacy plaintext-key > /dev/null'.format(cfg['user']))
# Enable AgentX in FRR
- os.system('vtysh -c "configure terminal" -c "agentx" >/dev/null')
+ call('vtysh -c "configure terminal" -c "agentx" >/dev/null')
return None