Skip to content
Snippets Groups Projects
Commit 8b533abe authored by Pelle Koster's avatar Pelle Koster
Browse files

POL1-826: reintroduce snmp check for ipv6 counters on juniper ae subinterfaces

parent ef63141e
No related branches found
No related tags found
No related merge requests found
......@@ -31,6 +31,10 @@ _DEFAULT_CONFIG = {
'config': '/var/lib/sensu/conf/get-interface-stats.config.json',
'command': '{script} --config {config} {args}',
},
'snmp-interface-check': {
'script': '/var/lib/sensu/bin/counter2influx-v6.sh',
'measurement': 'counters',
},
'gws-direct-interface-check': {
'script': '/var/lib/sensu/bin/poll-gws-direct.sh',
'measurement': 'gwsd_counters',
......@@ -81,6 +85,15 @@ CONFIG_SCHEMA = {
'required': ['script', 'config', 'command'],
'additionalProperties': False
},
'snmp-interface-check': {
'type': 'object',
'properties': {
'script': {'type': 'string'},
'measurement': {'type': 'string'},
},
'required': ['script', 'measurement'],
'additionalProperties': False
},
'sensu': {
'type': 'object',
'properties': {
......@@ -92,6 +105,8 @@ CONFIG_SCHEMA = {
'api-key': {'type': 'string'},
'interface-check':
{'$ref': '#/definitions/router-check'},
'snmp-interface-check':
{'$ref': '#/definitions/snmp-interface-check'},
'gws-direct-interface-check':
{'$ref': '#/definitions/influx-check'},
'dscp32-service-check':
......
......@@ -9,8 +9,6 @@ logger = logging.getLogger(__name__)
def _is_rtr_check(check):
name = check["metadata"]["name"]
# check-* is the old-style name (add to the returned
# data so it can be deleted)
return re.match(r"^(rtr)-[^-]+\.geant\.net$", name)
......@@ -26,8 +24,7 @@ def load_checks(sensu_params, filter_by):
return {c["metadata"]["name"]: c for c in checks}
# TODO [POL1-797] rm after POL1-773 runs in production
def load_deprecated_ifc_checks(sensu_params):
def load_ifc_checks(sensu_params):
return load_checks(sensu_params, _is_ifc_check)
......@@ -35,6 +32,45 @@ def load_router_checks(sensu_params):
return load_checks(sensu_params, _is_rtr_check)
class SNMPInterfaceCheck(sensu.AbstractCheck):
COMMAND_STR = "{script} {measurement} {community} {hostname} {interface} {if_index}"
def __init__(self, ifc_check_params, interface):
super().__init__()
self.ifc_check_params = ifc_check_params
self.interface = interface
@sensu.AbstractCheck.name.getter
def name(self):
# fix POL1-386 - replace : in interface name with .
# https://docs.sensu.io/sensu-go/latest/observability-pipeline/
# observe-schedule/checks/#metadata-attributes
ifc_name = self.interface["name"].replace("/", "-").replace(":", ".")
return f'ifc-{self.interface["router"]}-{ifc_name}'
@sensu.AbstractCheck.command.getter
def command(self):
return self.COMMAND_STR.format(
script=self.ifc_check_params["script"],
measurement=self.ifc_check_params["measurement"],
# TODO: add community string to /poller/interfaces response
# (cf. POL1-339)
community="0pBiFbD",
hostname=self.interface["router"],
interface=self.interface["name"],
if_index=self.interface["snmp-index"],
)
@sensu.AbstractCheck.proxy_entity_name.getter
def proxy_entity_name(self):
return self.interface["router"]
@staticmethod
def requires_snmp_check(interface):
# only juniper ae subinterfaces for now
return re.match(r"^ae\d+\.\d+", interface["name"])
class NetconfRouterCheck(sensu.AbstractCheck):
METRIC_FORMAT = ""
METRIC_HANDLERS = None
......@@ -68,7 +104,7 @@ class NetconfRouterCheck(sensu.AbstractCheck):
return self.router
def refresh(sensu_params, inventory_interfaces):
def netconf_router_refresh(sensu_params, inventory_interfaces):
routers_w_vendor = {
(ifc["router"], ifc.get("vendor")) for ifc in inventory_interfaces
}
......@@ -78,12 +114,16 @@ def refresh(sensu_params, inventory_interfaces):
for router, vendor in routers_w_vendor
]
r1 = sensu.refresh(sensu_params, [], load_deprecated_ifc_checks(sensu_params))
r2 = sensu.refresh(sensu_params, required_checks, load_router_checks(sensu_params))
return {
"checks": r1["checks"] + r2["checks"],
"input": r1["input"] + r2["input"],
"created": r1["created"] + r2["created"],
"updated": r1["updated"] + r2["updated"],
"deleted": r1["deleted"] + r2["deleted"],
}
return sensu.refresh(
sensu_params, required_checks, load_router_checks(sensu_params)
)
def snmp_interfaces_refresh(sensu_params, inventory_interfaces):
required_checks = [
SNMPInterfaceCheck(sensu_params["snmp-interface-check"], ifc)
for ifc in inventory_interfaces
if SNMPInterfaceCheck.requires_snmp_check(ifc)
]
return sensu.refresh(sensu_params, required_checks, load_ifc_checks(sensu_params))
......@@ -52,12 +52,13 @@ REFRESH_RESULT_SCHEMA = {
},
'type': 'object',
'properties': {
'interfaces': {'$ref': '#/definitions/refresh-result'},
'netconf': {'$ref': '#/definitions/refresh-result'},
'snmp': {'$ref': '#/definitions/refresh-result'},
'gws_direct': {'$ref': '#/definitions/refresh-result'},
'gws_indirect': {'$ref': '#/definitions/refresh-result'},
'eumetsat_multicast': {'$ref': '#/definitions/refresh-result'},
},
'required': ['interfaces'],
'required': ['netconf'],
'additionalProperties': False
}
......@@ -90,7 +91,8 @@ def refresh(config, force=False):
= inventory.load_eumetsat_multicast_subscriptions(
config['inventory'])
result = {
'interfaces': interfaces.refresh(config['sensu'], state.interfaces),
'netconf': interfaces.netconf_router_refresh(config['sensu'], state.interfaces),
'snmp': interfaces.snmp_interfaces_refresh(config['sensu'], state.interfaces),
'gws_direct': gws_direct.refresh(config['sensu'], state.gws_direct),
'gws_indirect': gws_indirect.refresh(
config['sensu'], state.gws_indirect),
......
......@@ -44,6 +44,10 @@ def config():
"config": "/var/lib/sensu/conf/get-interface-stats.config.json",
"command": "{script} --config {config} {args}",
},
"snmp-interface-check": {
"script": "/var/lib/sensu/bin/counter2influx-v6.sh",
"measurement": "counters",
},
"gws-direct-interface-check": {
"script": "/var/lib/sensu/bin/poll-gws-direct.sh",
"measurement": "gwsd_counters",
......
......@@ -55,5 +55,21 @@
"description": "blah blah nokia router",
"circuits": [],
"snmp-index": 9999
},
{
"router": "mx1.fra.de.geant.net",
"name": "ae10.1",
"bundle": [],
"bundle-parents": [],
"description": "blah blah",
"circuits": [
{
"id": 50028,
"name": "something",
"type": "SERVICE",
"status": "operational"
}
],
"snmp-index": 9999
}
]
......@@ -53,6 +53,30 @@ def test_router_check(config):
assert check["output_metric_handlers"] == []
def test_snmp_interface_check(config):
check = interfaces.SNMPInterfaceCheck(
config["sensu"]["snmp-interface-check"],
{"router": "bogus.router", "name": "bogus/1/1", "snmp-index": 123},
).to_dict()
assert check["command"] == (
"/var/lib/sensu/bin/counter2influx-v6.sh counters 0pBiFbD bogus.router "
"bogus/1/1 123"
)
assert check["proxy_entity_name"] == "bogus.router"
assert check["metadata"]["name"] == "ifc-bogus.router-bogus-1-1"
assert check["output_metric_format"] == "influxdb_line"
assert check["output_metric_handlers"] == ["influx-db-handler"]
@responses.activate
def test_snmp_interface_refresh(config, mocked_sensu, mocked_inventory):
routers = inventory.load_interfaces("http://inventory1")
result = interfaces.snmp_interfaces_refresh(
config["sensu"], inventory_interfaces=routers
)
assert result == {"checks": 3, "input": 1, "created": 1, "updated": 0, "deleted": 3}
def test_nokia_router_check(config):
check = interfaces.NetconfRouterCheck(
config["sensu"]["interface-check"], "xyz", vendor="nokia"
......@@ -68,22 +92,14 @@ def test_nokia_router_check(config):
assert check["output_metric_handlers"] == []
@responses.activate
def test_cleans_up_old_interface_checks(config, mocked_sensu, mocked_inventory):
routers = inventory.load_interfaces("http://inventory1")
result = interfaces.refresh(config["sensu"], inventory_interfaces=routers)
assert result == {"checks": 3, "input": 3, "created": 3, "updated": 0, "deleted": 3}
sensu.clear_cached_values()
result = interfaces.refresh(config["sensu"], inventory_interfaces=routers)
assert result == {"checks": 3, "input": 3, "created": 0, "updated": 0, "deleted": 0}
@responses.activate
def test_runs_idempotent(config, mocked_sensu, mocked_inventory):
routers = inventory.load_interfaces("http://inventory1")
interfaces.refresh(config["sensu"], inventory_interfaces=routers)
interfaces.netconf_router_refresh(config["sensu"], inventory_interfaces=routers)
sensu.clear_cached_values()
result = interfaces.refresh(config["sensu"], inventory_interfaces=routers)
result = interfaces.netconf_router_refresh(
config["sensu"], inventory_interfaces=routers
)
assert result == {"checks": 3, "input": 3, "created": 0, "updated": 0, "deleted": 0}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment