aboutsummaryrefslogtreecommitdiffstats
path: root/snmptrap/mod
diff options
context:
space:
mode:
Diffstat (limited to 'snmptrap/mod')
-rw-r--r--snmptrap/mod/__init__.py7
-rw-r--r--snmptrap/mod/trapd_exit.py7
-rw-r--r--snmptrap/mod/trapd_get_cbs_config.py36
-rw-r--r--snmptrap/mod/trapd_http_session.py12
-rw-r--r--snmptrap/mod/trapd_io.py31
-rw-r--r--snmptrap/mod/trapd_runtime_pid.py7
-rw-r--r--snmptrap/mod/trapd_settings.py23
-rw-r--r--snmptrap/mod/trapd_snmpv3.py112
-rw-r--r--snmptrap/mod/trapd_stats_settings.py44
-rw-r--r--snmptrap/mod/trapd_stormwatch.py513
-rw-r--r--snmptrap/mod/trapd_stormwatch_settings.py61
-rw-r--r--snmptrap/mod/trapd_vb_types.py42
12 files changed, 742 insertions, 153 deletions
diff --git a/snmptrap/mod/__init__.py b/snmptrap/mod/__init__.py
index 1875bf6..b0cfa95 100644
--- a/snmptrap/mod/__init__.py
+++ b/snmptrap/mod/__init__.py
@@ -1,5 +1,5 @@
-# ================================================================================
-# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+# ============LICENSE_START=======================================================
+# Copyright (c) 2018-2020 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.
@@ -13,9 +13,6 @@
# 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.
-
# empty __init__.py so that pytest can add correct path to coverage report, -- per pytest
# best practice guideline
diff --git a/snmptrap/mod/trapd_exit.py b/snmptrap/mod/trapd_exit.py
index ef7a2ae..6d1ea45 100644
--- a/snmptrap/mod/trapd_exit.py
+++ b/snmptrap/mod/trapd_exit.py
@@ -1,7 +1,5 @@
# ============LICENSE_START=======================================================
-# org.onap.dcae
-# ================================================================================
-# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2017-2020 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.
@@ -15,9 +13,6 @@
# 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.
-#
"""
trapc_exit_snmptrapd is responsible for removing any existing runtime PID
file, and exiting with the provided (param 1) exit code
diff --git a/snmptrap/mod/trapd_get_cbs_config.py b/snmptrap/mod/trapd_get_cbs_config.py
index 8bdff15..272aabe 100644
--- a/snmptrap/mod/trapd_get_cbs_config.py
+++ b/snmptrap/mod/trapd_get_cbs_config.py
@@ -1,7 +1,5 @@
# ============LICENSE_START=======================================================
-# org.onap.dcae
-# ================================================================================
-# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2018-2020 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.
@@ -15,9 +13,6 @@
# 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.
-#
"""
Look for CBS broker and return application config; if not present, look for
env variable that specifies JSON equiv of CBS config (typically used for
@@ -74,47 +69,52 @@ def get_cbs_config():
except Exception as e:
msg = "CBS_SIM_JSON not defined - FATAL ERROR, exiting"
stdout_logger(msg)
- cleanup_and_exit(1,None)
+ cleanup_and_exit(1, None)
if _cbs_sim_json_file == "None":
msg = "CBS_SIM_JSON not defined - FATAL ERROR, exiting"
stdout_logger(msg)
- cleanup_and_exit(1,None)
+ cleanup_and_exit(1, None)
else:
msg = ("ONAP controller override specified via CBS_SIM_JSON: %s" %
_cbs_sim_json_file)
stdout_logger(msg)
try:
tds.c_config = json.load(open(_cbs_sim_json_file))
- msg = ("%s loaded and parsed successfully" % _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"
stdout_logger(msg)
- cleanup_and_exit(1,None)
+ cleanup_and_exit(1, None)
+
+ # display consul config returned, regardless of source
+ msg = "cbs config: %s" % json.dumps(tds.c_config)
+ stdout_logger(msg)
# recalc timeout, set default if not present
try:
- tds.timeout_seconds = tds.c_config['publisher']['http_milliseconds_timeout'] / 1000.0
+ tds.timeout_seconds = float(tds.c_config['publisher']['http_milliseconds_timeout'] / 1000.0)
except Exception as e:
- tds.timeout_seconds = 1.5
+ tds.timeout_seconds = float(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 = float(tds.c_config['publisher']['http_milliseconds_between_retries'] / 1000.0)
except Exception as e:
- tds.seconds_between_retries = .750
+ tds.seconds_between_retries = float(.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 = int(tds.c_config['files']['minimum_severity_to_log'])
except Exception as e:
- tds.minimum_severity_to_log = 3
+ tds.minimum_severity_to_log = int(3)
try:
- tds.publisher_retries = tds.c_config['publisher']['http_retries']
+ tds.publisher_retries = int(tds.c_config['publisher']['http_retries'])
except Exception as e:
- tds.publisher_retries = 2
+ tds.publisher_retries = int(2)
return True
diff --git a/snmptrap/mod/trapd_http_session.py b/snmptrap/mod/trapd_http_session.py
index 3efca21..14abb21 100644
--- a/snmptrap/mod/trapd_http_session.py
+++ b/snmptrap/mod/trapd_http_session.py
@@ -1,7 +1,5 @@
# ============LICENSE_START=======================================================
-# org.onap.dcae
-# ================================================================================
-# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2017-2020 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.
@@ -15,9 +13,6 @@
# 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.
-#
"""
trapd_http_session establishes an http session for future use in publishing
messages to the dmaap cluster.
@@ -79,7 +74,6 @@ def close_session_obj(_loc_http_requ_session):
none
"""
-
# Close existing session if present.
if _loc_http_requ_session is not None:
try:
@@ -87,7 +81,8 @@ def close_session_obj(_loc_http_requ_session):
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)
+ ecomp_logger(tds.LOG_TYPE_ERROR, tds.SEV_FATAL,
+ tds.CODE_GENERAL, msg)
stdout_logger(msg)
cleanup_and_exit(1, tds.pid_file_name)
@@ -111,7 +106,6 @@ def reset_session_obj(_loc_http_requ_session):
none
"""
-
# close existing http_requ_session if present
ret = close_session_obj(_loc_http_requ_session)
diff --git a/snmptrap/mod/trapd_io.py b/snmptrap/mod/trapd_io.py
index d079cbe..991bcbd 100644
--- a/snmptrap/mod/trapd_io.py
+++ b/snmptrap/mod/trapd_io.py
@@ -1,7 +1,5 @@
-# ============LICENSE_START=======================================================)
-# org.onap.dcae
-# ================================================================================
-# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+# ============LICENSE_START=======================================================
+# Copyright (c) 2018-2020 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.
@@ -15,9 +13,6 @@
# 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.
-#
"""
"""
@@ -180,7 +175,7 @@ def roll_file(_loc_file_name):
_msg = ("ERROR: Unable to rename %s to %s"
% (_loc_file_name,
_loc_file_name_bak))
- ecomp_logger(tds.LOG_TYPE_ERROR, tds.SEV_CRIT,
+ ecomp_logger(tds.LOG_TYPE_ERROR, tds.SEV_ERROR,
tds.CODE_GENERAL, _msg)
return False
@@ -231,6 +226,7 @@ def close_file(_loc_fd, _loc_filename):
# is released for python via LOG-161
# # # # # # # # # # ## # # # # # # #
+
def ecomp_logger(_log_type, _sev, _error_code, _msg):
"""
Log to ecomp-style logfiles. Logs include:
@@ -309,10 +305,10 @@ def ecomp_logger(_log_type, _sev, _error_code, _msg):
# above were various attempts at setting time string found in other
# libs; instead, let's keep it real:
- t_out = datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S,%f")[:-3]
+ t_out = datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3]
calling_fx = inspect.stack()[1][3]
- # DLFM: this entire module is a hack to override concept of prog logging
+ # DLFM: this entire module is a xyz to override concept of prog logging
# written across multiple files (???), making diagnostics IMPOSSIBLE!
# Hoping to leverage ONAP logging libraries & standards when available
@@ -331,14 +327,19 @@ def ecomp_logger(_log_type, _sev, _error_code, _msg):
if _sev >= tds.minimum_severity_to_log:
# log to appropriate eelf log (different files ??)
if _log_type == tds.LOG_TYPE_ERROR:
- _out_rec = ('%s|%s|%s|%s|%s|%s|%s|%s|%s'
- % (calling_fx, "snmptrapd", unused, unused, unused, tds.SEV_TYPES[_sev], _error_code, unused, _msg))
+ # _out_rec = ('%s|%s|%s|%s|%s|%s|%s|%s|%s'
+ # _out_rec = ('%s|%s|%s|%s|%s|%s|%s|%s|%s'
+ # % (calling_fx, "snmptrapd", unused, unused, unused, tds.SEV_TYPES[_sev], _error_code, unused, _msg))
+ _out_rec = ('%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s'
+ % (unused, unused, calling_fx, unused, "snmptrapd", unused, unused, unused, unused, unused, unused, unused, tds.SEV_TYPES[_sev], unused, unused, unused, unused, unused, unused, unused, unused, unused, unused, unused, unused, unused, _msg))
try:
- tds.eelf_error_fd.write('%s|%s\n' % (t_out, str(_out_rec)))
+ tds.eelf_error_fd.write('%s|%s|%s\n' % (t_out, t_out, str(_out_rec)))
except Exception as e:
stdout_logger(str(_out_rec))
elif _log_type == tds.LOG_TYPE_AUDIT:
# log message in AUDIT format
+ # _out_rec = ('%s|%s|%s|%s|%s|%s|%s|%s|%s'
+ # % (calling_fx, "snmptrapd", unused, unused, unused, tds.SEV_TYPES[_sev], _error_code, unused, _msg))
_out_rec = ('%s|%s|%s|%s|%s|%s|%s|%s|%s'
% (calling_fx, "snmptrapd", unused, unused, unused, tds.SEV_TYPES[_sev], _error_code, unused, _msg))
try:
@@ -358,8 +359,8 @@ def ecomp_logger(_log_type, _sev, _error_code, _msg):
# DLFM: too much I/O !!!
# always write to debug; we need ONE logfile that has time-sequence full view !!!
# log message in DEBUG format
- _out_rec = ("%s|%s|%s|%s|%s|%s|%s|%s|%s"
- % (calling_fx, "snmptrapd", unused, unused, unused, tds.SEV_TYPES[_sev], _error_code, unused, _msg))
+ _out_rec = ("%s|%s|%s|%s|%s|%s|%s|%s|%s|%s"
+ % (unused, calling_fx, "snmptrapd", unused, unused, unused, tds.SEV_TYPES[_sev], _error_code, unused, _msg))
try:
tds.eelf_debug_fd.write('%s|%s\n' % (t_out, str(_out_rec)))
except Exception as e:
diff --git a/snmptrap/mod/trapd_runtime_pid.py b/snmptrap/mod/trapd_runtime_pid.py
index c6ef76e..74668f5 100644
--- a/snmptrap/mod/trapd_runtime_pid.py
+++ b/snmptrap/mod/trapd_runtime_pid.py
@@ -1,7 +1,5 @@
# ============LICENSE_START=======================================================
-# org.onap.dcae
-# ================================================================================
-# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2017-2020 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.
@@ -15,9 +13,6 @@
# 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.
-#
"""
trapd_runtime_pid maintains a 'PID file' (file that contains the
PID of currently running trap receiver)
diff --git a/snmptrap/mod/trapd_settings.py b/snmptrap/mod/trapd_settings.py
index 308a2f2..41dc18f 100644
--- a/snmptrap/mod/trapd_settings.py
+++ b/snmptrap/mod/trapd_settings.py
@@ -1,7 +1,5 @@
-# ============LICENSE_START=======================================================)
-# org.onap.dcae
-# ================================================================================
-# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+# ============LICENSE_START=======================================================
+# Copyright (c) 2018-2020 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.
@@ -15,9 +13,6 @@
# 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.
-#
"""
"""
@@ -81,10 +76,12 @@ def init():
first_varbind = True
global trap_dict
trap_dict = {}
- global all_traps_str
- all_traps_str = ""
+ global all_traps_json_str
+ all_traps_json_str = ""
global all_vb_json_str
all_vb_json_str = ""
+ global all_vb_str
+ all_vb_str = ""
global trap_uuids_in_buffer
trap_uuids_in_buffer = ""
# </trap and varbind dictionaries>
@@ -138,8 +135,6 @@ def init():
global sw_count_dict
sw_count_dict = {}
- global sw_interval_in_seconds
- sw_interval_in_seconds = 60
# </stormwatch >
# <logging types and severities>
@@ -161,14 +156,14 @@ def init():
global SEV_DETAILED
global SEV_INFO
global SEV_WARN
- global SEV_CRIT
+ global SEV_ERROR
global SEV_FATAL
- SEV_TYPES = ["none", "DETAILED", "INFO", "WARN", "CRITICAL", "FATAL"]
+ SEV_TYPES = ["none", "DETAILED", "INFO", "WARN", "ERROR", "FATAL"]
SEV_NONE = 0
SEV_DETAILED = 1
SEV_INFO = 2
SEV_WARN = 3
- SEV_CRIT = 4
+ SEV_ERROR = 4
SEV_FATAL = 5
global CODE_GENERAL
diff --git a/snmptrap/mod/trapd_snmpv3.py b/snmptrap/mod/trapd_snmpv3.py
index 5c0382b..b421ae1 100644
--- a/snmptrap/mod/trapd_snmpv3.py
+++ b/snmptrap/mod/trapd_snmpv3.py
@@ -1,7 +1,5 @@
# ============LICENSE_START=======================================================
-# org.onap.dcae
-# ================================================================================
-# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2018-2020 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.
@@ -15,9 +13,6 @@
# 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
@@ -52,9 +47,9 @@ prog_name = os.path.basename(__file__)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-def load_snmpv3_credentials (_py_config, _snmp_engine, _cbs_config):
+def load_snmpv3_credentials(_py_config, _snmp_engine, _cbs_config):
"""
- Add V3 credentials from CBS config to receiver config
+ Add V3 credentials from CBS config to receiver config
so traps will be recieved from specified engines/users
:Parameters:
_config: snmp entity config
@@ -63,7 +58,7 @@ def load_snmpv3_credentials (_py_config, _snmp_engine, _cbs_config):
# add V3 credentials from CBS json structure to running config
try:
- v3_users=_cbs_config["snmpv3_config"]["usm_users"]
+ 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)
@@ -73,121 +68,126 @@ def load_snmpv3_credentials (_py_config, _snmp_engine, _cbs_config):
# engineId
try:
- ctx_engine_id=v3_user['engineId']
+ ctx_engine_id = v3_user['engineId']
except Exception as e:
- ctx_engine_id=None
+ ctx_engine_id = None
# user
try:
- userName=v3_user['user']
+ userName = v3_user['user']
except Exception as e:
- userName=None
+ userName = None
# authorization
# find options at -> site-packages/pysnmp/entity/config.py
- # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# print("Checking auth for %s" % (userName))
# usmHMACMD5AuthProtocol
try:
- authKey=v3_user['usmHMACMD5AuthProtocol']
- authProtocol=config.usmHMACMD5AuthProtocol
+ authKey = v3_user['usmHMACMD5AuthProtocol']
+ authProtocol = config.usmHMACMD5AuthProtocol
except Exception as e:
try:
- authKey=v3_user['usmHMACSHAAuthProtocol']
- authProtocol=config.usmHMACSHAAuthProtocol
+ authKey = v3_user['usmHMACSHAAuthProtocol']
+ authProtocol = config.usmHMACSHAAuthProtocol
except Exception as e:
try:
- authKey=v3_user['usmHMAC128SHA224AuthProtocol']
- authProtocol=config.usmHMAC128SHA224AuthProtocol
+ authKey = v3_user['usmHMAC128SHA224AuthProtocol']
+ authProtocol = config.usmHMAC128SHA224AuthProtocol
except Exception as e:
try:
- authKey=v3_user['usmHMAC192SHA256AuthProtocol']
- authProtocol=config.usmHMAC192SHA256AuthProtocol
+ authKey = v3_user['usmHMAC192SHA256AuthProtocol']
+ authProtocol = config.usmHMAC192SHA256AuthProtocol
except Exception as e:
try:
- authKey=v3_user['usmHMAC256SHA384AuthProtocol']
- authProtocol=config.usmHMAC256SHA384AuthProtocol
+ authKey = v3_user['usmHMAC256SHA384AuthProtocol']
+ authProtocol = config.usmHMAC256SHA384AuthProtocol
except Exception as e:
try:
- authKey=v3_user['usmHMAC384SHA512AuthProtocol']
- authProtocol=config.usmHMAC384SHA512AuthProtocol
+ authKey = v3_user['usmHMAC384SHA512AuthProtocol']
+ authProtocol = config.usmHMAC384SHA512AuthProtocol
except Exception as e:
try:
- authKey=v3_user['usmNoAuthProtocol']
- authProtocol=config.usmNoAuthProtocol
+ authKey = v3_user['usmNoAuthProtocol']
+ 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)
+ 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)
# privacy
# find options at -> site-packages/pysnmp/entity/config.py
- # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# print("Checking priv for %s" % (userName))
# usm3DESEDEPriv
try:
- privKey=v3_user['usm3DESEDEPrivProtocol']
- privProtocol=config.usm3DESEDEPrivProtocol
+ privKey = v3_user['usm3DESEDEPrivProtocol']
+ privProtocol = config.usm3DESEDEPrivProtocol
except Exception as e:
# usmAesCfb128Protocol
try:
- privKey=v3_user['usmAesCfb128Protocol']
- privProtocol=config.usmAesCfb128Protocol
+ privKey = v3_user['usmAesCfb128Protocol']
+ privProtocol = config.usmAesCfb128Protocol
except Exception as e:
# usmAesCfb192Protocol
try:
- privKey=v3_user['usmAesCfb192Protocol']
- privProtocol=config.usmAesCfb192Protocol
+ privKey = v3_user['usmAesCfb192Protocol']
+ privProtocol = config.usmAesCfb192Protocol
except Exception as e:
# usmAesBlumenthalCfb192Protocol
try:
- privKey=v3_user['usmAesBlumenthalCfb192Protocol']
- privProtocol=config.usmAesBlumenthalCfb192Protocol
+ privKey = v3_user['usmAesBlumenthalCfb192Protocol']
+ privProtocol = config.usmAesBlumenthalCfb192Protocol
except Exception as e:
# usmAesCfb256Protocol
try:
- privKey=v3_user['usmAesCfb256Protocol']
- privProtocol=config.usmAesCfb256Protocol
+ privKey = v3_user['usmAesCfb256Protocol']
+ privProtocol = config.usmAesCfb256Protocol
except Exception as e:
# usmAesBlumenthalCfb256Protocol
try:
- privKey=v3_user['usmAesBlumenthalCfb256Protocol']
- privProtocol=config.usmAesBlumenthalCfb256Protocol
+ privKey = v3_user['usmAesBlumenthalCfb256Protocol']
+ privProtocol = config.usmAesBlumenthalCfb256Protocol
except Exception as e:
# usmDESPrivProtocol
try:
- privKey=v3_user['usmDESPrivProtocol']
- privProtocol=config.usmDESPrivProtocol
+ privKey = v3_user['usmDESPrivProtocol']
+ privProtocol = config.usmDESPrivProtocol
except Exception as e:
# usmNoPrivProtocol
try:
- privKey=v3_user['usmNoPrivProtocol']
- privProtocol=config.usmNoPrivProtocol
+ privKey = v3_user['usmNoPrivProtocol']
+ 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
+ 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))
+ 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 ->
+ # 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:
+ if ctx_engine_id is not None:
config.addV3User(
_snmp_engine, userName,
authProtocol, authKey,
diff --git a/snmptrap/mod/trapd_stats_settings.py b/snmptrap/mod/trapd_stats_settings.py
new file mode 100644
index 0000000..df4da0e
--- /dev/null
+++ b/snmptrap/mod/trapd_stats_settings.py
@@ -0,0 +1,44 @@
+# ============LICENSE_START=======================================================
+# Copyright (c) 2020 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=========================================================
+"""
+"""
+
+__docformat__ = 'restructuredtext'
+
+
+def init():
+
+ # <stats>
+ #
+ # oid_counter_dict
+ # key [<notify oid>] -> count
+ #
+ # agent_counter_dict
+ # key [<agent>] -> count
+ #
+ global oid_counter_dict
+ oid_counter_dict = {}
+
+ global agent_counter_dict
+ agent_counter_dict = {}
+
+ global total_notifications
+ total_notifications = 0
+
+ global metric_log_notification_threshold_pct
+ metric_log_notification_threshold_pct = 25
+
+ # </stats>
diff --git a/snmptrap/mod/trapd_stormwatch.py b/snmptrap/mod/trapd_stormwatch.py
new file mode 100644
index 0000000..623fe39
--- /dev/null
+++ b/snmptrap/mod/trapd_stormwatch.py
@@ -0,0 +1,513 @@
+# ============LICENSE_START=======================================================
+# Copyright (c) 2020 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=========================================================
+"""
+trapd_stormwatch makes the decision on whether an
+arriving SNMP trap is exceeding a pre-configured
+threshold (storm), and if so it will return "False"
+so the trap can be logged and immediately discarded
+"""
+
+__docformat__ = 'restructuredtext'
+
+import sys
+import os
+import string
+import time
+
+from trapd_io import stdout_logger, ecomp_logger
+import trapd_settings as tds
+import trapd_stats_settings as stats
+import trapd_stormwatch_settings as sws
+from trapd_exit import cleanup_and_exit
+
+prog_name = os.path.basename(__file__)
+
+
+def sw_init():
+
+ # <Storm Watch>
+ #
+ # sw_storm_counter_dict
+ # key [<ip address>.<notify oid>] -> count
+ #
+ # sw_storm_active_dict
+ # key [<ip address>.<notify oid>] -> True (or False, but no key present
+ # means False)
+ #
+ # sw_config_oid_dict
+ # key [<notify oid>] -> "true" (key presence means it participates)
+ #
+ # sw_config_low_water_in_interval_dict
+ # key [<notify oid>] -> <int> value that stormActive turns False
+ #
+ # sw_config_high_water_in_interval_dict
+ # key [<notify oid>] -> <int> value that stormActive turns True
+ #
+ sws.sw_counter_dict = {}
+ sws.sw_storm_active_dict = {}
+ sws.sw_config_oid_dict = {}
+ sws.sw_config_low_water_in_interval_dict = {}
+ sws.sw_config_high_water_in_interval_dict = {}
+ sws.sw_interval_in_seconds = 60
+
+
+# # # # # # # # # # # # #
+# fx: sw_storm_active
+# - check if storm is active for agent/oid
+# - returns True if yes, False if no
+# # # # # # # # # # # # #
+def sw_clear_dicts():
+ """
+ Clear all storm watch dictionaries
+ :Parameters:
+ :Exceptions:
+ none
+ :Keywords:
+ stormwatch count threshold
+ :Variables:
+ """
+ try:
+ stats.oid_counter_dict.clear()
+ stats.agent_counter_dict.clear()
+ sws.sw_storm_active_dict.clear()
+ sws.sw_storm_counter_dict.clear()
+ sws.sw_config_oid_dict.clear()
+ sws.sw_config_low_water_in_interval_dict.clear()
+ sws.sw_config_high_water_in_interval_dict.clear()
+ sws.sw_config_category.clear()
+ return True
+ except Exception as e:
+ msg = "unable to reset stormwatch dictionaries - results will be indeterminate: %s" % (
+ e)
+ ecomp_logger(tds.LOG_TYPE_ERROR, tds.SEV_WARN, tds.CODE_GENERAL, msg)
+ return False
+
+# # # # # # # # # # # # #
+# fx: sw_load_trap_config
+# - load trap configurations from CBS response
+# # # # # # # # # # # # #
+
+
+def sw_load_trap_config(_config):
+ """
+ Load trap configs into dictionary
+ :Parameters:
+ _config: trapd_config from CBS
+ :Exceptions:
+ """
+
+ # clear any dicts present from previous invocations
+ try:
+ sws.sw_storm_active_dict
+ ret = sw_clear_dicts()
+ msg = ("reset existing sws dictionaries to empty")
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
+ except NameError:
+ msg = ("sws dictionaries not present - initializing")
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
+ ret = sw_init()
+
+ # set last storm analysis to now
+ sws.sw_last_stormwatch_dict_analysis = int(time.time())
+
+ # get metric % threshold for logging trap count by-agent to metric log
+ try:
+ stats.metric_log_notification_threshold_pct = int(
+ _config["trap_config"]["metric_log_notification_threshold_pct"])
+ msg = ("metric_log_notification_threshold_pct value: %d" %
+ stats.metric_log_notification_threshold_pct)
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
+ except Exception as e:
+ msg = (
+ "metric_log_notification_threshold_pct not present in config - default to 25")
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_WARN, tds.CODE_GENERAL, msg)
+ stats.metric_log_notification_threshold_pct = 25
+
+ # get stormwatch interval; default to 60 seconds
+ try:
+ sws.sw_interval_in_seconds = int(
+ _config["trap_config"]["sw_interval_in_seconds"])
+ msg = ("sw_interval_in_seconds value: %d" % sws.sw_interval_in_seconds)
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
+ except Exception as e:
+ msg = ("sw_interval_in_seconds not present in config - default to 60 seconds")
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_WARN, tds.CODE_GENERAL, msg)
+ sws.sw_interval_in_seconds = 60
+
+ # add trap configs from CBS json structure to running config
+ try:
+ notify_oids = _config["trap_config"]["notify_oids"]
+ except Exception as e:
+ msg = ("no trap_config or notify_oids defined")
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_WARN, tds.CODE_GENERAL, msg)
+ return False
+
+ trap_block_counter = 0
+ for trap_block in notify_oids:
+ # oid
+ try:
+ _oid = trap_block['oid']
+ except Exception as e:
+ msg = (
+ "missing oid value in notify_oids - oid section of CBS config - using empty value, disregard entry")
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_WARN,
+ tds.CODE_GENERAL, msg)
+ _oid = None
+
+ # sw_high_water_in_interval
+ try:
+ _sw_high_water_in_interval = int(
+ trap_block['sw_high_water_in_interval'])
+ except Exception as e:
+ msg = (
+ "missing sw_high_water_in_interval value in notify_oids - oid section of CBS config - using empty value")
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_WARN,
+ tds.CODE_GENERAL, msg)
+ _sw_high_water_in_interval = None
+
+ # sw_low_water_in_interval
+ try:
+ _sw_low_water_in_interval = int(
+ trap_block['sw_low_water_in_interval'])
+ except Exception as e:
+ msg = (
+ "missing sw_low_water_in_interval value in notify_oids - oid section of CBS config - using empty value")
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_WARN,
+ tds.CODE_GENERAL, msg)
+ _sw_low_water_in_interval = None
+
+ # category
+ try:
+ _category = trap_block['category']
+ except Exception as e:
+ msg = (
+ "missing category value in notify_oids - oid section of CBS config - using empty value")
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_WARN,
+ tds.CODE_GENERAL, msg)
+ _category = None
+
+ if (_oid is not None and _category is not None and
+ _sw_low_water_in_interval is not None and _sw_high_water_in_interval is not None and
+ _sw_low_water_in_interval < _sw_high_water_in_interval):
+ # FMDL: Do we actually need sw_config_oid_dict?
+ msg = ("oid: %s sw_high_water_in_interval: %d sw_low_water_in_interval: %d category: %s" % (
+ _oid, _sw_high_water_in_interval, _sw_low_water_in_interval, _category))
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO,
+ tds.CODE_GENERAL, msg)
+ sws.sw_config_oid_dict[_oid] = True
+ sws.sw_config_low_water_in_interval_dict[_oid] = _sw_low_water_in_interval
+ sws.sw_config_high_water_in_interval_dict[_oid] = _sw_high_water_in_interval
+ sws.sw_config_category[_oid] = _category
+ trap_block_counter += 1
+ else:
+ msg = ("Missing or incorrect value for stormwatch config entry %d: skipping: %s" % (
+ trap_block_counter, trap_block))
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO,
+ tds.CODE_GENERAL, msg)
+
+
+ return trap_block_counter
+
+
+# # # # # # # # # # # # #
+# fx: sw_log_metrics
+# - log stats for any count in interval that is > sw_metric_log_notification_threshold_pct % of total arriving traps
+# # # # # # # # # # # # #
+def sw_log_metrics():
+ """
+ Log counts for agents that exceed sw_metric_log_notification_threshold_pct % of
+ total traps that arrived in interval
+ :Parameters:
+ :Exceptions:
+ none
+ :Keywords:
+ stormwatch metrics
+ :Variables:
+ """
+
+ msg = "total notifications: %d, interval in seconds: %d" % (
+ stats.total_notifications, sws.sw_interval_in_seconds)
+ ecomp_logger(tds.LOG_TYPE_METRICS, tds.SEV_INFO, tds.CODE_GENERAL, msg)
+
+ # print metrics for total traps and traps-per-second avg
+ # during sample interval
+ avg_traps_per_second = stats.total_notifications / 60
+ msg = "total traps: %d, interval in seconds: %d, average traps-per-second: %d" % (
+ stats.total_notifications, sws.sw_interval_in_seconds, avg_traps_per_second)
+ ecomp_logger(tds.LOG_TYPE_METRICS, tds.SEV_WARN,
+ tds.CODE_GENERAL, msg)
+
+ # print metrics for any agent that represents more than stats.metric_log_notification_threshold_pct
+ # during sample interval
+ for k in stats.agent_counter_dict:
+ c = stats.agent_counter_dict[k]
+ p = c / stats.total_notifications * 100
+ if p > stats.metric_log_notification_threshold_pct:
+ msg = "agent: %s, notifications: %d, interval in seconds: %d, percent of total traps: %d" % (
+ k, c, sws.sw_interval_in_seconds, p)
+ ecomp_logger(tds.LOG_TYPE_METRICS, tds.SEV_WARN,
+ tds.CODE_GENERAL, msg)
+
+# # # # # # # # # # # # #
+# fx: stats_increment_counters
+# - increment dictionary counters that are accumulating
+# - total traps by OID and agent for each sample interval
+# # # # # # # # # # # # #
+
+
+def stats_increment_counters(_loc_agent, _loc_oid):
+ """
+ update counters tracking traps-per-interval by
+ OID and agent
+ :Parameters:
+ _loc_agent
+ agent address from trap PDU
+ _loc_oid
+ notify OID from trap PDU
+ :Exceptions:
+ none
+ :Keywords:
+ stormwatch stats metrics
+ :Variables:
+ """
+ # increment oid occurances in window
+ msg = "increment metric counters for %s %s" % (_loc_agent, _loc_oid)
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
+ try:
+ stats.total_notifications += 1
+ except Exception as e:
+ stats.total_notifications = 1
+
+ try:
+ stats.oid_counter_dict[_loc_oid] += 1
+ except Exception as e:
+ stats.oid_counter_dict[_loc_oid] = 1
+
+ # increment agent occurances in window
+ try:
+ stats.agent_counter_dict[_loc_agent] += 1
+ except Exception as e:
+ stats.agent_counter_dict[_loc_agent] = 1
+
+
+# # # # # # # # # # # # #
+# fx: sw_storm_active
+# - check if storm is active for agent/oid
+# - returns True if yes, False if no
+# # # # # # # # # # # # #
+def sw_storm_active(_loc_agent, _loc_oid):
+ """
+ Check if this event is currently in an
+ active storm state.
+ :Parameters:
+ _loc_agent
+ agent address from trap PDU
+ _loc_oid
+ notify OID from trap PDU
+ :Exceptions:
+ none
+ :Keywords:
+ stormwatch count threshold
+ :Variables:
+ """
+
+ # we have to come here for every arriving trap, so increment
+ # trap counter dictionaries while we are here
+ stats_increment_counters(_loc_agent, _loc_oid)
+
+ # if we are at or above stormwatch interval, re-eval and re-set
+ elapsed_time = int(time.time()) - sws.sw_last_stormwatch_dict_analysis
+ if elapsed_time >= sws.sw_interval_in_seconds:
+ msg = "%d seconds has elapsed since stormwatch dictionary eval (%d second threshold) - check and reset counters " % (
+ elapsed_time, sws.sw_interval_in_seconds)
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
+ sw_log_metrics()
+ sw_reset_counter_dict()
+
+ # Note: If there's a sw_config_high_water_in_interval config value present
+ # that means it's participating in stormwatch, otherwise bail out
+ try:
+ _high_water_val = sws.sw_config_high_water_in_interval_dict[_loc_oid]
+ msg = "%s present in stormwatch config - high water value: %d" % (
+ _loc_oid, _high_water_val)
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
+ except Exception as e:
+ return False
+
+ # build stormwatch dict key by appending agent IP and trap oid
+ _dict_key = _loc_agent + " " + _loc_oid
+
+ # increment traps encountered for agent/oid
+ sw_increment_counter(_dict_key)
+
+ # first check if storm is active for _dict_key (early bail-out if so)
+ msg = "check if stormWatch is active for %s" % (_dict_key)
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
+ if sws.sw_storm_active_dict.get(_dict_key) is not None:
+ msg = "stormWatch is active for %s - return true" % (_dict_key)
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
+ return True
+ else:
+ msg = "no stormWatch active entry for %s - continue" % (_dict_key)
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
+
+ # if we got this far, trap is in stormwatch configs, we've incremented
+ # counter in sw_storm_counter_dict - figure out if we are over limit
+ if sws.sw_storm_counter_dict[_dict_key] > _high_water_val:
+ _loc_agent = _dict_key.split()[0]
+ _loc_oid = _dict_key.split()[1]
+ msg = "STORM ACTIVE: received %d events (%s) from %s (greater than high water threshold: %d)" % (
+ sws.sw_storm_counter_dict[_dict_key], _loc_oid, _loc_agent, _high_water_val)
+ ecomp_logger(tds.LOG_TYPE_AUDIT, tds.SEV_WARN, tds.CODE_GENERAL, msg)
+ try:
+ sws.sw_storm_active_dict[_dict_key] = True
+ except Exception as e:
+ msg = "ERROR setting %s in storm active state: %s " % (
+ _dict_key, e)
+ ecomp_logger(tds.LOG_TYPE_ERROR, tds.SEV_ERROR,
+ tds.CODE_GENERAL, msg)
+ return True
+ else:
+ return False
+
+# # # # # # # # # # # # #
+# fx: sw_reset_counter_dict
+# - reset counter dictionary on <interval> boundaries
+# # # # # # # # # # # # #
+
+
+def sw_reset_counter_dict():
+ """
+ Create new storm_active_dict based on quantities received during
+ last sample interval
+ :Parameters:
+ :Exceptions:
+ none
+ :Keywords:
+ stormwatch count threshold
+ :Variables:
+ """
+
+ # <stats>
+ # publish stats to MR...
+ try:
+ msg = "publish counts-by-oid from stats.oid_counter_dict"
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO,
+ tds.CODE_GENERAL, msg)
+ msg = "publish count-by-agent from stats.agent_counter_dict"
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO,
+ tds.CODE_GENERAL, msg)
+ except Exception as e:
+ msg = "unable to publish counts by oid and agent to MR: " % (e)
+ ecomp_logger(tds.LOG_TYPE_ERROR, tds.SEV_WARN, tds.CODE_GENERAL, msg)
+
+ # ...and now reset stats counters to start next interval
+ try:
+ stats.oid_counter_dict.clear()
+ stats.agent_counter_dict.clear()
+ stats.total_notifications = 0
+ except Exception as e:
+ msg = "unable to reset counts by oid and agent dictionaries - stats will be INNACURATE: " % (
+ e)
+ ecomp_logger(tds.LOG_TYPE_ERROR, tds.SEV_WARN, tds.CODE_GENERAL, msg)
+ # </stats>
+
+ # <storm watch active>
+
+ # for k in sws.sw_storm_active_dict:
+ # File "./snmptrapd.py", line 642, in notif_receiver_cb
+ # if stormwatch.sw_storm_active(tds.trap_dict["agent address"], tds.trap_dict["notify OID"]):
+ # File "/opt/app/snmptrap/bin/mod/trapd_stormwatch.py", line 299, in sw_storm_active
+ # sw_reset_counter_dict()
+ # File "/opt/app/snmptrap/bin/mod/trapd_stormwatch.py", line 381, in sw_reset_counter_dict
+ # for k in sws.sw_storm_active_dict:
+ # RuntimeError: dictionary changed size during iteration
+ # FIXME: changed to "for k in list(sw_storm_active_dict)" as explained here:
+ # see https://stackoverflow.com/questions/20418851/delete-an-entry-from-a-dictionary-python
+
+ for k in list(sws.sw_storm_active_dict):
+ _loc_agent = k.split()[0]
+ _loc_oid = k.split()[1]
+
+ _high_water_val = sws.sw_config_high_water_in_interval_dict[_loc_oid]
+
+ if sws.sw_storm_counter_dict[k] >= _high_water_val:
+ msg = "%s remaining in storm state, received %d events (GE to upper threshold: %d)" % (
+ k, sws.sw_storm_counter_dict[k], _high_water_val)
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO,
+ tds.CODE_GENERAL, msg)
+ sws.sw_storm_counter_dict[k] = 0
+ else:
+ _low_water_val = sws.sw_config_low_water_in_interval_dict[_loc_oid]
+ if sws.sw_storm_counter_dict[k] < _low_water_val:
+ try:
+ msg = "STORM OVER: received %d events (%s) from %s (less than low water threshold: %d)" % (
+ sws.sw_storm_counter_dict[k], _loc_oid, _loc_agent, _low_water_val)
+ ecomp_logger(tds.LOG_TYPE_AUDIT, tds.SEV_WARN,
+ tds.CODE_GENERAL, msg)
+ del sws.sw_storm_active_dict[k]
+ sws.sw_storm_counter_dict[k] = 0
+ except Exception as e:
+ msg = "unable to remove %s from storm active dictionary - TRAPS MAY BE DISCARDED UNINTENTIONALLY! Reason: %s " % (
+ k, e)
+ ecomp_logger(tds.LOG_TYPE_ERROR, tds.SEV_ERROR,
+ tds.CODE_GENERAL, msg)
+ else:
+ msg = "%s remaining in storm state, received %d events (GE to lower threshold: %d)" % (
+ k, sws.sw_storm_counter_dict[k], _low_water_val)
+ ecomp_logger(tds.LOG_TYPE_ERROR, tds.SEV_INFO,
+ tds.CODE_GENERAL, msg)
+ sws.sw_storm_counter_dict[k] = 0
+
+ sws.sw_last_stormwatch_dict_analysis = int(time.time())
+
+ return True
+
+# # # # # # # # # # # # #
+# fx: sw_increment_counter
+# - increment OID and agent trap counters
+# based on arriving trap attributes
+# # # # # # # # # # # # #
+
+
+def sw_increment_counter(_dict_key):
+ """
+ Add to appropriate counter based on arriving trap
+ agent and OID
+ :Parameters:
+ _dict_key
+ agent address from trap PDU and notify OID
+ trap PDU, separated by a space
+ :Exceptions:
+ none
+ :Keywords:
+ stormwatch count threshold
+ :Variables:
+ """
+
+ try:
+ sws.sw_storm_counter_dict[_dict_key] += 1
+ msg = "stormwatch counter for %s now: %d" % (
+ _dict_key, sws.sw_storm_counter_dict[_dict_key])
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO,
+ tds.CODE_GENERAL, msg)
+ return True
+ except Exception as E:
+ msg = "first trap for %s - init stormwatch counter to 1" % (_dict_key)
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO,
+ tds.CODE_GENERAL, msg)
+ sws.sw_storm_counter_dict[_dict_key] = 1
+ return True
diff --git a/snmptrap/mod/trapd_stormwatch_settings.py b/snmptrap/mod/trapd_stormwatch_settings.py
new file mode 100644
index 0000000..f2586f9
--- /dev/null
+++ b/snmptrap/mod/trapd_stormwatch_settings.py
@@ -0,0 +1,61 @@
+# ============LICENSE_START=======================================================
+# Copyright (c) 2020 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=========================================================
+"""
+"""
+
+__docformat__ = 'restructuredtext'
+
+
+def init():
+
+ # <Storm Watch>
+ #
+ # sw_storm_counter_dict
+ # key [<ip address>.<notify oid>] -> count
+ #
+ # sw_storm_active_dict
+ # key [<ip address>.<notify oid>] -> True (or False, but no key present
+ # means False)
+ #
+ # sw_config_oid_dict
+ # key [<notify oid>] -> "true" (key presence means it participates)
+ #
+ # sw_config_low_water_in_interval_dict
+ # key [<notify oid>] -> <int> value that stormActive turns False
+ #
+ # sw_config_high_water_in_interval_dict
+ # key [<notify oid>] -> <int> value that stormActive turns True
+ #
+ global sw_storm_counter_dict
+ sw_storm_counter_dict = {}
+
+ global sw_storm_active_dict
+ sw_storm_active_dict = {}
+
+ global sw_config_oid_dict
+ sw_config_oid_dict = {}
+ global sw_config_low_water_in_interval_dict
+ sw_config_low_water_in_interval_dict = {}
+ global sw_config_high_water_in_interval_dict
+ sw_config_high_water_in_interval_dict = {}
+ global sw_config_category
+ sw_config_category = {}
+
+ global sw_interval_in_seconds
+ sw_interval_in_seconds = 60
+ global sw_last_stormwatch_dict_analysis
+ sw_last_stormwatch_dict_analysis = 0
+ # </Storm Watch>
diff --git a/snmptrap/mod/trapd_vb_types.py b/snmptrap/mod/trapd_vb_types.py
index 2d01a30..98d5d2c 100644
--- a/snmptrap/mod/trapd_vb_types.py
+++ b/snmptrap/mod/trapd_vb_types.py
@@ -1,7 +1,5 @@
# ============LICENSE_START=======================================================
-# org.onap.dcae
-# ================================================================================
-# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2018-2020 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.
@@ -15,9 +13,6 @@
# 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 converting varbind types from Net-SNMP to PYSNMP
@@ -47,22 +42,24 @@ prog_name = os.path.basename(__file__)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
_pysnmp_to_netsnmp_vb_type = {
- 'Integer' : 'integer',
- 'Gauge32' : 'unsigned',
- 'Counter32' : 'counter32',
- 'OctetString' : 'octet',
- 'py_type_5' : 'hex',
- 'py_type_6' : 'decimal',
- 'Null' : 'null',
- 'ObjectIdentifier' : 'oid',
- 'TimeTicks' : 'timeticks',
- 'IpAddress' : 'ipaddress',
- 'Bits' : 'bits'
- }
+ 'Integer32': 'integer',
+ 'Integer': 'integer',
+ 'Gauge32': 'unsigned',
+ 'Counter32': 'counter32',
+ 'OctetString': 'octet',
+ 'py_type_5': 'hex',
+ 'py_type_6': 'decimal',
+ 'Null': 'null',
+ 'ObjectIdentifier': 'oid',
+ 'TimeTicks': 'timeticks',
+ 'IpAddress': 'ipaddress',
+ 'Bits': 'bits'
+}
default_vb_type = "octet"
-def pysnmp_to_netsnmp_varbind_convert (_pysnmp_vb_type):
+
+def pysnmp_to_netsnmp_varbind_convert(_pysnmp_vb_type):
"""
Convert pysnmp varbind types to Net-SNMP nomenclature
to maintain backward compatibilty with existing solutions
@@ -76,14 +73,11 @@ def pysnmp_to_netsnmp_varbind_convert (_pysnmp_vb_type):
# lookup _pysnmp_vb_type in conversion dictionary
try:
- msg = ("checking for netsnmp equiv of varbind type: %s" \
- % _pysnmp_vb_type)
- ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
_netsnmp_vb_type = _pysnmp_to_netsnmp_vb_type[_pysnmp_vb_type]
return _netsnmp_vb_type
except Exception as e:
# if not found, return original pysnmp type
- msg = ("%s not configured as pysnmp varbind type" \
- % _pysnmp_vb_type)
+ msg = ("%s not configured as pysnmp varbind type - returning %s"
+ % (_pysnmp_vb_type,default_vb_type))
ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
return default_vb_type