aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLadue, David (dl3158) <dl3158@att.com>2018-08-15 18:11:46 -0400
committerLadue, David (dl3158) <dl3158@att.com>2018-08-16 09:23:02 -0400
commit844c50d8b9b473b3daebdfe357ead3f904db9721 (patch)
tree1fe22551a3e1b212ee7f1e6a97826bab8645ad8e
parentcbad421e6448f15179c18db1892c88d18838a916 (diff)
adding snmpV3 support
Change-Id: I6250e30fa1aa2516a16c4906628be8cc904fbc71 Issue-ID: DCAEGEN2-630 Signed-off-by: Ladue, David (dl3158) <dl3158@att.com>
-rw-r--r--etc/snmptrapd.json165
-rwxr-xr-xmvn-phase-script.sh2
-rw-r--r--pom.xml2
-rw-r--r--setup.py4
-rwxr-xr-xsnmptrap/healthcheck.sh6
-rw-r--r--snmptrap/mod/trapd_get_cbs_config.py12
-rw-r--r--snmptrap/mod/trapd_http_session.py64
-rw-r--r--snmptrap/mod/trapd_io.py8
-rw-r--r--snmptrap/mod/trapd_settings.py13
-rw-r--r--snmptrap/mod/trapd_snmpv3.py195
-rw-r--r--snmptrap/snmptrapd.py199
-rwxr-xr-x[-rw-r--r--]snmptrap/snmptrapd.sh213
-rw-r--r--spec/snmptrap-collector-component-spec.json448
-rw-r--r--tests/snmp.setup.py2
-rw-r--r--tests/test_snmptrapd.py48
-rw-r--r--tests/test_trapd_get_cbs_config.py2
-rw-r--r--tests/test_trapd_io.py2
17 files changed, 952 insertions, 433 deletions
diff --git a/etc/snmptrapd.json b/etc/snmptrapd.json
index 630ebc6..e4fa44f 100644
--- a/etc/snmptrapd.json
+++ b/etc/snmptrapd.json
@@ -1,69 +1,108 @@
{
-"snmptrap.version": "1.3.0",
-"snmptrap.title": "ONAP SNMP Trap Receiver" ,
-"protocols.transport": "udp",
-"protocols.ipv4_interface": "0.0.0.0",
-"protocols.ipv4_port": 6162,
-"protocols.ipv6_interface": "::1",
-"protocols.ipv6_port": 6162,
-"cache.dns_cache_ttl_seconds": 60,
-"publisher.http_timeout_milliseconds": 1500,
-"publisher.http_retries": 3,
-"publisher.http_milliseconds_between_retries": 750,
-"publisher.http_primary_publisher": "true",
-"publisher.http_peer_publisher": "unavailable",
-"publisher.max_traps_between_publishes": 10,
-"publisher.max_milliseconds_between_publishes": 10000,
+ "snmptrapd": {
+ "version": "1.4.0",
+ "title": "ONAP SNMP Trap Receiver"
+ },
+ "protocols": {
+ "transport": "udp",
+ "ipv4_interface": "0.0.0.0",
+ "ipv4_port": 6162,
+ "ipv6_interface": "::1",
+ "ipv6_port": 6162
+ },
+ "cache": {
+ "dns_cache_ttl_seconds": 60
+ },
+ "publisher": {
+ "http_timeout_milliseconds": 1500,
+ "http_retries": 3,
+ "http_milliseconds_between_retries": 750,
+ "http_primary_publisher": "true",
+ "http_peer_publisher": "unavailable",
+ "max_traps_between_publishes": 10,
+ "max_milliseconds_between_publishes": 10000
+ },
"streams_publishes": {
- "sec_measurement": {
- "type": "message_router",
- "aaf_password": "aaf_password",
- "dmaap_info": {
- "location": "mtl5",
- "client_id": "111111",
- "client_role": "com.att.dcae.member",
- "topic_url": null
- },
- "aaf_username": "aaf_username"
+ "sec_fault_unsecure": {
+ "type": "message_router",
+ "aaf_password": null,
+ "dmaap_info": {
+ "location": "mtl5",
+ "client_id": null,
+ "client_role": null,
+ "topic_url": "http://localhost:3904/events/ONAP-COLLECTOR-SNMPTRAP"
+ },
+ "aaf_username": null
+ }
+ },
+ "files": {
+ "runtime_base_dir": "/opt/app/snmptrap",
+ "log_dir": "logs",
+ "data_dir": "data",
+ "pid_dir": "tmp",
+ "arriving_traps_log": "snmptrapd_arriving_traps.log",
+ "snmptrapd_diag": "snmptrapd_prog_diag.log",
+ "traps_stats_log": "snmptrapd_stats.csv",
+ "perm_status_file": "snmptrapd_status.log",
+ "eelf_base_dir": "/opt/app/snmptrap/logs",
+ "eelf_error": "error.log",
+ "eelf_debug": "debug.log",
+ "eelf_audit": "audit.log",
+ "eelf_metrics": "metrics.log",
+ "roll_frequency": "day",
+ "minimum_severity_to_log": 2
+ },
+ "trap_config": {
+ "sw_interval_in_seconds": 60,
+ "notify_oids": {
+ ".1.3.6.1.4.1.9.0.1": {
+ "sw_high_water_in_interval": 102,
+ "sw_low_water_in_interval": 7,
+ "category": "logonly"
},
- "sec_fault_unsecure": {
- "type": "message_router",
- "aaf_password": null,
- "dmaap_info": {
- "location": "mtl5",
- "client_id": null,
- "client_role": null,
- "topic_url": "http://ueb_server:3904/events/ONAP-COLLECTOR-SNMPTRAP"
- },
- "aaf_username": null
+ ".1.3.6.1.4.1.9.0.2": {
+ "sw_high_water_in_interval": 101,
+ "sw_low_water_in_interval": 7,
+ "category": "logonly"
+ },
+ ".1.3.6.1.4.1.9.0.3": {
+ "sw_high_water_in_interval": 102,
+ "sw_low_water_in_interval": 7,
+ "category": "logonly"
+ },
+ ".1.3.6.1.4.1.9.0.4": {
+ "sw_high_water_in_interval": 10,
+ "sw_low_water_in_interval": 3,
+ "category": "logonly"
}
+ }
},
-"files.runtime_base_dir": "/opt/app/snmptrap",
-"files.log_dir": "logs",
-"files.data_dir": "data",
-"files.pid_dir": "tmp",
-"files.arriving_traps_log": "snmptrapd_arriving_traps.log",
-"files.snmptrapd_diag": "snmptrapd_prog_diag.log",
-"files.traps_stats_log": "snmptrapd_stats.csv",
-"files.perm_status_file": "snmptrapd_status.log",
-"files.eelf_base_dir": "/opt/app/snmptrap/logs",
-"files.eelf_error": "error.log",
-"files.eelf_debug": "debug.log",
-"files.eelf_audit": "audit.log",
-"files.eelf_metrics": "metrics.log",
-"files.roll_frequency": "hour",
-"files.minimum_severity_to_log": 2,
-"trap_def.1.trap_oid" : ".1.3.6.1.4.1.74.2.46.12.1.1",
-"trap_def.1.trap_category": "ONAP-COLLECTOR-SNMPTRAP",
-"trap_def.2.trap_oid" : "*",
-"trap_def.2.trap_category": "ONAP-COLLECTOR-SNMPTRAP",
-"stormwatch.1.stormwatch_oid" : ".1.3.6.1.4.1.74.2.46.12.1.1",
-"stormwatch.1.low_water_rearm_per_minute" : "5",
-"stormwatch.1.high_water_arm_per_minute" : "100",
-"stormwatch.2.stormwatch_oid" : ".1.3.6.1.4.1.74.2.46.12.1.2",
-"stormwatch.2.low_water_rearm_per_minute" : "2",
-"stormwatch.2.high_water_arm_per_minute" : "200",
-"stormwatch.3.stormwatch_oid" : ".1.3.6.1.4.1.74.2.46.12.1.2",
-"stormwatch.3.low_water_rearm_per_minute" : "2",
-"stormwatch.3.high_water_arm_per_minute" : "200"
+ "snmpv3_config": {
+ "usm_users": [
+ {
+ "user": "usr-sha-aes256",
+ "engineId": "8000000001020304",
+ "usmHMACSHAAuth": "authkey1",
+ "usmAesCfb256": "privkey1"
+ },
+ {
+ "user": "user1",
+ "engineId": "8000000000000001",
+ "usmHMACMD5Auth": "authkey1",
+ "usmDESPriv": "privkey1"
+ },
+ {
+ "user": "user2",
+ "engineId": "8000000000000002",
+ "usmHMACSHAAuth": "authkey2",
+ "usmAesCfb128": "privkey2"
+ },
+ {
+ "user": "user3",
+ "engineId": "8000000000000003",
+ "usmHMACSHAAuth": "authkey3",
+ "usmAesCfb256": "privkey3"
+ }
+ ]
+ }
}
diff --git a/mvn-phase-script.sh b/mvn-phase-script.sh
index e195720..a14c292 100755
--- a/mvn-phase-script.sh
+++ b/mvn-phase-script.sh
@@ -29,7 +29,7 @@ PROJECT_ROOT=$(dirname $0)
echo "MVN_RELEASE_TAG is set to [$MVN_RELEASE_TAG]"
-RELEASE_TAG=${MVN_RELEASE_TAG:-R3}
+RELEASE_TAG=${MVN_RELEASE_TAG:-R2}
if [ "$RELEASE_TAG" != "R1" ]; then
RELEASE_TAGGED_DIR="${RELEASE_TAG}/"
else
diff --git a/pom.xml b/pom.xml
index 6f6bdaa..0e89237 100644
--- a/pom.xml
+++ b/pom.xml
@@ -30,7 +30,7 @@ ECOMP is a trademark and service mark of AT&T Intellectual Property.
<groupId>org.onap.dcaegen2.collectors</groupId>
<artifactId>snmptrap</artifactId>
<name>dcaegen2-collectors-snmptrap</name>
- <version>1.3.0-SNAPSHOT</version>
+ <version>1.4.0-SNAPSHOT</version>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
diff --git a/setup.py b/setup.py
index a299113..dc0c44b 100644
--- a/setup.py
+++ b/setup.py
@@ -27,11 +27,11 @@ from setuptools import setup, find_packages
setup(
name = "snmptrap",
description = "snmp trap receiver for ONAP docker image",
- version = "1.3.0",
+ version = "1.4.0",
packages=find_packages(),
install_requires=[
"pysnmp==4.4.2",
- "requests==2.19.1",
+ "requests==2.18.3",
"onap_dcae_cbs_docker_client==1.0.1"
],
author = "Dave L",
diff --git a/snmptrap/healthcheck.sh b/snmptrap/healthcheck.sh
index d23c859..371c18a 100755
--- a/snmptrap/healthcheck.sh
+++ b/snmptrap/healthcheck.sh
@@ -21,5 +21,7 @@
# health. A better possible health check is if the distribution client provided a
# health check call.
-exit 0
-
+# run standard status command, exit with results
+/opt/app/snmptrap/bin/snmptrapd.sh status > /dev/null 2>&1
+ret=$?
+exit ${ret}
diff --git a/snmptrap/mod/trapd_get_cbs_config.py b/snmptrap/mod/trapd_get_cbs_config.py
index 524f1c2..1506dca 100644
--- a/snmptrap/mod/trapd_get_cbs_config.py
+++ b/snmptrap/mod/trapd_get_cbs_config.py
@@ -86,6 +86,8 @@ def get_cbs_config():
stdout_logger(msg)
try:
tds.c_config = json.load(open(_cbs_sim_json_file))
+ msg = ("%s loaded and parsed successfully" % _cbs_sim_json_file)
+ stdout_logger(msg)
except Exception as e:
msg = "Unable to load CBS_SIM_JSON " + _cbs_sim_json_file + \
" (invalid json?) - FATAL ERROR, exiting"
@@ -94,25 +96,25 @@ def get_cbs_config():
# recalc timeout, set default if not present
try:
- tds.timeout_seconds = tds.c_config['publisher.http_timeout_milliseconds'] / 1000.0
+ tds.timeout_seconds = tds.c_config['publisher']['http_timeout_milliseconds'] * 1000.0
except Exception as e:
tds.timeout_seconds = 1.5
# recalc seconds_between_retries, set default if not present
try:
- tds.seconds_between_retries = tds.c_config['publisher.http_milliseconds_between_retries'] / 1000.0
+ tds.seconds_between_retries = tds.c_config['publisher']['http_milliseconds_between_retries'] * 1000.0
except Exception as e:
tds.seconds_between_retries = .750
# recalc min_severity_to_log, set default if not present
try:
- tds.minimum_severity_to_log = tds.c_config['files.minimum_severity_to_log']
+ tds.minimum_severity_to_log = tds.c_config['files']['minimum_severity_to_log']
except Exception as e:
tds.minimum_severity_to_log = 3
try:
- tds.publisher_retries = tds.c_config['publisher.http_retries']
+ tds.publisher_retries = tds.c_config['publisher']['http_retries']
except Exception as e:
- tds.publisher_retries = 3
+ tds.publisher_retries = 2
return True
diff --git a/snmptrap/mod/trapd_http_session.py b/snmptrap/mod/trapd_http_session.py
index b34c19d..3efca21 100644
--- a/snmptrap/mod/trapd_http_session.py
+++ b/snmptrap/mod/trapd_http_session.py
@@ -53,6 +53,68 @@ def init_session_obj():
try:
_loc_session = requests.Session()
except Exception as e:
- return None
+ msg = "Unable to create new http session - FATAL ERROR, exiting"
+ ecomp_logger(tds.LOG_TYPE_ERROR, tds.SEV_FATAL, tds.CODE_GENERAL, msg)
+ stdout_logger(msg)
+ cleanup_and_exit(1, tds.pid_file_name)
return _loc_session
+
+
+# # # # # # # # # # # # #
+# fx: close_session_obj
+# # # # # # # # # # # # #
+def close_session_obj(_loc_http_requ_session):
+ """
+ Closes existing http request session object
+ :Parameters:
+ _loc_http_requ_session
+ :Exceptions:
+ session object creation
+ this function will throw an exception if unable to create
+ a new session object
+ :Keywords:
+ http request session
+ :Variables:
+ none
+ """
+
+
+ # Close existing session if present.
+ if _loc_http_requ_session is not None:
+ try:
+ _loc_http_requ_session.close()
+ return True
+ except Exception as e:
+ msg = "Unable to close current http session - FATAL ERROR, exiting"
+ ecomp_logger(tds.LOG_TYPE_ERROR, tds.SEV_FATAL, tds.CODE_GENERAL, msg)
+ stdout_logger(msg)
+ cleanup_and_exit(1, tds.pid_file_name)
+
+
+# # # # # # # # # # # # #
+# fx: reset_session_obj
+# # # # # # # # # # # # #
+def reset_session_obj(_loc_http_requ_session):
+ """
+ Closes existing http request session object
+ and re-opens with current config vals
+ :Parameters:
+ _loc_http_requ_session
+ :Exceptions:
+ session object creation
+ this function will throw an exception if unable to create
+ a new session object
+ :Keywords:
+ http request session
+ :Variables:
+ none
+ """
+
+
+ # close existing http_requ_session if present
+ ret = close_session_obj(_loc_http_requ_session)
+
+ # open new http_requ_session
+ _loc_http_requ_session = init_session_obj()
+ return _loc_http_requ_session
diff --git a/snmptrap/mod/trapd_io.py b/snmptrap/mod/trapd_io.py
index ef67c69..d079cbe 100644
--- a/snmptrap/mod/trapd_io.py
+++ b/snmptrap/mod/trapd_io.py
@@ -117,7 +117,7 @@ def open_eelf_logs():
# open various ecomp logs - if any fails, exit
tds.eelf_error_file_name = (
- tds.c_config['files.eelf_base_dir'] + "/" + tds.c_config['files.eelf_error'])
+ tds.c_config['files']['eelf_base_dir'] + "/" + tds.c_config['files']['eelf_error'])
tds.eelf_error_fd = open_file(tds.eelf_error_file_name)
except Exception as e:
@@ -127,7 +127,7 @@ def open_eelf_logs():
try:
tds.eelf_debug_file_name = (
- tds.c_config['files.eelf_base_dir'] + "/" + tds.c_config['files.eelf_debug'])
+ tds.c_config['files']['eelf_base_dir'] + "/" + tds.c_config['files']['eelf_debug'])
tds.eelf_debug_fd = open_file(tds.eelf_debug_file_name)
except Exception as e:
@@ -137,7 +137,7 @@ def open_eelf_logs():
try:
tds.eelf_audit_file_name = (
- tds.c_config['files.eelf_base_dir'] + "/" + tds.c_config['files.eelf_audit'])
+ tds.c_config['files']['eelf_base_dir'] + "/" + tds.c_config['files']['eelf_audit'])
tds.eelf_audit_fd = open_file(tds.eelf_audit_file_name)
except Exception as e:
msg = "Error opening eelf audit log : " + str(e)
@@ -146,7 +146,7 @@ def open_eelf_logs():
try:
tds.eelf_metrics_file_name = (
- tds.c_config['files.eelf_base_dir'] + "/" + tds.c_config['files.eelf_metrics'])
+ tds.c_config['files']['eelf_base_dir'] + "/" + tds.c_config['files']['eelf_metrics'])
tds.eelf_metrics_fd = open_file(tds.eelf_metrics_file_name)
except Exception as e:
msg = "Error opening eelf metric log : " + str(e)
diff --git a/snmptrap/mod/trapd_settings.py b/snmptrap/mod/trapd_settings.py
index be87e26..308a2f2 100644
--- a/snmptrap/mod/trapd_settings.py
+++ b/snmptrap/mod/trapd_settings.py
@@ -115,7 +115,7 @@ def init():
# <json log of traps published>
global json_traps_filename
- json_log_filename = ""
+ json_traps_filename = ""
global json_traps_fd
json_fd = None
# </json log of traps published>
@@ -131,6 +131,17 @@ def init():
global pid_file_name
pid_file_name = ""
+ # <stormwatch>
+ global sw_participant_oid_dict
+ sw_participant_oid_dict = {}
+
+ global sw_count_dict
+ sw_count_dict = {}
+
+ global sw_interval_in_seconds
+ sw_interval_in_seconds = 60
+ # </stormwatch >
+
# <logging types and severities>
global LOG_TYPES
global LOG_TYPE_NONE
diff --git a/snmptrap/mod/trapd_snmpv3.py b/snmptrap/mod/trapd_snmpv3.py
new file mode 100644
index 0000000..97c048c
--- /dev/null
+++ b/snmptrap/mod/trapd_snmpv3.py
@@ -0,0 +1,195 @@
+# ============LICENSE_START=======================================================
+# org.onap.dcae
+# ================================================================================
+# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============LICENSE_END=========================================================
+#
+# ECOMP is a trademark and service mark of AT&T Intellectual Property.
+#
+"""
+module for snmpv3 support
+
+- loads various USM values for engineID/users
+
+"""
+
+__docformat__ = 'restructuredtext'
+
+import json
+import os
+import sys
+import string
+import time
+import traceback
+import collections
+import pprint
+
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import ntfrcv
+from pysnmp.proto.api import v2c
+
+import trapd_settings as tds
+from trapd_exit import cleanup_and_exit
+from trapd_io import stdout_logger, ecomp_logger
+
+prog_name = os.path.basename(__file__)
+
+
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+# module: init
+# FMDL: should this re-establish listener, with
+# blank V3 config attribs?
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+
+def init():
+
+ global v3_config_dict
+ v3_config_dict = {}
+
+
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+# module: load_snmpv3_credentials
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+
+def load_snmpv3_credentials (_py_config, _snmp_engine, _cbs_config):
+ """
+ Add V3 credentials from CBS config to receiver config
+ so traps will be recieved from specified engines/users
+ :Parameters:
+ _config: snmp entity config
+ :Exceptions:
+ """
+
+ # add V3 credentials from CBS json structure to running config
+ try:
+ v3_users=_cbs_config["snmpv3_config"]["usm_users"]
+ except Exception as e:
+ msg = ("No V3 users defined")
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
+ return _py_config, _snmp_engine
+
+ for v3_user in v3_users:
+
+ # engineId
+ try:
+ ctx_engine_id=v3_user['engineId']
+ except Exception as e:
+ ctx_engine_id=None
+
+ # user
+ try:
+ userName=v3_user['user']
+ except Exception as e:
+ userName=None
+
+ # authorization
+ # find options at -> site-packages/pysnmp/entity/config.py
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ # print("Checking auth for %s" % (userName))
+
+ # usmHMACMD5Auth
+ try:
+ authKey=v3_user['usmHMACMD5Auth']
+ authProtocol=config.usmHMACMD5AuthProtocol
+ except Exception as e:
+ # usmHMACSHAAuth
+ try:
+ authKey=v3_user['usmHMACSHAAuth']
+ authProtocol=config.usmHMAC192SHA256AuthProtocol
+ except Exception as e:
+ # usmNoAuth
+ try:
+ authKey=v3_user['usmNoAuth']
+ authProtocol=config.usmNoAuthProtocol
+ except Exception as e:
+ # FMDL: default to NoAuth, or error/skip entry?
+ msg = ("No auth specified for user %s ?" % (userName))
+ authKey=None
+ authProtocol=config.usmNoAuthProtocol
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
+ # break
+
+ # privacy
+ # find options at -> site-packages/pysnmp/entity/config.py
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ # print("Checking priv for %s" % (userName))
+
+ # usm3DESEDEPriv
+ try:
+ privKey=v3_user['usm3DESEDEPriv']
+ privProtocol=config.usm3DESEDEPrivProtocol
+ except Exception as e:
+ # usmAesCfb128
+ try:
+ privKey=v3_user['usmAesCfb128']
+ privProtocol=config.usmAesCfb128Protocol
+ except Exception as e:
+ # usmAesCfb192
+ try:
+ privKey=v3_user['usmAesCfb192']
+ privProtocol=config.usmAesCfb192Protocol
+ except Exception as e:
+ # usmAesCfb256
+ try:
+ privKey=v3_user['usmAesCfb256']
+ privProtocol=config.usmAesCfb256Protocol
+ except Exception as e:
+ # usmDESPriv
+ try:
+ privKey=v3_user['usmDESPriv']
+ privProtocol=config.usmDESPrivProtocol
+ except Exception as e:
+ # usmNoPriv
+ try:
+ privKey=v3_user['usmNoPriv']
+ privProtocol=config.usmNoPrivProtocol
+ except Exception as e:
+ # FMDL: default to NoPriv, or error/skip entry?
+ msg = ("No priv specified for user %s" % (userName))
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
+ privKey=None
+ privProtocol=config.usmNoPrivProtocol
+ # break
+
+ # msg = ("userName: %s authKey: %s authProtocol: %s privKey: %s privProtocol: %s engineId: %s % (userName, authKey, authProtocol, privKey, privProtocol, ctx_engine_id))
+ msg = ("userName: %s authKey: **** authProtocol: %s privKey: **** privProtocol: %s engineId: ****" % (userName, authProtocol, privProtocol))
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
+
+ # user: usr-md5-des, auth: MD5, priv DES, contextEngineId: 8000000001020304
+ # this USM entry is used for TRAP receiving purposes
+
+ # help(addV3User) returns ->
+ # addV3User(snmpEngine, userName, authProtocol=(1, 3, 6, 1, 6, 3, 10, 1, 1, 1), authKey=None, privProtocol=(1, 3, 6, 1, 6, 3, 10, 1, 2, 1), priv Key=None, securityEngineId=None, securityName=None, contextEngineId=None)
+
+ if ctx_engine_id is not None:
+ config.addV3User(
+ _snmp_engine, userName,
+ authProtocol, authKey,
+ privProtocol, privKey,
+ contextEngineId=v2c.OctetString(hexValue=ctx_engine_id)
+ )
+ else:
+ config.addV3User(
+ _snmp_engine, userName,
+ authProtocol, authKey,
+ privProtocol, privKey
+ )
+
+ return _py_config, _snmp_engine
diff --git a/snmptrap/snmptrapd.py b/snmptrap/snmptrapd.py
index f435c30..cbf004b 100644
--- a/snmptrap/snmptrapd.py
+++ b/snmptrap/snmptrapd.py
@@ -28,7 +28,7 @@ As traps arrive they are decomposed and transformed into a JSON message which
is published to a dmaap instance that has been defined by controller.
:Parameters:
- usage: snmptrapd.py [-v]
+ usage: snmptrapd.py
:Keywords:
onap dcae snmp trap publish dmaap
"""
@@ -65,14 +65,15 @@ from pysnmp.carrier.asyncio.dgram import udp, udp6
# from pysnmp.carrier.asyncore.dgram import udp
from pysnmp.entity.rfc3413 import ntfrcv
from pysnmp.proto.api import v2c
+from pysnmp import debug
# dcae_snmptrap
import trapd_settings as tds
from trapd_runtime_pid import save_pid, rm_pid
from trapd_get_cbs_config import get_cbs_config
from trapd_exit import cleanup_and_exit
-from trapd_http_session import init_session_obj
-
+from trapd_http_session import init_session_obj, close_session_obj, reset_session_obj
+from trapd_snmpv3 import init, load_snmpv3_credentials
from trapd_io import roll_all_logs, open_eelf_logs, roll_file, open_file, close_file, ecomp_logger, stdout_logger
prog_name = os.path.basename(__file__)
@@ -95,7 +96,7 @@ def usage_err():
"""
print('Incorrect usage invoked. Correct usage:')
- print(' %s [-v]' % prog_name)
+ print(' %s' % prog_name)
cleanup_and_exit(1, "undefined")
@@ -127,36 +128,34 @@ def load_all_configs(_signum, _frame):
ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_DETAILED,
tds.CODE_GENERAL, msg)
- # Initialize dmaap requests session object. Close existing session
- # if applicable.
- if tds.http_requ_session is not None:
- tds.http_requ_session.close()
-
- tds.http_requ_session = init_session_obj()
- if tds.http_requ_session is None:
- msg = "Unable to create new http session - FATAL ERROR, exiting"
- ecomp_logger(tds.LOG_TYPE_ERROR, tds.SEV_FATAL, tds.CODE_GENERAL, msg)
- stdout_logger(msg)
- cleanup_and_exit(1, tds.pid_file_name)
-
- # re-request config from config binding service
- # (either broker, or json file override)
+ # re-request config (from broker, or local json file
+ # if broker not present)
if not get_cbs_config():
- msg = "error (re)loading CBS config - FATAL ERROR, exiting"
+ msg = "Error (re)loading CBS config - FATAL ERROR, exiting"
stdout_logger(msg)
cleanup_and_exit(1, tds.pid_file_name)
else:
- current_runtime_config_file_name = tds.c_config['files.runtime_base_dir'] + \
+ current_runtime_config_file_name = tds.c_config['files']['runtime_base_dir'] + \
"/tmp/current_config.json"
-
- msg = "current config logged to : %s" % current_runtime_config_file_name
+ if int(_signum) != 0:
+ msg = "updated config logged to : %s" % current_runtime_config_file_name
+ else:
+ msg = "current config logged to : %s" % current_runtime_config_file_name
ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
with open(current_runtime_config_file_name, 'w') as outfile:
json.dump(tds.c_config, outfile)
- # if here, config re-read successfully
- return True
+ # reset http session based on latest config
+ tds.http_requ_session = reset_session_obj(tds.http_requ_session)
+
+ # FMDL: add with stormWatch
+ # reload sw participating entries, reset counter dictionary
+ # sw.interval_in_seconds, sw.participant_oid_dict = load_sw_participant_dict(tds.c_config['trap_config'])
+ # sw.counter_dict = init_counter_dict()
+
+ # if here, config re-read successfully
+ return True
# # # # # # # # # # # # #
# fx: log_all_arriving_traps
@@ -166,12 +165,12 @@ def load_all_configs(_signum, _frame):
def log_all_arriving_traps():
# roll logs as needed/defined in files.roll_frequency
- if tds.c_config['files.roll_frequency'] == "minute":
+ if tds.c_config['files']['roll_frequency'] == "minute":
curr_minute = datetime.datetime.now().minute
if curr_minute != tds.last_minute:
roll_all_logs()
tds.last_minute = curr_minute
- elif tds.c_config['files.roll_frequency'] == "hour":
+ elif tds.c_config['files']['roll_frequency'] == "hour":
curr_hour = datetime.datetime.now().hour
if curr_hour != tds.last_hour:
roll_all_logs()
@@ -183,7 +182,7 @@ def log_all_arriving_traps():
roll_all_logs()
tds.last_day = curr_day
- # now log latest arriving trap
+ # always log arriving trap
try:
# going for:
# 1520971776 Tue Mar 13 16:09:36 2018; 1520971776 2018-03-13 16:09:36 DCAE-COLLECTOR-UCSNMP 15209717760049 .1.3.6.1.4.1.2636.4.1.6 gfpmt5pcs10.oss.att.com 135.91.10.139 12.123.1.240 12.123.1.240 2 varbinds: [0] .1.3.6.1.2.1.1.3.0 {10} 1212058366 140 days, 6:49:43.66 [1] .1.3.6.1.6.3.1.1.4.1.0 {6} .1.3.6.1.4.1.2636.4.1.6 [2] .1.3.6.1.4.1.2636.3.1.15.1.1.2.4.0.0 {2} 2 [3] .1.3.6.1.4.1.2636.3.1.15.1.2.2.4.0.0 {2} 4 [4] .1.3.6.1.4.1.2636.3.1.15.1.3.2.4.0.0 {2} 0 [5] .1.3.6.1.4.1.2636.3.1.15.1.4.2.4.0.0 {2} 0 [6] .1.3.6.1.4.1.2636.3.1.15.1.5.2.4.0.0 {4} PEM 3 [7] .1.3.6.1.4.1.2636.3.1.15.1.6.2.4.0.0 {2} 7 [8] .1.3.6.1.4.1.2636.3.1.15.1.7.2.4.0.0 {2} 4 [9] .1.3.6.1.6.3.18.1.3.0 {7} 12.123.1.240
@@ -273,7 +272,7 @@ def post_dmaap():
k = 0
dmaap_pub_success = False
- while not dmaap_pub_success and k < (int(tds.c_config['publisher.http_retries'])):
+ while not dmaap_pub_success and k < (int(tds.c_config['publisher']['http_retries'])):
try:
if tds.c_config['streams_publishes']['sec_fault_unsecure']['aaf_username'] == "" or tds.c_config['streams_publishes']['sec_fault_unsecure']['aaf_username'] is None:
msg = "%d trap(s) : %s - attempt %d (unsecure)" % (
@@ -323,7 +322,7 @@ def post_dmaap():
k += 1
- if k < tds.c_config['publisher.http_retries']:
+ if k < tds.c_config['publisher']['http_retries']:
msg = "sleeping %.4f seconds and retrying" % (
tds.seconds_between_retries)
ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_DETAILED,
@@ -380,9 +379,40 @@ def snmp_engine_observer_cb(snmp_engine, execpoint, variables, cbCtx):
:Variables:
"""
+ # All sorts of goodies available:
+ # print('Execution point: %s' % execpoint)
+ # print('* transportDomain: %s' % '.'.join([str(x) for x in variables['transportDomain']]))
+ # print('* transportAddress: %s' % '@'.join([str(x) for x in variables['transportAddress']]))
+ # print('* securityModel: %s' % variables['securityModel'])
+ # print('* securityName: %s' % variables['securityName'])
+ # print('* securityLevel: %s' % variables['securityLevel'])
+ # print('* contextEngineId: %s' % variables['contextEngineId'].prettyPrint())
+ # print('* contextName: %s' % variables['contextName'].prettyPrint())
+ # print('* PDU: %s' % variables['pdu'].prettyPrint())
+ # V1 only:
+ # print('* enterprise: %s' % variables['pdu']['enterprise'].prettyPrint())
+ # V1 name (e.g. coldstart, warmstart):
+ # print('* generic: %s' % variables['pdu']['generic-trap'].prettyPrint())
+ # print('* generic: %d' % variables['pdu']['generic-trap'])
+ # print('* specific: %s' % variables['pdu']['specific-trap'].prettyPrint())
+ # print('* specific: %d' % variables['pdu']['specific-trap'])
+
# init dictionary on new trap
tds.trap_dict = {}
+ # FMDL.CHECK_WITH_DOWNSTREAM_CONSUMERS: get rid of round for millisecond val
+ # epoch_second = int(round(time.time()))
+ epoch_msecond = time.time()
+ epoch_second = int(round(epoch_msecond))
+ if epoch_second == tds.last_epoch_second:
+ tds.traps_in_epoch += 1
+ else:
+ tds.traps_in_epoch = 0
+ tds.last_epoch_second = epoch_second
+ traps_in_epoch_04d = format(tds.traps_in_epoch, '04d')
+ tds.trap_dict['epoch_serno'] = int(
+ (str(epoch_second) + str(traps_in_epoch_04d)))
+
# assign uuid to trap
tds.trap_dict["uuid"] = str(uuid_mod.uuid1())
@@ -413,7 +443,7 @@ def snmp_engine_observer_cb(snmp_engine, execpoint, variables, cbCtx):
tds.dns_cache_ip_to_name[ip_addr_str] = agent_fqdn
tds.dns_cache_ip_expires[ip_addr_str] = (
- time.time() + tds.c_config['cache.dns_cache_ttl_seconds'])
+ time.time() + tds.c_config['cache']['dns_cache_ttl_seconds'])
msg = "cache for %s (%s) updated - set to expire at %d" % \
(agent_fqdn, ip_addr_str, tds.dns_cache_ip_expires[ip_addr_str])
ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_DETAILED,
@@ -424,40 +454,35 @@ def snmp_engine_observer_cb(snmp_engine, execpoint, variables, cbCtx):
tds.trap_dict["community"] = ""
tds.trap_dict["community len"] = 0
- # FMDL.CHECK_WITH_DOWNSTREAM_CONSUMERS: get rid of round for millisecond val
- # epoch_second = int(round(time.time()))
- epoch_msecond = time.time()
- epoch_second = int(round(epoch_msecond))
- if epoch_second == tds.last_epoch_second:
- tds.traps_in_epoch += 1
- else:
- tds.traps_in_epoch = 0
- tds.last_epoch_second = epoch_second
- traps_in_epoch_04d = format(tds.traps_in_epoch, '04d')
- tds.trap_dict['epoch_serno'] = int(
- (str(epoch_second) + str(traps_in_epoch_04d)))
-
snmp_version = variables['securityModel']
if snmp_version == 1:
tds.trap_dict["protocol version"] = "v1"
+ enterprise = variables['pdu']['enterprise'].prettyPrint()
+ generic_trap = variables['pdu']['generic-trap']
+ specific_trap = variables['pdu']['specific-trap']
+ if generic_trap < 6:
+ tds.trap_dict["notify OID"] = str(enterprise) + "." + str(specific_trap)
+ else:
+ tds.trap_dict["notify OID"] = str(enterprise) + ".0." + str(specific_trap)
+ tds.trap_dict["notify OID len"] = (tds.trap_dict["notify OID"].count('.') + 1)
+ tds.trap_dict["sysUptime"] = variables['pdu']['time-stamp'].prettyPrint()
else:
if snmp_version == 2:
tds.trap_dict["protocol version"] = "v2c"
else:
if snmp_version == 3:
tds.trap_dict["protocol version"] = "v3"
+ tds.trap_dict["security level"] = str(variables['securityLevel'])
+ tds.trap_dict["context name"] = str(
+ variables['contextName'].prettyPrint())
+ tds.trap_dict["security name"] = str(variables['securityName'])
+ tds.trap_dict["security engine"] = str(
+ variables['contextEngineId'].prettyPrint())
else:
tds.trap_dict["protocol version"] = "unknown"
- if snmp_version == 3:
- tds.trap_dict["protocol version"] = "v3"
- tds.trap_dict["security level"] = str(variables['securityLevel'])
- tds.trap_dict["context name"] = str(
- variables['contextName'].prettyPrint())
- tds.trap_dict["security name"] = str(variables['securityName'])
- tds.trap_dict["security engine"] = str(
- variables['contextEngineId'].prettyPrint())
- tds.trap_dict['time received'] = epoch_msecond
+ # tds.trap_dict['time received'] = epoch_msecond
+ tds.trap_dict['time received'] = epoch_second
tds.trap_dict['trap category'] = (
tds.c_config['streams_publishes']['sec_fault_unsecure']['dmaap_info']['topic_url']).split('/')[-1]
@@ -486,7 +511,7 @@ def add_varbind_to_json(vb_idx, vb_oid, vb_type, vb_val):
_individual_vb_dict = {}
- if tds.trap_dict["protocol version"] == "v2c":
+ if tds.trap_dict["protocol version"] == "v2c" or tds.trap_dict["protocol version"] == "v3":
# if v2c and first 2 varbinds, special handling required - e.g. put
# in trap_dict, not vb_json_str
if vb_idx == 0:
@@ -537,10 +562,18 @@ def notif_receiver_cb(snmp_engine, stateReference, contextEngineId, contextName,
callback trap arrival
:Variables:
"""
-
msg = "processing varbinds for %s" % (tds.trap_dict["uuid"])
ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_DETAILED, tds.CODE_GENERAL, msg)
+ # help(snmp_engine)
+ # print(snmp_engine)
+ # help(varBinds)
+ # print(varBinds)
+ # help(cbCtx)
+ # print(cbCtx)
+ # for key, val in cbCtx:
+ # print(key, val)
+
# FMDL update reset location when batching publishes
vb_idx = 0
@@ -573,6 +606,9 @@ def notif_receiver_cb(snmp_engine, stateReference, contextEngineId, contextName,
msg = "trap %s : %s" % (tds.trap_dict["uuid"], curr_trap_json_str)
ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_DETAILED, tds.CODE_GENERAL, msg)
+ # always log arriving traps
+ log_all_arriving_traps()
+
# now have a complete json message for this trap in "curr_trap_json_str"
tds.traps_since_last_publish += 1
milliseconds_since_last_publish = (time.time() - tds.last_pub_time) * 1000
@@ -588,17 +624,14 @@ def notif_receiver_cb(snmp_engine, stateReference, contextEngineId, contextName,
', ' + tds.trap_dict["uuid"]
tds.all_traps_str = tds.all_traps_str + ', ' + curr_trap_json_str
- # always log arriving traps
- log_all_arriving_traps()
-
# publish to dmaap after last varbind is processed
- if tds.traps_since_last_publish >= tds.c_config['publisher.max_traps_between_publishes']:
+ if tds.traps_since_last_publish >= tds.c_config['publisher']['max_traps_between_publishes']:
msg = "num traps since last publish (%d) exceeds threshold (%d) - publish traps" % (
- tds.traps_since_last_publish, tds.c_config['publisher.max_traps_between_publishes'])
+ tds.traps_since_last_publish, tds.c_config['publisher']['max_traps_between_publishes'])
ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_DETAILED,
tds.CODE_GENERAL, msg)
post_dmaap()
- elif milliseconds_since_last_publish >= tds.c_config['publisher.max_milliseconds_between_publishes']:
+ elif milliseconds_since_last_publish >= tds.c_config['publisher']['max_milliseconds_between_publishes']:
msg = "num milliseconds since last publish (%.0f) exceeds threshold - publish traps" % milliseconds_since_last_publish
ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_DETAILED,
tds.CODE_GENERAL, msg)
@@ -633,13 +666,17 @@ if __name__ == "__main__":
# init vars
tds.init()
+ # FMDL: add with stormWatch
+ # init sw vars
+ # sw.init()
+
# Set initial startup hour for rolling logfile
tds.last_hour = datetime.datetime.now().hour
# get config binding service (CBS) values (either broker, or json file override)
load_all_configs(0, 0)
msg = "%s : %s version %s starting" % (
- prog_name, tds.c_config['snmptrap.title'], tds.c_config['snmptrap.version'])
+ prog_name, tds.c_config['snmptrapd']['title'], tds.c_config['snmptrapd']['version'])
stdout_logger(msg)
# open various ecomp logs
@@ -650,18 +687,21 @@ if __name__ == "__main__":
msg = "WARNING: '-v' argument present. All diagnostic messages will be logged. This can slow things down, use only when needed."
tds.minimum_severity_to_log = 0
stdout_logger(msg)
+ # use specific flags or 'all' for full debugging
+ help(debug.setLogger)
+ debug.setLogger(debug.Debug('dsp', 'msgproc'))
# name and open arriving trap log
- tds.arriving_traps_filename = tds.c_config['files.runtime_base_dir'] + "/" + \
- tds.c_config['files.log_dir'] + "/" + \
- (tds.c_config['files.arriving_traps_log'])
+ tds.arriving_traps_filename = tds.c_config['files']['runtime_base_dir'] + "/" + \
+ tds.c_config['files']['log_dir'] + "/" + \
+ (tds.c_config['files']['arriving_traps_log'])
tds.arriving_traps_fd = open_file(tds.arriving_traps_filename)
msg = ("arriving traps logged to: %s" % tds.arriving_traps_filename)
stdout_logger(msg)
ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
# name and open json trap log
- tds.json_traps_filename = tds.c_config['files.runtime_base_dir'] + "/" + tds.c_config['files.log_dir'] + "/" + "DMAAP_" + (
+ tds.json_traps_filename = tds.c_config['files']['runtime_base_dir'] + "/" + tds.c_config['files']['log_dir'] + "/" + "DMAAP_" + (
tds.c_config['streams_publishes']['sec_fault_unsecure']['dmaap_info']['topic_url'].split('/')[-1]) + ".json"
tds.json_traps_fd = open_file(tds.json_traps_filename)
msg = ("published traps logged to: %s" % tds.json_traps_filename)
@@ -672,8 +712,8 @@ if __name__ == "__main__":
signal.signal(signal.SIGUSR1, load_all_configs)
# save current PID for future/external reference
- tds.pid_file_name = tds.c_config['files.runtime_base_dir'] + \
- '/' + tds.c_config['files.pid_dir'] + '/' + prog_name + ".pid"
+ tds.pid_file_name = tds.c_config['files']['runtime_base_dir'] + \
+ '/' + tds.c_config['files']['pid_dir'] + '/' + prog_name + ".pid"
msg = "Runtime PID file: %s" % tds.pid_file_name
ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
rc = save_pid(tds.pid_file_name)
@@ -681,7 +721,7 @@ if __name__ == "__main__":
# Get the event loop for this thread
loop = asyncio.get_event_loop()
- # Create SNMP engine with autogenernated engineID pre-bound
+ # Create SNMP engine with autogenerated engineID pre-bound
# to socket transport dispatcher
snmp_engine = engine.SnmpEngine()
@@ -690,12 +730,17 @@ if __name__ == "__main__":
# # # # # # # # # # # #
# UDP over IPv4
- # FMDL: add check for presense of ipv4_interface prior to attempting add OR just put entire thing in try/except clause
try:
- ipv4_interface = tds.c_config['protocols.ipv4_interface']
- ipv4_port = tds.c_config['protocols.ipv4_port']
+ ipv4_interface = tds.c_config['protocols']['ipv4_interface']
+ ipv4_port = tds.c_config['protocols']['ipv4_port']
try:
+ # FIXME: this doesn't appear to throw an exception even if
+ # the userID is unable (perms) to bind to port
+ #
+ # We may need to open raw port using other
+ # means to confirm proper privileges (then
+ # close it and reopen w/ pysnmp api)
config.addTransport(
snmp_engine,
udp.domainName + (1,),
@@ -716,10 +761,9 @@ if __name__ == "__main__":
# UDP over IPv6
- # FMDL: add check for presense of ipv6_interface prior to attempting add OR just put entire thing in try/except clause
try:
- ipv6_interface = tds.c_config['protocols.ipv6_interface']
- ipv6_port = tds.c_config['protocols.ipv6_port']
+ ipv6_interface = tds.c_config['protocols']['ipv6_interface']
+ ipv6_port = tds.c_config['protocols']['ipv6_port']
try:
config.addTransport(
@@ -755,7 +799,12 @@ if __name__ == "__main__":
comm_string_rewrite_observer,
'rfc2576.processIncomingMsg:writable'
)
-
+
+ # # # # # # # # # # # #
+ # SNMPv3 setup
+ # # # # # # # # # # # #
+ config, snmp_engine=load_snmpv3_credentials(config, snmp_engine, tds.c_config)
+
# register snmp_engine_observer_cb for message arrival
snmp_engine.observer.registerObserver(
snmp_engine_observer_cb,
diff --git a/snmptrap/snmptrapd.sh b/snmptrap/snmptrapd.sh
index e8ef93e..57fd1b4 100644..100755
--- a/snmptrap/snmptrapd.sh
+++ b/snmptrap/snmptrapd.sh
@@ -21,18 +21,28 @@
# ECOMP is a trademark and service mark of AT&T Intellectual Property.
#
-# get to where we are supposed to be for startup
-cd /opt/app/snmptrap/bin
+# basics
+current_cmd=`basename $0`
+current_module=`echo $current_cmd | cut -d"." -f1`
+
+# FMDL:: need to pick up these values from json config, but it isn't
+# present at startup
+base_dir=/opt/app/snmptrap
+pid_file=${base_dir}/tmp/${current_module}.py.pid
+start_dir=${base_dir}/bin
# include path to 3.6+ version of python that has required dependencies included
export PATH=/opt/app/python-3.6.1/bin:$PATH
-# expand search for python modules to include ./mod in runtime dir
-export PYTHONPATH=./mod:./:$PYTHONPATH
-
# set location of SSL certificates
export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-bundle.crt
+# get to where we are supposed to be for startup
+cd /opt/app/snmptrap/bin
+
+# expand search for python modules to include ./mod in current/runtime dir
+export PYTHONPATH=./mod:./:$PYTHONPATH
+
# PYTHONUNBUFFERED:
# set PYTHONUNBUFFERED to a non-empty string to avoid output buffering;
# comment out for runtime environments/better performance!
@@ -42,14 +52,191 @@ export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-bundle.crt
#
export CBS_SIM_JSON=../etc/snmptrapd.json
-# want tracing? Use this:
-# python -m trace --trackcalls snmptrapd.py -v
+# # # # # # # # # #
+# log_msg - log messages to stdout in standard manner
+# # # # # # # # # #
+log_msg()
+{
+ msg=$*
+
+ printf "`date +%Y-%m-%dT%H:%M:%S,%N | cut -c1-23` ${msg}"
+}
+
+# # # # # # # # # #
+# Start the service
+# # # # # # # # # #
+start_service()
+{
+ # Hints for startup modifications:
+ # _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+ # standard startup? Use this:
+ cmd="python ./snmptrapd.py &"
+ # want tracing? Use this:
+ # "python -m trace --trackcalls snmptrapd.py &"
+ # unbuffered io for logs? Use this:
+ # "python -u snmptrapd.py &"
+
+ cd ${start_dir}
+
+ # check for process already running
+ if [ -r ${pid_file} ]
+ then
+ pid=$(cat ${pid_file})
+ if ps -p ${pid} > /dev/null
+ then
+ printf "${current_module} already running - PID ${pid}\n"
+ return 0
+ fi
+ fi
+
+ # FMDL:: do this in snmptrapd.py at startup
+ # roll log if present at startup
+ # if [ -f ${LOGFILE} ]
+ # then
+ # mv -f ${LOGFILE} ${LOGFILE}.`date +%h-%m-%Y_%H:%M:%S`
+ # fi
+
+ log_msg "Starting ${current_module}... "
+ eval ${cmd}
+ return_code=$?
+
+ if [ ${return_code} -eq 0 ]
+ then
+ log_msg "Started.\n"
+ else
+ log_msg "\nERROR! Unable to start ${current_module}. Check logs for details.\n"
+ fi
+
+ return ${return_code}
+
+}
+
+# # # # # # # # # #
+# Stop the service
+# # # # # # # # # #
+stop_service()
+{
+ if [ ! -r ${pid_file} ]
+ then
+ log_msg "PID file ${pid_file} does not exist or not readable - unable to stop specific instance of ${current_module}.\n"
+ log_msg "Diagnose further at command line as needed.\n"
+ return_code=1
+ else
+ pid=$(cat ${pid_file})
+ log_msg "Stopping ${current_module} PID ${pid}...\n"
+ kill ${pid}
+ if [ $? -ne 0 ]
+ then
+ log_msg "\nERROR while trying to terminate ${current_module} PID ${pid} (is it not running or owned by another userID?)"
+ log_msg "\nDiagnose further at command line as needed."
+ return_code=$?
+ if [ -w ${pid_file} ]
+ then
+ rm -f ${pid_file}
+ fi
+ else
+ log_msg "Stopped\n"
+ if [ -w ${pid_file} ]
+ then
+ rm -f ${pid_file}
+ fi
+ return_code=0
+ fi
+ fi
+
+ return ${return_code}
+}
+
+# # # # # # # # # # # # # # #
+# Check status of the service
+# # # # # # # # # # # # # # #
+status_service()
+{
+ if [ -r ${pid_file} ]
+ then
+ pid=$(cat ${pid_file})
+ pgrep -a python | grep ${current_module} | grep "^${pid}" > /dev/null
+ return_code=$?
+
+ if [ ${return_code} -eq 0 ]
+ then
+ log_msg "Status: ${current_module} running\n"
+ ps -p ${pid} -f | grep -v PID
+ return_code=0
+ else
+ log_msg "Status: ERROR! ${current_module} not running.\n"
+ return_code=1
+ fi
+ else
+ log_msg "PID file ${pid_file} does not exist or not readable - unable to check status of ${current_module}\n"
+ log_msg "Diagnose further at command line as needed.\n"
+ return 1
+ fi
+
+ return ${return_code}
+}
+
+# # # # # # # # # # # # # # # # #
+# Signal process to reload config
+# # # # # # # # # # # # # # # # #
+reload_cfg()
+{
+ if [ -r ${pid_file} ]
+ then
+ pid=$(cat ${pid_file})
+ ps -p ${pid} > /dev/null 2>&1
+ ret=$?
+ if [ ${ret} ]
+ then
+ log_msg "Signaling ${current_module} PID ${pid} to request/read updated configs...\n"
+ kill -USR1 ${pid}
+ return_code=$?
+ if [ ${return_code} -eq 0 ]
+ then
+ log_msg "...Signal complete.\n"
+ else
+ log_msg "\nERROR signaling ${current_module} - diagnose further at the command line.\n"
+ fi
+ else
+ log_msg "\nERROR: ${current_module} PID ${pid} does not appear to be running.\n"
+ return_code=1
+ fi
+ else
+ log_msg "\nERROR: ${current_module} pid_file ${pid_file} does not exist - unable to signal for config re-read.\n"
+ return_code=1
+ fi
-# want verbose logging? Use this:
-# python snmptrapd.py -v
+ return ${return_code}
+}
-# standard startup? Use this:
-# python snmptrapd.py
+# # # # # # # # # # # # #
+# M A I N
+# # # # # # # # # # # # #
-# unbuffered io for logs and verbose logging? Use this:
-python -u snmptrapd.py -v
+case "$1" in
+ "start")
+ start_service
+ exit $?
+ ;;
+ "stop")
+ stop_service
+ exit $?
+ ;;
+ "restart")
+ stop_service
+ sleep 1
+ start_service
+ exit $?
+ ;;
+ "status")
+ status_service
+ exit $?
+ ;;
+ "reloadCfg")
+ reload_cfg
+ exit $?
+ ;;
+ *)
+ printf "\nUsage: ${current_cmd} {start|stop|restart|status|rollLog|reloadCfg}\n"
+ exit 1
+ esac
diff --git a/spec/snmptrap-collector-component-spec.json b/spec/snmptrap-collector-component-spec.json
index b0436d4..e9f827e 100644
--- a/spec/snmptrap-collector-component-spec.json
+++ b/spec/snmptrap-collector-component-spec.json
@@ -1,7 +1,7 @@
{
"self": {
- "version": "1.3.0",
- "name": "snmptrap-collector",
+ "version": "1.4.0",
+ "name": "snmptrap-collector",
"description": "Collector for receiving SNMP traps and publishing to DMAAP/MR",
"component_type": "docker"
},
@@ -20,232 +20,242 @@
},
"services": {
"calls": [],
- "provides": [],
+ "provides": []
},
"parameters": [
{
- "name": "snmptrap.version",
- "value":"1.3.0",
- "description": "version number"
- },
- {
- "name": "snmptrap.title",
- "value":"ONAP SNMP Trap Receiver",
- "description": "title for logging"
- },
- {
- "name": "protocols.transport",
- "value":"udp",
- "description": "protocol used to transport trap (udp|tcp)"
- },
- {
- "name": "protocols.ipv4_interface",
- "value":"0.0.0.0",
- "description": "ipv4 address trap receiver should listen to (0.0.0.0 -> all)"
- },
- {
- "name": "protocols.ipv4_port",
- "value":162,
- "description": "port trap receiver should bind to for ipv4 traps"
- },
- {
- "name": "protocols.ipv6_interface",
- "value":"::1",
- "description": "ipv6 address trap receiver should listen to (::1 -> all)"
- },
- {
- "name": "protocols.ipv6_port",
- "value":162,
- "description": "port trap receiver should bind to for ipv6 traps"
- },
- {
- "name": "cache.dns_cache_ttl_seconds",
- "value":60,
- "description": "number of seconds snmptrapd will cache dns entry before re-loading it"
- },
- {
- "name": "publisher.http_timeout_milliseconds",
- "value":1500,
- "description":"milliseconds snmptrapd will wait for MR to respond to publish attempt",
- },
- {
- "name":"publisher.http_retries",
- "value":3,
- "description":"number of times snmptrapd will re-attempt MR publish before moving on",
- },
- {
- "name": "publisher.http_milliseconds_between_retries",
- "value":750,
- "description":"milliseconds snmptrapd will wait between MR publish re-attempts",
- },
- {
- "name": "publisher.http_primary_publisher",
- "value":"true",
- "description": "future use (resiliency)"
- },
- {
- "name": "publisher.http_peer_publisher",
- "value":"unavailable",
- "description": "future use (resiliency)"
- },
- {
- "name": "publisher.max_traps_between_publishes",
- "value":10,
- "description": "max number of traps snmptrapd will queue before publishing"
- },
- {
- "name": "publisher.max_milliseconds_between_publishes",
- "value":1000,
- "description": "max number of milliseconds snmptrapd will accumulate traps before publishing"
- },
- {
- "name": "files.runtime_base_dir",
- "value":"/tmp/opt/app/snmptrap",
- "description": "base dir of snmptrapd install"
- },
- {
- "name": "files.log_dir",
- "value":"logs",
- "description": "location from runtime_base_dir for logs"
- },
- {
- "name": "files.data_dir",
- "value":"data",
- "description": "location from runtime_base_dir for data"
- },
- {
- "name": "files.pid_dir",
- "value":"tmp",
- "description": "location from runtime_base_dir for pid_dir"
- },
- {
- "name": "files.arriving_traps_log",
- "value":"snmptrapd_arriving_traps.log",
- "description": "log of all arriving traps (published or not)"
- },
- {
- "name": "files.snmptrapd_diag",
- "value":"snmptrapd_prog_diag.log",
- "description": "future use"
- },
- {
- "name": "files.traps_stats_log",
- "value":"snmptrapd_stats.csv",
- "description": "future use"
- },
- {
- "name": "files.perm_status_file",
- "value":"snmptrapd_status.log",
- "description": "future use"
- },
- {
- "name": "files.eelf_base_dir",
- "value":"/tmp/opt/app/snmptrap/logs",
- "description": "directory that all EELF format logs will be written to"
- },
- {
- "name": "files.eelf_error",
- "value":"error.log",
- "description": "EELF error log"
- },
- {
- "name": "files.eelf_debug",
- "value":"debug.log",
- "description": "EELF debug log"
- },
- {
- "name": "files.eelf_audit",
- "value":"audit.log",
- "description": "EELF audit log"
- },
- {
- "name": "files.eelf_metrics",
- "value":"metrics.log",
- "description": "EELF metrics log"
- },
- {
- "name": "files.roll_frequency",
- "value":"hour",
- "description": "how often snmptrapd will roll logs to <logfilename>.timestamp, and start a new one"
- },
- {
- "name": "files.minimum_severity_to_log",
- "value":2,
- "description": "minimium severity to log in above EELF log files: SEV_DETAILED=1, SEV_INFO=2, SEV_WARN=3, SEV_CRIT=4, SEV_FATAL=5"
-
- },
- {
- "name": "trap_def.1.trap_oid",
- "value":".1.3.6.1.4.1.74.2.46.12.1.1",
- "description": "oid 1 of interest"
- },
- {
- "name": "trap_def.1.trap_category",
- "value":"DCAE-SNMP-TRAPS",
- "description": "topic to publish oid 1 to (future use)"
- },
- {
- "name": "trap_def.2.trap_oid",
- "value":"*",
- "description": "oid 1 of interest"
- },
- {
- "name": "trap_def.2.trap_category",
- "value":"DCAE-SNMP-TRAPS",
- "description": "topic to publish oid 1 to (future use)"
- },
- {
- "name": "stormwatch.1.stormwatch_oid",
- "value":".1.3.6.1.4.1.74.2.46.12.1.1",
- "description": "stormWatch candidate oid 1"
- },
- {
- "name": "stormwatch.1.low_water_rearm_per_minute",
- "value":"5",
- "description": "stormWatch candidate oid 1 low-water rearm value (future use)"
- },
- {
- "name": "stormwatch.1.high_water_arm_per_minute",
- "value":"100",
- "description": "stormWatch candidate oid 1 high-water storm activation value (future use)"
- },
- {
- "name": "stormwatch.2.stormwatch_oid",
- "value":".1.3.6.1.4.1.74.2.46.12.1.2",
- "description": "stormWatch candidate oid 2"
- },
- {
- "name": "stormwatch.2.low_water_rearm_per_minute",
- "value":"2",
- "description": "stormWatch candidate oid 2 low-water rearm value (future use)"
- },
- {
- "name": "stormwatch.2.high_water_arm_per_minute",
- "value":"200",
- "description": "stormWatch candidate oid 2 high-water storm activation value (future use)"
- },
- {
- "name": "stormwatch.3.stormwatch_oid",
- "value":".1.3.6.1.4.1.74.2.46.12.1.2",
- "description": "stormWatch candidate oid 3"
- },
- {
- "name": "stormwatch.3.low_water_rearm_per_minute",
- "value":"2",
- "description": "stormWatch candidate oid 3 low-water rearm value (future use)"
- },
- {
- "name": "stormwatch.3.high_water_arm_per_minute",
- "value":"200",
- "description": "stormWatch candidate oid 3 high-water storm activation value (future use)"
+ "name": "sw_interval_in_seconds",
+ "value": "60",
+ "description": "StormWatch sample interval",
+ "designer_editable" : false,
+ "policy_editable" : false,
+ "sourced_at_deployment" : false
+ },
+ {
+ "name": "StormWatchPolicy",
+ "description": "Configure storm watch control parameters via Policy",
+ "sourced_at_deployment": false,
+ "designer_editable": true,
+ "policy_editable": true,
+ "policy_group": "DCAE.Config_StormWatch",
+ "policy_schema": [
+ {
+ "name": "sw_trap_config",
+ "description": "List of storm watch control rules",
+ "type": "list",
+ "entry_schema": [
+ {
+ "name": "sw_notify_oid",
+ "description": "Stormwatch notify oid",
+ "type": "string",
+ "value": ""
+ },
+ {
+ "name": "sw_high_water_in_interval",
+ "description": "Onset number of traps in interval",
+ "type": "string",
+ "value": ""
+ },
+ {
+ "name": "sw_low_water_in_interval",
+ "description": "Clearing number of traps in interval",
+ "type": "string",
+ "value": ""
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "Protocols",
+ "description": "Protocol parameters",
+ "sourced_at_deployment": false,
+ "designer_editable": false,
+ "policy_editable": false,
+ "value": [
+ {
+ "name": "ipv4_interface",
+ "description": "ipv4 address trap receiver should listen to (0.0.0.0 -> all)",
+ "value": "0.0.0.0"
+ },
+ {
+ "name": "ipv4_port",
+ "description": "port trap receiver should bind to for ipv4 traps",
+ "value": "162"
+ },
+ {
+ "name": "ipv6_interface",
+ "description": "ipv6 address trap receiver should listen to (::FFFF:0:0 -> all)",
+ "value": "::FFFF:0:0"
+ },
+ {
+ "name": "ipv6_port",
+ "description": "port trap receiver should bind to for ipv6 traps",
+ "value": "162"
+ }
+ ]
+ },
+ {
+ "name": "Cache",
+ "description": "Cache parameters",
+ "sourced_at_deployment": false,
+ "designer_editable": false,
+ "policy_editable": false,
+ "value": [
+ {
+ "name": "dns_cache_ttl_seconds",
+ "description": "dns cache ttl in seconds",
+ "value": "60"
+ }
+ ]
+ },
+ {
+ "name": "Files",
+ "description": "Files parameters",
+ "sourced_at_deployment": false,
+ "designer_editable": false,
+ "policy_editable": false,
+ "value": [
+ {
+ "name": "arriving_traps_log",
+ "description": "log for all traps accepted by receiver",
+ "value": "snmptrapd_arriving_traps.log"
+ },
+ {
+ "name": "data_dir",
+ "description": "directory for published traps (json)",
+ "value": "data"
+ },
+ {
+ "name": "eelf_audit",
+ "description": "eelf audit log",
+ "value": "audit.log"
+ },
+ {
+ "name": "eelf_base_dir",
+ "description": "base directory for eelf logs",
+ "value": "/opt/app/snmptrap/logs"
+ },
+ {
+ "name": "eelf_debug",
+ "description": "eelf debug log",
+ "value": "debug.log"
+ },
+ {
+ "name": "eelf_error",
+ "description": "eelf error log",
+ "value": "error.log"
+ },
+ {
+ "name": "eelf_metrics",
+ "description": "eelf metrics log",
+ "value": "metrics.log"
+ },
+ {
+ "name": "log_dir",
+ "description": "logs directory",
+ "value": "logs"
+ },
+ {
+ "name": "minimum_severity_to_log",
+ "description": "minimun severity to log",
+ "value": "2"
+ },
+ {
+ "name": "perm_status_file",
+ "description": "permanent status log",
+ "value": "snmptrapd_status.log"
+ },
+ {
+ "name": "pid_dir",
+ "description": "directory for pid file",
+ "value": "tmp"
+ },
+ {
+ "name": "roll_frequency",
+ "description": "frequency of log file rolls",
+ "value": "hour"
+ },
+ {
+ "name": "runtime_base_dir",
+ "description": "base directory for runtime files",
+ "value": "hour"
+ },
+ {
+ "name": "snmptrapd_diag",
+ "description": "diagnostic program log",
+ "value": "snmptrapd_prog_diag.log"
+ },
+ {
+ "name": "traps_stats_log",
+ "description": "traps statistics log",
+ "value": "snmptrapd_stats.csv"
+ }
+ ]
+ },
+ {
+ "name": "Publisher",
+ "description": "Publisher parameters",
+ "sourced_at_deployment": false,
+ "designer_editable": false,
+ "policy_editable": false,
+ "value": [
+ {
+ "name": "http_milliseconds_between_retries",
+ "description": "milliseconds between publish retries",
+ "value": "750"
+ },
+ {
+ "name": "http_peer_publisher",
+ "description": "peer publisher",
+ "value": "unavailable"
+ },
+ {
+ "name": "http_primary_publisher",
+ "description": "primary publisher",
+ "value": "true"
+ },
+ {
+ "name": "http_retries",
+ "description": "retries for publish attempts",
+ "value": "3"
+ },
+ {
+ "name": "http_timeout_milliseconds",
+ "description": "milliseconds for publish timeout",
+ "value": "1500"
+ },
+ {
+ "name": "max_milliseconds_between_publishes",
+ "description": "max milliseconds between publishes",
+ "value": "10000"
+ },
+ {
+ "name": "max_traps_between_publishes",
+ "description": "max traps between publishes",
+ "value": "10"
+ }
+ ]
}
- ],
+ ],
"auxilary": {
+ "healthcheck": {
+ "type": "docker",
+ "interval": "300s",
+ "timeout": "120s",
+ "script": "/opt/app/snmptrap/bin/healthcheck.sh"
+ },
+ "reconfigs": {
+ "dti": "/opt/app/snmptrap/bin/snmptrapd.sh reloadCfg"
+ },
+ "ports": [
+ "6162:162"
+ ]
},
"artifacts": [
{
"type": "docker image",
- "uri": "nexus.onap.org:10001/snapshots/onap/org.onap.dcaegen2.collectors.snmptrap:1.3.0"
+ "uri": "nexus.onap.org:10001/snapshots/onap/org.onap.dcaegen2.collectors.snmptrap:1.4.0"
}
]
}
diff --git a/tests/snmp.setup.py b/tests/snmp.setup.py
index 5a12f10..ed565f2 100644
--- a/tests/snmp.setup.py
+++ b/tests/snmp.setup.py
@@ -62,7 +62,7 @@ reqs = [str(ir.req) for ir in install_reqs]
setup(
name = "dcaegen2-collectors-snmptrap",
description = "snmp trap receiver for ONAP docker image",
- version = "1.3.0",
+ version = "1.4.0",
packages=find_packages(),
author = "Dave L",
author_email = "dl3158@att.com",
diff --git a/tests/test_snmptrapd.py b/tests/test_snmptrapd.py
index d02b4f7..941c0ae 100644
--- a/tests/test_snmptrapd.py
+++ b/tests/test_snmptrapd.py
@@ -15,7 +15,7 @@ class test_snmptrapd(unittest.TestCase):
Test the save_pid mod
"""
- pytest_json_data = "{ \"snmptrap.version\": \"1.3.0\", \"snmptrap.title\": \"ONAP SNMP Trap Receiver\" , \"protocols.transport\": \"udp\", \"protocols.ipv4_interface\": \"0.0.0.0\", \"protocols.ipv4_port\": 6164, \"protocols.ipv6_interface\": \"::1\", \"protocols.ipv6_port\": 6164, \"cache.dns_cache_ttl_seconds\": 60, \"publisher.http_timeout_milliseconds\": 1500, \"publisher.http_retries\": 3, \"publisher.http_milliseconds_between_retries\": 750, \"publisher.http_primary_publisher\": \"true\", \"publisher.http_peer_publisher\": \"unavailable\", \"publisher.max_traps_between_publishes\": 10, \"publisher.max_milliseconds_between_publishes\": 10000, \"streams_publishes\": { \"sec_measurement\": { \"type\": \"message_router\", \"aaf_password\": \"aaf_password\", \"dmaap_info\": { \"location\": \"mtl5\", \"client_id\": \"111111\", \"client_role\": \"com.att.dcae.member\", \"topic_url\": null }, \"aaf_username\": \"aaf_username\" }, \"sec_fault_unsecure\": { \"type\": \"message_router\", \"aaf_password\": null, \"dmaap_info\": { \"location\": \"mtl5\", \"client_id\": null, \"client_role\": null, \"topic_url\": \"http://uebsb93kcdc.it.att.com:3904/events/ONAP-COLLECTOR-SNMPTRAP\" }, \"aaf_username\": null } }, \"files.runtime_base_dir\": \"/tmp/opt/app/snmptrap\", \"files.log_dir\": \"logs\", \"files.data_dir\": \"data\", \"files.pid_dir\": \"/tmp/opt/app/snmptrap/tmp\", \"files.arriving_traps_log\": \"snmptrapd_arriving_traps.log\", \"files.snmptrapd_diag\": \"snmptrapd_prog_diag.log\", \"files.traps_stats_log\": \"snmptrapd_stats.csv\", \"files.perm_status_file\": \"snmptrapd_status.log\", \"files.eelf_base_dir\": \"/tmp/opt/app/snmptrap/logs\", \"files.eelf_error\": \"error.log\", \"files.eelf_debug\": \"debug.log\", \"files.eelf_audit\": \"audit.log\", \"files.eelf_metrics\": \"metrics.log\", \"files.roll_frequency\": \"hour\", \"files.minimum_severity_to_log\": 2, \"trap_def.1.trap_oid\" : \".1.3.6.1.4.1.74.2.46.12.1.1\", \"trap_def.1.trap_category\": \"DCAE-SNMP-TRAPS\", \"trap_def.2.trap_oid\" : \"*\", \"trap_def.2.trap_category\": \"DCAE-SNMP-TRAPS\", \"stormwatch.1.stormwatch_oid\" : \".1.3.6.1.4.1.74.2.46.12.1.1\", \"stormwatch.1.low_water_rearm_per_minute\" : \"5\", \"stormwatch.1.high_water_arm_per_minute\" : \"100\", \"stormwatch.2.stormwatch_oid\" : \".1.3.6.1.4.1.74.2.46.12.1.2\", \"stormwatch.2.low_water_rearm_per_minute\" : \"2\", \"stormwatch.2.high_water_arm_per_minute\" : \"200\", \"stormwatch.3.stormwatch_oid\" : \".1.3.6.1.4.1.74.2.46.12.1.2\", \"stormwatch.3.low_water_rearm_per_minute\" : \"2\", \"stormwatch.3.high_water_arm_per_minute\" : \"200\" }"
+ pytest_json_data = "{ \"snmptrapd\": { \"version\": \"1.4.0\", \"title\": \"ONAP SNMP Trap Receiver\" }, \"protocols\": { \"transport\": \"udp\", \"ipv4_interface\": \"0.0.0.0\", \"ipv4_port\": 6162, \"ipv6_interface\": \"::1\", \"ipv6_port\": 6162 }, \"cache\": { \"dns_cache_ttl_seconds\": 60 }, \"publisher\": { \"http_timeout_milliseconds\": 1500, \"http_retries\": 3, \"http_milliseconds_between_retries\": 750, \"http_primary_publisher\": \"true\", \"http_peer_publisher\": \"unavailable\", \"max_traps_between_publishes\": 10, \"max_milliseconds_between_publishes\": 10000 }, \"streams_publishes\": { \"sec_fault_unsecure\": { \"type\": \"message_router\", \"aaf_password\": null, \"dmaap_info\": { \"location\": \"mtl5\", \"client_id\": null, \"client_role\": null, \"topic_url\": \"http://uebsb91kcdc.it.att.com:3904/events/ONAP-COLLECTOR-SNMPTRAP\" }, \"aaf_username\": null } }, \"files\": { \"runtime_base_dir\": \"/tmp/opt/app/snmptrap\", \"log_dir\": \"logs\", \"data_dir\": \"data\", \"pid_dir\": \"tmp\", \"arriving_traps_log\": \"snmptrapd_arriving_traps.log\", \"snmptrapd_diag\": \"snmptrapd_prog_diag.log\", \"traps_stats_log\": \"snmptrapd_stats.csv\", \"perm_status_file\": \"snmptrapd_status.log\", \"eelf_base_dir\": \"/tmp/opt/app/snmptrap/logs\", \"eelf_error\": \"error.log\", \"eelf_debug\": \"debug.log\", \"eelf_audit\": \"audit.log\", \"eelf_metrics\": \"metrics.log\", \"roll_frequency\": \"day\", \"minimum_severity_to_log\": 2 }, \"trap_config\": { \"sw_interval_in_seconds\": 60, \"notify_oids\": { \".1.3.6.1.4.1.9.0.1\": { \"sw_high_water_in_interval\": 102, \"sw_low_water_in_interval\": 7, \"category\": \"logonly\" }, \".1.3.6.1.4.1.9.0.2\": { \"sw_high_water_in_interval\": 101, \"sw_low_water_in_interval\": 7, \"category\": \"logonly\" }, \".1.3.6.1.4.1.9.0.3\": { \"sw_high_water_in_interval\": 102, \"sw_low_water_in_interval\": 7, \"category\": \"logonly\" }, \".1.3.6.1.4.1.9.0.4\": { \"sw_high_water_in_interval\": 10, \"sw_low_water_in_interval\": 3, \"category\": \"logonly\" } } }, \"snmpv3_config\": { \"usm_users\": [ { \"user\": \"usr-sha-aes256\", \"engineId\": \"8000000001020304\", \"usmHMACSHAAuth\": \"authkey1\", \"usmAesCfb256\": \"privkey1\" }, { \"user\": \"user1\", \"engineId\": \"8000000000000001\", \"usmHMACMD5Auth\": \"authkey1\", \"usmDESPriv\": \"privkey1\" }, { \"user\": \"user2\", \"engineId\": \"8000000000000002\", \"usmHMACSHAAuth\": \"authkey2\", \"usmAesCfb128\": \"privkey2\" }, { \"user\": \"user3\", \"engineId\": \"8000000000000003\", \"usmHMACSHAAuth\": \"authkey3\", \"usmAesCfb256\": \"privkey3\" } ] } }"
# create copy of snmptrapd.json for pytest
pytest_json_config = "/tmp/opt/app/snmptrap/etc/snmptrapd.json"
@@ -90,13 +90,13 @@ class test_snmptrapd(unittest.TestCase):
trapd_io.open_eelf_logs()
# open trap logs
- tds.arriving_traps_filename = tds.c_config['files.runtime_base_dir'] + "/" + \
- tds.c_config['files.log_dir'] + "/" + \
- (tds.c_config['files.arriving_traps_log'])
+ tds.arriving_traps_filename = tds.c_config['files']['runtime_base_dir'] + "/" + \
+ tds.c_config['files']['log_dir'] + "/" + \
+ (tds.c_config['files']['arriving_traps_log'])
tds.arriving_traps_fd = trapd_io.open_file(tds.arriving_traps_filename)
# name and open json trap log
- tds.json_traps_filename = tds.c_config['files.runtime_base_dir'] + "/" + tds.c_config['files.log_dir'] + "/" + "DMAAP_" + (
+ tds.json_traps_filename = tds.c_config['files']['runtime_base_dir'] + "/" + tds.c_config['files']['log_dir'] + "/" + "DMAAP_" + (
tds.c_config['streams_publishes']['sec_fault_unsecure']['dmaap_info']['topic_url'].split('/')[-1]) + ".json"
tds.json_traps_fd = trapd_io.open_file(tds.json_traps_filename)
msg = ("published traps logged to: %s" % tds.json_traps_filename)
@@ -123,43 +123,5 @@ class test_snmptrapd(unittest.TestCase):
# open eelf logs
trapd_io.open_eelf_logs()
- def test_post_dmaap(self):
- """
- Test publish of traps
- """
-
- # init vars
- tds.init()
-
- # request load of CBS data
- os.environ.update(CBS_SIM_JSON='/tmp/opt/app/snmptrap/etc/snmptrapd.json')
- result = trapd_get_cbs_config.get_cbs_config()
-
- # set last day to current
- tds.last_day = datetime.datetime.now().day
-
- # trap dict for publish
- tds.trap_dict = {'uuid': '06f6e91c-3236-11e8-9953-005056865aac', 'agent address': '1.2.3.4', 'agent name': 'test-agent.nodomain.com', 'cambria.partition': 'test-agent.nodomain.com', 'community': '', 'community len': 0, 'epoch_serno': 15222068260000, 'protocol version': 'v2c', 'time received': 1522206826.2938566, 'trap category': 'ONAP-COLLECTOR-SNMPTRAP', 'sysUptime': '218567736', 'notify OID': '1.3.6.1.4.1.9999.9.9.999', 'notify OID len': 10}
-
- # open eelf logs
- trapd_io.open_eelf_logs()
-
- # open trap logs
- tds.arriving_traps_filename = tds.c_config['files.runtime_base_dir'] + "/" + \
- tds.c_config['files.log_dir'] + "/" + \
- (tds.c_config['files.arriving_traps_log'])
- tds.arriving_traps_fd = trapd_io.open_file(tds.arriving_traps_filename)
-
- # name and open json trap log
- tds.json_traps_filename = tds.c_config['files.runtime_base_dir'] + "/" + tds.c_config['files.log_dir'] + "/" + "DMAAP_" + (
- tds.c_config['streams_publishes']['sec_fault_unsecure']['dmaap_info']['topic_url'].split('/')[-1]) + ".json"
- tds.json_traps_fd = trapd_io.open_file(tds.json_traps_filename)
- msg = ("published traps logged to: %s" % tds.json_traps_filename)
- trapd_io.stdout_logger(msg)
- trapd_io.ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
-
- result = snmptrapd.post_dmaap()
- print("result from post_dmaap -> %s" % result)
-
if __name__ == '__main__':
unittest.main()
diff --git a/tests/test_trapd_get_cbs_config.py b/tests/test_trapd_get_cbs_config.py
index 2b62724..accb986 100644
--- a/tests/test_trapd_get_cbs_config.py
+++ b/tests/test_trapd_get_cbs_config.py
@@ -13,7 +13,7 @@ class test_get_cbs_config(unittest.TestCase):
Test the trapd_get_cbs_config mod
"""
- pytest_json_data = "{ \"snmptrap.version\": \"1.3.0\", \"snmptrap.title\": \"ONAP SNMP Trap Receiver\" , \"protocols.transport\": \"udp\", \"protocols.ipv4_interface\": \"0.0.0.0\", \"protocols.ipv4_port\": 6164, \"protocols.ipv6_interface\": \"::1\", \"protocols.ipv6_port\": 6164, \"cache.dns_cache_ttl_seconds\": 60, \"publisher.http_timeout_milliseconds\": 1500, \"publisher.http_retries\": 3, \"publisher.http_milliseconds_between_retries\": 750, \"publisher.http_primary_publisher\": \"true\", \"publisher.http_peer_publisher\": \"unavailable\", \"publisher.max_traps_between_publishes\": 10, \"publisher.max_milliseconds_between_publishes\": 10000, \"streams_publishes\": { \"sec_measurement\": { \"type\": \"message_router\", \"aaf_password\": \"aaf_password\", \"dmaap_info\": { \"location\": \"mtl5\", \"client_id\": \"111111\", \"client_role\": \"com.att.dcae.member\", \"topic_url\": null }, \"aaf_username\": \"aaf_username\" }, \"sec_fault_unsecure\": { \"type\": \"message_router\", \"aaf_password\": null, \"dmaap_info\": { \"location\": \"mtl5\", \"client_id\": null, \"client_role\": null, \"topic_url\": \"http://uebsb93kcdc.it.att.com:3904/events/ONAP-COLLECTOR-SNMPTRAP\" }, \"aaf_username\": null } }, \"files.runtime_base_dir\": \"/tmp/opt/app/snmptrap\", \"files.log_dir\": \"logs\", \"files.data_dir\": \"data\", \"files.pid_dir\": \"/tmp/opt/app/snmptrap/tmp\", \"files.arriving_traps_log\": \"snmptrapd_arriving_traps.log\", \"files.snmptrapd_diag\": \"snmptrapd_prog_diag.log\", \"files.traps_stats_log\": \"snmptrapd_stats.csv\", \"files.perm_status_file\": \"snmptrapd_status.log\", \"files.eelf_base_dir\": \"/tmp/opt/app/snmptrap/logs\", \"files.eelf_error\": \"error.log\", \"files.eelf_debug\": \"debug.log\", \"files.eelf_audit\": \"audit.log\", \"files.eelf_metrics\": \"metrics.log\", \"files.roll_frequency\": \"hour\", \"files.minimum_severity_to_log\": 2, \"trap_def.1.trap_oid\" : \".1.3.6.1.4.1.74.2.46.12.1.1\", \"trap_def.1.trap_category\": \"DCAE-SNMP-TRAPS\", \"trap_def.2.trap_oid\" : \"*\", \"trap_def.2.trap_category\": \"DCAE-SNMP-TRAPS\", \"stormwatch.1.stormwatch_oid\" : \".1.3.6.1.4.1.74.2.46.12.1.1\", \"stormwatch.1.low_water_rearm_per_minute\" : \"5\", \"stormwatch.1.high_water_arm_per_minute\" : \"100\", \"stormwatch.2.stormwatch_oid\" : \".1.3.6.1.4.1.74.2.46.12.1.2\", \"stormwatch.2.low_water_rearm_per_minute\" : \"2\", \"stormwatch.2.high_water_arm_per_minute\" : \"200\", \"stormwatch.3.stormwatch_oid\" : \".1.3.6.1.4.1.74.2.46.12.1.2\", \"stormwatch.3.low_water_rearm_per_minute\" : \"2\", \"stormwatch.3.high_water_arm_per_minute\" : \"200\" }"
+ pytest_json_data = "{ \"snmptrapd\": { \"version\": \"1.4.0\", \"title\": \"ONAP SNMP Trap Receiver\" }, \"protocols\": { \"transport\": \"udp\", \"ipv4_interface\": \"0.0.0.0\", \"ipv4_port\": 6162, \"ipv6_interface\": \"::1\", \"ipv6_port\": 6162 }, \"cache\": { \"dns_cache_ttl_seconds\": 60 }, \"publisher\": { \"http_timeout_milliseconds\": 1500, \"http_retries\": 3, \"http_milliseconds_between_retries\": 750, \"http_primary_publisher\": \"true\", \"http_peer_publisher\": \"unavailable\", \"max_traps_between_publishes\": 10, \"max_milliseconds_between_publishes\": 10000 }, \"streams_publishes\": { \"sec_fault_unsecure\": { \"type\": \"message_router\", \"aaf_password\": null, \"dmaap_info\": { \"location\": \"mtl5\", \"client_id\": null, \"client_role\": null, \"topic_url\": \"http://localhost:3904/events/ONAP-COLLECTOR-SNMPTRAP\" }, \"aaf_username\": null } }, \"files\": { \"runtime_base_dir\": \"/tmp/opt/app/snmptrap\", \"log_dir\": \"logs\", \"data_dir\": \"data\", \"pid_dir\": \"tmp\", \"arriving_traps_log\": \"snmptrapd_arriving_traps.log\", \"snmptrapd_diag\": \"snmptrapd_prog_diag.log\", \"traps_stats_log\": \"snmptrapd_stats.csv\", \"perm_status_file\": \"snmptrapd_status.log\", \"eelf_base_dir\": \"/tmp/opt/app/snmptrap/logs\", \"eelf_error\": \"error.log\", \"eelf_debug\": \"debug.log\", \"eelf_audit\": \"audit.log\", \"eelf_metrics\": \"metrics.log\", \"roll_frequency\": \"day\", \"minimum_severity_to_log\": 2 }, \"trap_config\": { \"sw_interval_in_seconds\": 60, \"notify_oids\": { \".1.3.6.1.4.1.9.0.1\": { \"sw_high_water_in_interval\": 102, \"sw_low_water_in_interval\": 7, \"category\": \"logonly\" }, \".1.3.6.1.4.1.9.0.2\": { \"sw_high_water_in_interval\": 101, \"sw_low_water_in_interval\": 7, \"category\": \"logonly\" }, \".1.3.6.1.4.1.9.0.3\": { \"sw_high_water_in_interval\": 102, \"sw_low_water_in_interval\": 7, \"category\": \"logonly\" }, \".1.3.6.1.4.1.9.0.4\": { \"sw_high_water_in_interval\": 10, \"sw_low_water_in_interval\": 3, \"category\": \"logonly\" } } }, \"snmpv3_config\": { \"usm_users\": [ { \"user\": \"usr-sha-aes256\", \"engineId\": \"8000000001020304\", \"usmHMACSHAAuth\": \"authkey1\", \"usmAesCfb256\": \"privkey1\" }, { \"user\": \"user1\", \"engineId\": \"8000000000000001\", \"usmHMACMD5Auth\": \"authkey1\", \"usmDESPriv\": \"privkey1\" }, { \"user\": \"user2\", \"engineId\": \"8000000000000002\", \"usmHMACSHAAuth\": \"authkey2\", \"usmAesCfb128\": \"privkey2\" }, { \"user\": \"user3\", \"engineId\": \"8000000000000003\", \"usmHMACSHAAuth\": \"authkey3\", \"usmAesCfb256\": \"privkey3\" } ] } }"
# create copy of snmptrapd.json for pytest
pytest_json_config = "/tmp/opt/app/snmptrap/etc/snmptrapd.json"
diff --git a/tests/test_trapd_io.py b/tests/test_trapd_io.py
index cf45730..c791c7d 100644
--- a/tests/test_trapd_io.py
+++ b/tests/test_trapd_io.py
@@ -12,7 +12,7 @@ class test_trapd_io(unittest.TestCase):
"""
Test the save_pid mod
"""
- tds.c_config = json.loads("{ \"snmptrap.version\": \"1.3.0\", \"snmptrap.title\": \"ONAP SNMP Trap Receiver\" , \"protocols.transport\": \"udp\", \"protocols.ipv4_interface\": \"0.0.0.0\", \"protocols.ipv4_port\": 6164, \"protocols.ipv6_interface\": \"::1\", \"protocols.ipv6_port\": 6164, \"cache.dns_cache_ttl_seconds\": 60, \"publisher.http_timeout_milliseconds\": 1500, \"publisher.http_retries\": 3, \"publisher.http_milliseconds_between_retries\": 750, \"publisher.http_primary_publisher\": \"true\", \"publisher.http_peer_publisher\": \"unavailable\", \"publisher.max_traps_between_publishes\": 10, \"publisher.max_milliseconds_between_publishes\": 10000, \"streams_publishes\": { \"sec_measurement\": { \"type\": \"message_router\", \"aaf_password\": \"aaf_password\", \"dmaap_info\": { \"location\": \"mtl5\", \"client_id\": \"111111\", \"client_role\": \"com.att.dcae.member\", \"topic_url\": null }, \"aaf_username\": \"aaf_username\" }, \"sec_fault_unsecure\": { \"type\": \"message_router\", \"aaf_password\": null, \"dmaap_info\": { \"location\": \"mtl5\", \"client_id\": null, \"client_role\": null, \"topic_url\": \"http://uebsb93kcdc.it.att.com:3904/events/ONAP-COLLECTOR-SNMPTRAP\" }, \"aaf_username\": null } }, \"files.runtime_base_dir\": \"/tmp/opt/app/snmptrap\", \"files.log_dir\": \"logs\", \"files.data_dir\": \"data\", \"files.pid_dir\": \"/tmp/opt/app/snmptrap/tmp\", \"files.arriving_traps_log\": \"snmptrapd_arriving_traps.log\", \"files.snmptrapd_diag\": \"snmptrapd_prog_diag.log\", \"files.traps_stats_log\": \"snmptrapd_stats.csv\", \"files.perm_status_file\": \"snmptrapd_status.log\", \"files.eelf_base_dir\": \"/tmp/opt/app/snmptrap/logs\", \"files.eelf_error\": \"error.log\", \"files.eelf_debug\": \"debug.log\", \"files.eelf_audit\": \"audit.log\", \"files.eelf_metrics\": \"metrics.log\", \"files.roll_frequency\": \"hour\", \"files.minimum_severity_to_log\": 2, \"trap_def.1.trap_oid\" : \".1.3.6.1.4.1.74.2.46.12.1.1\", \"trap_def.1.trap_category\": \"DCAE-SNMP-TRAPS\", \"trap_def.2.trap_oid\" : \"*\", \"trap_def.2.trap_category\": \"DCAE-SNMP-TRAPS\", \"stormwatch.1.stormwatch_oid\" : \".1.3.6.1.4.1.74.2.46.12.1.1\", \"stormwatch.1.low_water_rearm_per_minute\" : \"5\", \"stormwatch.1.high_water_arm_per_minute\" : \"100\", \"stormwatch.2.stormwatch_oid\" : \".1.3.6.1.4.1.74.2.46.12.1.2\", \"stormwatch.2.low_water_rearm_per_minute\" : \"2\", \"stormwatch.2.high_water_arm_per_minute\" : \"200\", \"stormwatch.3.stormwatch_oid\" : \".1.3.6.1.4.1.74.2.46.12.1.2\", \"stormwatch.3.low_water_rearm_per_minute\" : \"2\", \"stormwatch.3.high_water_arm_per_minute\" : \"200\" }")
+ tds.c_config = json.loads("{ \"snmptrapd\": { \"version\": \"1.4.0\", \"title\": \"ONAP SNMP Trap Receiver\" }, \"protocols\": { \"transport\": \"udp\", \"ipv4_interface\": \"0.0.0.0\", \"ipv4_port\": 6162, \"ipv6_interface\": \"::1\", \"ipv6_port\": 6162 }, \"cache\": { \"dns_cache_ttl_seconds\": 60 }, \"publisher\": { \"http_timeout_milliseconds\": 1500, \"http_retries\": 3, \"http_milliseconds_between_retries\": 750, \"http_primary_publisher\": \"true\", \"http_peer_publisher\": \"unavailable\", \"max_traps_between_publishes\": 10, \"max_milliseconds_between_publishes\": 10000 }, \"streams_publishes\": { \"sec_fault_unsecure\": { \"type\": \"message_router\", \"aaf_password\": null, \"dmaap_info\": { \"location\": \"mtl5\", \"client_id\": null, \"client_role\": null, \"topic_url\": \"http://localhost:3904/events/ONAP-COLLECTOR-SNMPTRAP\" }, \"aaf_username\": null } }, \"files\": { \"runtime_base_dir\": \"/tmp/opt/app/snmptrap\", \"log_dir\": \"logs\", \"data_dir\": \"data\", \"pid_dir\": \"tmp\", \"arriving_traps_log\": \"snmptrapd_arriving_traps.log\", \"snmptrapd_diag\": \"snmptrapd_prog_diag.log\", \"traps_stats_log\": \"snmptrapd_stats.csv\", \"perm_status_file\": \"snmptrapd_status.log\", \"eelf_base_dir\": \"/tmp/opt/app/snmptrap/logs\", \"eelf_error\": \"error.log\", \"eelf_debug\": \"debug.log\", \"eelf_audit\": \"audit.log\", \"eelf_metrics\": \"metrics.log\", \"roll_frequency\": \"day\", \"minimum_severity_to_log\": 2 }, \"trap_config\": { \"sw_interval_in_seconds\": 60, \"notify_oids\": { \".1.3.6.1.4.1.9.0.1\": { \"sw_high_water_in_interval\": 102, \"sw_low_water_in_interval\": 7, \"category\": \"logonly\" }, \".1.3.6.1.4.1.9.0.2\": { \"sw_high_water_in_interval\": 101, \"sw_low_water_in_interval\": 7, \"category\": \"logonly\" }, \".1.3.6.1.4.1.9.0.3\": { \"sw_high_water_in_interval\": 102, \"sw_low_water_in_interval\": 7, \"category\": \"logonly\" }, \".1.3.6.1.4.1.9.0.4\": { \"sw_high_water_in_interval\": 10, \"sw_low_water_in_interval\": 3, \"category\": \"logonly\" } } }, \"snmpv3_config\": { \"usm_users\": [ { \"user\": \"usr-sha-aes256\", \"engineId\": \"8000000001020304\", \"usmHMACSHAAuth\": \"authkey1\", \"usmAesCfb256\": \"privkey1\" }, { \"user\": \"user1\", \"engineId\": \"8000000000000001\", \"usmHMACMD5Auth\": \"authkey1\", \"usmDESPriv\": \"privkey1\" }, { \"user\": \"user2\", \"engineId\": \"8000000000000002\", \"usmHMACSHAAuth\": \"authkey2\", \"usmAesCfb128\": \"privkey2\" }, { \"user\": \"user3\", \"engineId\": \"8000000000000003\", \"usmHMACSHAAuth\": \"authkey3\", \"usmAesCfb256\": \"privkey3\" } ] } }")
def test_open_eelf_error_file(self):