diff --git a/agent_based/ospfv3_area.py b/agent_based/ospfv3_area.py index bbf909a02647f7f330bb55e9d306c4dfd791cd74..fc87fa8e505ee2de5c410591f3111fc381747c93 100644 --- a/agent_based/ospfv3_area.py +++ b/agent_based/ospfv3_area.py @@ -43,7 +43,7 @@ # .1.3.6.1.2.1.191.1.2.1.16.0 = INTEGER: 2 # .1.3.6.1.2.1.191.1.2.1.16.3 = INTEGER: 2 # -# sample info +# sample string_table # [ # ['0', '1', '17', '4', '0', '18', '646544', '2', '1', '2', '3', '0', '0', '1', '2'], # ['1', '1', '3', '1', '0', '7', '317410', '2', '1', '2', '3', '0', '0', '1', '2'] @@ -69,6 +69,16 @@ from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( StringTable, ) +from cmk.base.plugins.agent_based.utils.ospfv3 import ( + ospf_area_impotasextern, + ospf_area_summary, + ospf_area_translatorrole, + ospf_area_translatorrolestate, + ospf_area_submetrictype, + ospf_area_teeenabled, + get_area_type +) + @dataclass class OspfV3Area: @@ -90,61 +100,6 @@ class OspfV3Area: def parse_ospfv3_area(string_table: StringTable) -> Dict[str, OspfV3Area]: - def ospf_area_impotasextern(st: str) -> str: - names = {'1': 'import External', - '2': 'import no External', - '3': 'import Nssa', - } - return names.get(st, st) - - def ospf_area_summary(st: str) -> str: - names = {'1': 'no Area Summary', - '2': 'send Area Summary'} - return names.get(st, st) - - def ospf_area_translatorrole(st: str) -> str: - names = { - '1': 'always', - '2': 'candidate', - } - return names.get(st, st) - - def ospf_area_translatorrolestate(st: str) -> str: - names = { - '1': 'enabled', - '2': 'elected', - '3': 'disabled', - } - return names.get(st, st) - - def ospf_area_submetrictype(st: str) -> str: - names = { - '1': 'ospfv3 Metric', - '2': 'comparable Cost', - '3': 'non Comparable', - } - return names.get(st, st) - - def ospf_area_teeenabled(st: str) -> str: - names = { - '1': 'enabled', - } - return names.get(st, 'disabled') - - def get_area_type(AreaImportAsExtern: str, AreaSummary: str) -> str: - areatype = 'UNKNOWN' - if int(AreaImportAsExtern) == 1 and int(AreaSummary) == 2: - areatype = 'normal' - if int(AreaImportAsExtern) == 2 and int(AreaSummary) == 1: - areatype = 'totaly subby' - if int(AreaImportAsExtern) == 2 and int(AreaSummary) == 2: - areatype = 'stubby' - if int(AreaImportAsExtern) == 3 and int(AreaSummary) == 2: - areatype = 'NSSA' - if int(AreaImportAsExtern) == 3 and int(AreaSummary) == 1: - areatype = 'totaly NSSA' - return areatype - areas = {} for area in string_table: AreaId, AreaImportAsExtern, AreaSpfRuns, AreaBdrRtrCount, AreaAsBdrRtrCount, AreaScopeLsaCount, \ @@ -194,12 +149,10 @@ def check_ospfv3_area(item, params, section: Dict[str, OspfV3Area]) -> CheckResu value=value, label=label, metric_name=f'ospfv3_area_{metric}', + render_func=lambda v: f'{v:.0f}' ) - yield Result(state=State.OK, summary=f'Area type: {area.AreaType}') - yield Result(state=State.OK, summary=f'area scope LSA checksum: {area.AreaScopeLsaCksumSum}') - - yield Metric(name='ospfv3_area_nssatranslatorevents', value=area.AreaNssaTranslatorEvents) - + yield Result(state=State.OK, notice=f'Area type: {area.AreaType}') + yield Result(state=State.OK, notice=f'Area scope LSA checksum: {area.AreaScopeLsaCksumSum}') yield Result(state=State.OK, notice=f'Area import as extern: {area.AreaImportAsExtern}') yield Result(state=State.OK, notice=f'Area summary: {area.AreaSummary}') yield Result(state=State.OK, notice=f'Area stub metric: {area.AreaStubMetric}') @@ -209,6 +162,8 @@ def check_ospfv3_area(item, params, section: Dict[str, OspfV3Area]) -> CheckResu yield Result(state=State.OK, notice=f'Area NSSA stub metric type: {area.AreaStubMetricType}') yield Result(state=State.OK, notice=f'Area Traffic engineering {area.AreaTEEnabled}') + yield Metric(name='ospfv3_area_nssatranslatorevents', value=area.AreaNssaTranslatorEvents) + register.snmp_section( name='ospfv3_area', diff --git a/agent_based/ospfv3_general.py b/agent_based/ospfv3_general.py index 7e0594bc33bd95b3adfe69f55ea5ebefebd501ba..c6f909e54f9d8625119bf20dc6231a5be5880869 100644 --- a/agent_based/ospfv3_general.py +++ b/agent_based/ospfv3_general.py @@ -38,7 +38,7 @@ # .1.3.6.1.2.1.191.1.1.24.0 = 0 # .1.3.6.1.2.1.191.1.1.25.0 = 0 # -# sample info +# sample string_table # [['0', '16843038', '1', '3', '1', '2', '0', '0', '256', '51', '0', '100000', '1', '1']] from dataclasses import dataclass @@ -53,7 +53,6 @@ from cmk.base.plugins.agent_based.agent_based_api.v1 import ( exists, Metric, OIDEnd, - check_levels, ) from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( DiscoveryResult, @@ -61,6 +60,14 @@ from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( StringTable, ) +from cmk.base.plugins.agent_based.utils.ospfv3 import ( + ospf_stub_router_advertisement, + ospf_admin_status, + ospf_abr_asbr_status, + ospf_stub_router_support, + render_ipv4_neighbor_id, +) + @dataclass class OspfV3General: @@ -80,69 +87,6 @@ class OspfV3General: def parse_ospfv3_general(string_table: StringTable) -> Optional[OspfV3General]: - def ospf_stub_router_advertisement(st: str) -> str: - names = {'1': 'do Not Advertise', - '2': 'advertise'} - return names.get(st, st) - - def ospf_exit_reason(st: str) -> str: - names = { - '1': 'none', - '2': 'in Progress', - '3': 'completed', - '4': 'timed Out', - '5': 'topology Changed', - } - return names.get(st, st) - - def ospf_restart_status(st: str) -> str: - names = { - '1': 'not Restarting', - '2': 'planned Restart', - '3': 'unplanned Restart', - } - return names.get(st, st) - - def ospf_restart_support(st: str) -> str: - names = { - '1': 'none', - '2': 'planned Only', - '3': 'planned And Unplanned', - } - return names.get(st, st) - - def ospf_admin_status(st: str) -> str: - names = { - '1': 'enabled', - '2': 'disabled', - } - return names.get(st, st) - - def ospf_abr_asbr_status(st: str) -> str: - names = { - '1': 'yes', - '2': 'no', - } - return names.get(st, st) - - def ospf_stub_router_support(st: str) -> str: - names = { - '1': 'yes', - '2': 'no', - } - return names.get(st, st) - - def render_ipv4_router_id(nbrRtrId: str) -> str: - nbrRtrId = int(nbrRtrId) - firstoctet = nbrRtrId / (256 * 256 * 256) - nbrRtrId = nbrRtrId - (firstoctet * 256 * 256 * 256) - secondocted = nbrRtrId / (256 * 256) - nbrRtrId = nbrRtrId - (secondocted * 256 * 256) - thirdorted = nbrRtrId / 256 - nbrRtrId = nbrRtrId - (thirdorted * 256) - nbrRtrId = '%d.%d.%d.%d' % (firstoctet, secondocted, thirdorted, nbrRtrId) - return nbrRtrId - try: OID_END, RouterId, AdminStatus, VersionNumber, AreaBdrRtrStatus, ASBdrRtrStatus, AsScopeLsaCount, \ AsScopeLsaCksumSum, OriginateNewLsas, RxNewLsas, ExtLsaCount, ExtAreaLsdbLimit, \ @@ -151,7 +95,7 @@ def parse_ospfv3_general(string_table: StringTable) -> Optional[OspfV3General]: return return OspfV3General( - RouterId=render_ipv4_router_id(RouterId), + RouterId=render_ipv4_neighbor_id(RouterId), AdminStatus=ospf_admin_status(AdminStatus), VersionNumber=int(VersionNumber), AreaBdrRtrStatus=ospf_abr_asbr_status(AreaBdrRtrStatus), @@ -173,23 +117,23 @@ def discovery_ospfv3_general(section: OspfV3General) -> DiscoveryResult: def check_ospfv3_general(params, section: OspfV3General) -> CheckResult: yield Result(state=State.OK, summary=f'Router ID: {section.RouterId}') - yield Result(state=State.OK, summary=f'Area border router: {section.AreaBdrRtrStatus}') - yield Result(state=State.OK, summary=f'Autonomous system border router: {section.ASBdrRtrStatus}') - - yield Metric(name='ospf_general_lsacount', value=section.AsScopeLsaCount) - yield Metric(name='ospf_general_rxnewlsas', value=section.RxNewLsas) - yield Metric(name='ospf_general_extlsacount', value=section.ExtLsaCount) + yield Result(state=State.OK, summary=f'ABR: {section.AreaBdrRtrStatus}') + yield Result(state=State.OK, summary=f'ASBR: {section.ASBdrRtrStatus}') yield Result(state=State.OK, notice=f'Version number: {section.VersionNumber}') yield Result(state=State.OK, notice=f'AS scope LSA checksum: {section.AsScopeLsaCksumSum}') yield Result(state=State.OK, notice=f'max # of non-default AS-external-LSAs: {section.ExtAreaLsdbLimit}') - yield Result(state=State.OK, notice=f'Reference bandwidth: %s KBPS' % section.ReferenceBandwidth) + yield Result(state=State.OK, notice=f'Reference bandwidth: {section.ReferenceBandwidth} KBPS') yield Result(state=State.OK, notice=f'Stub router support: {section.StubRouterSupport}') yield Result(state=State.OK, notice=f'Stub router advertisement: {section.StubRouterAdvertisement}') if section.AdminStatus == 'disabled': yield Result(state=State.WARN, notice='Admin disabled') + yield Metric(name='ospf3_general_lsacount', value=section.AsScopeLsaCount) + yield Metric(name='ospf3_general_rxnewlsas', value=section.RxNewLsas) + yield Metric(name='ospf3_general_extlsacount', value=section.ExtLsaCount) + register.snmp_section( name='ospfv3_general', @@ -230,7 +174,7 @@ register.snmp_section( register.check_plugin( name='ospfv3_general', - service_name='OSPFv3', + service_name='OSPFv3 general', discovery_function=discovery_ospfv3_general, check_function=check_ospfv3_general, check_default_parameters={ diff --git a/agent_based/ospfv3_interface.py b/agent_based/ospfv3_interface.py index 2c135ada935ba88b687a1cd23a34f5e7d2f61147..9e01868f4a44c24e784b2c71a09868a9bf4dbbd0 100644 --- a/agent_based/ospfv3_interface.py +++ b/agent_based/ospfv3_interface.py @@ -60,7 +60,7 @@ # .1.3.6.1.2.1.191.1.7.1.25.18.0 = INTEGER: 2 # .1.3.6.1.2.1.191.1.7.1.25.23.0 = INTEGER: 2 # -# sample info +# sample string_table # [ # [ # ['1.0', '0', '1', '1', '1', '1', '4', '120', '6', '50529055', '16843038', '6', '1', '4', '104400'], @@ -101,7 +101,6 @@ from cmk.base.plugins.agent_based.agent_based_api.v1 import ( exists, Metric, OIDEnd, - check_levels, ) from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( DiscoveryResult, @@ -109,6 +108,14 @@ from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( StringTable, ) +from cmk.base.plugins.agent_based.utils.ospfv3 import ( + ospf_if_type, + ospf_if_admin_status, + ospf_if_state, + render_ipv4_neighbor_id, + get_short_if_name, +) + @dataclass class OspfV3Interface: @@ -129,59 +136,6 @@ class OspfV3Interface: def parse_ospfv3_interface(string_table: List[StringTable]) -> Optional[Dict[str, OspfV3Interface]]: - def ospf_if_type(st: str) -> str: - names = {'1': 'broadcast', - '2': 'nbma', - '3': 'pointToPoint', - '5': 'pointToMultipoint', - } - return names.get(st, st) - - def ospf_if_admin_status(st: str) -> str: - names = {'1': 'enabled', - '2': 'disabled'} - return names.get(st, st) - - def ospf_if_state(st: str) -> str: - names = { - '1': 'down', - '2': 'loopback', - '3': 'waiting', - '4': 'P2P', - '5': 'DR', - '6': 'BDR', - '7': 'other DR', - '8': 'standby', - } - return names.get(st, st) - - def render_ipv4_neighbor_id(nbrRtrId: str) -> str: - nbrRtrId = int(nbrRtrId) - firstoctet = nbrRtrId / (256 * 256 * 256) - nbrRtrId = nbrRtrId - (firstoctet * 256 * 256 * 256) - secondocted = nbrRtrId / (256 * 256) - nbrRtrId = nbrRtrId - (secondocted * 256 * 256) - thirdorted = nbrRtrId / 256 - nbrRtrId = nbrRtrId - (thirdorted * 256) - nbrRtrId = '%d.%d.%d.%d' % (firstoctet, secondocted, thirdorted, nbrRtrId) - return nbrRtrId - - def get_short_if_name(st: str) -> str: - names = {'ethernet': 'Eth', - 'fastethernet': 'Fa', - 'gigabitethernet': 'Gi', - 'tengigabitethernet': 'Te', - 'fortygigabitethernet': 'Fo', - 'hundredgigabitethernet': 'H', - 'port-channel': 'Po', - 'tunnel': 'T', - 'loopback': 'Lo', - } - for item in names.keys(): - if st.lower().startswith(item): - st = st.lower().replace(item, names.get(item)) - return st - ospf_interfaces = {} interfaceinfo, interfaces = string_table @@ -233,11 +187,8 @@ def check_ospfv3_interface(item, params, section: Dict[str, OspfV3Interface]) -> yield Result(state=State.OK, summary=f'DR: {interface.IfDesignatedRouter}') yield Result(state=State.OK, summary=f'BDR: {interface.IfBackupDesignatedRouter}') yield Result(state=State.OK, summary=f'State: {interface.IfState}') - yield Result(state=State.OK, summary=f'link scope LSA checksum: {interface.IfLinkLsaCksumSum}') - - yield Metric(name='ospfv3_interface_events', value=interface.IfEvents) - yield Metric(name='ospfv3_interface_linkscopelsacount', value=interface.IfLinkScopeLsaCount) + yield Result(state=State.OK, notice=f'Link scope LSA checksum: {interface.IfLinkLsaCksumSum}') yield Result(state=State.OK, notice=f'Interface type: {interface.IfType}') yield Result(state=State.OK, notice=f'Interface priority: {interface.IfRtrPriority}') yield Result(state=State.OK, notice=f'Interface hello interval: {interface.IfHelloInterval}') @@ -254,6 +205,9 @@ def check_ospfv3_interface(item, params, section: Dict[str, OspfV3Interface]) -> if interface.IfState in ['waiting', 'standby']: yield Result(state=State.WARN, notice=f'state is {interface.IfState}') + yield Metric(name='ospfv3_interface_events', value=interface.IfEvents) + yield Metric(name='ospfv3_interface_linkscopelsacount', value=interface.IfLinkScopeLsaCount) + register.snmp_section( name='ospfv3_interface', diff --git a/agent_based/ospfv3_neighbor.py b/agent_based/ospfv3_neighbor.py index f75eda696753b11b9823c89e0fa7282ec7da267d..f074333c2a50910bb513ef3058d465cc74b4e21b 100644 --- a/agent_based/ospfv3_neighbor.py +++ b/agent_based/ospfv3_neighbor.py @@ -37,6 +37,8 @@ # OSPFV3-MIB::ospfv3NbrRestartHelperAge.1.0.50529054 = Gauge32: 0 seconds # OSPFV3-MIB::ospfv3NbrRestartHelperExitReason.1.0.50529054 = INTEGER: none(1) # +# +# sample string_table # [ # [ # ['1.0.50529054', '2', '\xfe\x80\x00\x00\x00\x00\x00\x00\x01\x92\x01h\x00\x00\x00\x03', @@ -67,9 +69,8 @@ # -import re from dataclasses import dataclass -from typing import Optional, Dict, List +from typing import Dict, List from cmk.base.plugins.agent_based.agent_based_api.v1 import ( register, @@ -80,7 +81,6 @@ from cmk.base.plugins.agent_based.agent_based_api.v1 import ( exists, Metric, OIDEnd, - check_levels, ) from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( DiscoveryResult, @@ -88,6 +88,17 @@ from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( StringTable, ) +from cmk.base.plugins.agent_based.utils.ospfv3 import ( + ospf_nbr_addresstype, + ospf_nbr_hellosuppressed, + ospf_nbr_helperstatus, + ospf_nbr_helperexitreason, + render_ipv6_address, + render_ipv4_neighbor_id, + get_short_if_name, + ospf_nbr_state, +) + @dataclass class OspfV3Neighbor: @@ -107,85 +118,6 @@ class OspfV3Neighbor: def parse_ospfv3_neighbor(string_table: List[StringTable]) -> Dict[str, OspfV3Neighbor]: - def ospf_nbr_addresstype(st: str) -> str: - names = {'0': 'unknown', - '1': 'ipv4', - '2': 'ipv6', - '3': 'ipv4z', - '4': 'ipv6z', - '16': 'dns', } - return names.get(st, st) - - def ospf_nbr_hellosuppressed(st: str) -> str: - names = {'1': 'true', - '2': 'false'} - return names.get(st, st) - - def ospf_nbr_helperstatus(st: str) -> str: - names = {'1': 'not Helping', - '2': 'helping'} - return names.get(st, st) - - def ospf_nbr_helperexitreason(st: str) -> str: - names = {'1': 'none', - '2': 'inProgress', - '3': 'completed', - '4': 'timedOut', - '5': 'topologyChanged'} - return names.get(st, st) - - def shorten_ipv6_adress(address: str) -> str: - address = address.split(':') - span = 2 - address = [''.join(address[i:i + span]) for i in range(0, len(address), span)] - for m in range(0, len(address)): - address[m] = re.sub(r'^0{1,3}', r'', address[m]) - address = ':'.join(address) - zeros = ':0:0:0:0:0:0:' - while not zeros == '': - if zeros in address: - address = re.sub(r'%s' % zeros, r'::', address) - zeros = '' - else: - zeros = zeros[:-2] - if address == '0::0': - address = '::' - - return address - - def render_ipv6_address(bytestring) -> str: - address = ':'.join(['%02s' % hex(ord(m))[2:] for m in bytestring]).replace(' ', '0').upper() - address = shorten_ipv6_adress(address) - - return address - - def render_ipv4_neighbor_id(nbrRtrId: str) -> str: - nbrRtrId = int(nbrRtrId) - firstoctet = nbrRtrId / (256 * 256 * 256) - nbrRtrId = nbrRtrId - (firstoctet * 256 * 256 * 256) - secondocted = nbrRtrId / (256 * 256) - nbrRtrId = nbrRtrId - (secondocted * 256 * 256) - thirdorted = nbrRtrId / 256 - nbrRtrId = nbrRtrId - (thirdorted * 256) - nbrRtrId = '%d.%d.%d.%d' % (firstoctet, secondocted, thirdorted, nbrRtrId) - return nbrRtrId - - def get_short_if_name(st: str) -> str: - names = {'ethernet': 'Eth', - 'fastethernet': 'Fa', - 'gigabitethernet': 'Gi', - 'tengigabitethernet': 'Te', - 'fortygigabitethernet': 'Fo', - 'hundredgigabitethernet': 'H', - 'port-channel': 'Po', - 'tunnel': 'T', - 'loopback': 'Lo', - } - for item in names.keys(): - if st.lower().startswith(item): - st = st.lower().replace(item, names.get(item)) - return st - neighbors = {} neighborinfo, interfaces = string_table @@ -228,17 +160,6 @@ def discovery_ospfv3_neighbor(section: Dict[str, OspfV3Neighbor]) -> DiscoveryRe def check_ospfv3_neighbor(item, params, section: Dict[str, OspfV3Neighbor]) -> CheckResult: - def ospf_nbr_state(st: int) -> str: - names = {1: 'down', - 2: 'attempt', - 3: 'init', - 4: 'twoWay', - 5: 'exchangeStart', - 6: 'exchange', - 7: 'loading', - 8: 'full'} - return names.get(st, st) - try: neighbor = section[item] except KeyError: @@ -261,9 +182,6 @@ def check_ospfv3_neighbor(item, params, section: Dict[str, OspfV3Neighbor]) -> C else: yield Result(state=State.UNKNOWN, notice='Invalid Output from Agent') - yield Metric(name='ospfv3_events', value=neighbor.nbrEvents) - yield Metric(name='ospfv3_lsretransqlen', value=neighbor.nbrLsRetransQLen) - yield Result(state=State.OK, notice=f'Neighbor options: {neighbor.nbrOptions}') yield Result(state=State.OK, notice=f'Neighbor priority: {neighbor.nbrPriority}') yield Result(state=State.OK, notice=f'Neighbor hello suppressed: {neighbor.nbrHelloSuppressed}') @@ -271,6 +189,9 @@ def check_ospfv3_neighbor(item, params, section: Dict[str, OspfV3Neighbor]) -> C yield Result(state=State.OK, notice=f'Neighbor helper age: {neighbor.nbrRestartHelperAge}') yield Result(state=State.OK, notice=f'Neighbor helper exit reason: {neighbor.nbrRestartHelperExitReason}') + yield Metric(name='ospfv3_events', value=neighbor.nbrEvents) + yield Metric(name='ospfv3_lsretransqlen', value=neighbor.nbrLsRetransQLen) + register.snmp_section( name='ospfv3_neighbor', diff --git a/agent_based/ospfv3_virtuallink.py b/agent_based/ospfv3_virtuallink.py index df2af49f62e549c28c7f0144df0e68b585a299f7..f78aeb3854aca5940e2326524eed10b1e223d9b5 100644 --- a/agent_based/ospfv3_virtuallink.py +++ b/agent_based/ospfv3_virtuallink.py @@ -39,10 +39,11 @@ # OSPFV3-MIB::ospfv3VirtNbrRestartHelperAge.3.50529054 = Gauge32: 0 seconds # OSPFV3-MIB::ospfv3VirtNbrRestartHelperExitReason.3.50529054 = INTEGER: none(1) # -# +# sample string_table # [ # [ -# ['3.50529054', '0', '0', '2', '0\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x03\x00\x03\x000', '51', '8', '6', '0', '1', '26', '1', '0', '1'] +# ['3.50529054', '0', '0', '2', '0\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x03\x00\x03\x000', +# '51', '8', '6', '0', '1', '26', '1', '0', '1'] # ], # [ # ['1', 'Vlan1'], @@ -66,9 +67,8 @@ # ] # -import re from dataclasses import dataclass -from typing import Optional, Dict, List +from typing import Dict, List from cmk.base.plugins.agent_based.agent_based_api.v1 import ( register, @@ -79,7 +79,6 @@ from cmk.base.plugins.agent_based.agent_based_api.v1 import ( exists, Metric, OIDEnd, - check_levels, ) from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( DiscoveryResult, @@ -87,6 +86,17 @@ from cmk.base.plugins.agent_based.agent_based_api.v1.type_defs import ( StringTable, ) +from cmk.base.plugins.agent_based.utils.ospfv3 import ( + ospf_nbr_addresstype, + ospf_nbr_hellosuppressed, + ospf_nbr_helperstatus, + ospf_nbr_helperexitreason, + render_ipv6_address, + render_ipv4_neighbor_id, + get_short_if_name, + ospf_nbr_state, +) + @dataclass class OspfV3VirtualLink: @@ -100,88 +110,9 @@ class OspfV3VirtualLink: VirtNbrRestartHelperStatus: str VirtNbrRestartHelperAge: int VirtNbrRestartHelperExitReason: str - - -def parse_ospfv3_virtuallink(string_table: List[StringTable]) -> Dict[str, OspfV3VirtualLink]: - def ospf_nbr_addresstype(st): - names = { '0': 'unknown', - '1': 'ipv4', - '2': 'ipv6', - '3': 'ipv4z', - '4': 'ipv6z', - '16':'dns',} - return names.get(st, st) - - def ospf_nbr_hellosuppressed(st): - names = {'1': 'true', - '2': 'false'} - return names.get(st, st) - - def ospf_nbr_helperstatus(st): - names = {'1': 'not Helping', - '2': 'helping'} - return names.get(st, st) - - def ospf_nbr_helperexitreason(st): - names = {'1': 'none', - '2': 'inProgress', - '3': 'completed', - '4': 'timedOut', - '5': 'topologyChanged'} - return names.get(st, st) - - def shorten_ipv6_adress(address): - address = address.split(':') - span = 2 - address = [''.join(address[i:i + span]) for i in range(0, len(address), span)] - for m in range(0, len(address)): - address[m] = re.sub(r'^0{1,3}', r'', address[m]) - address = ':'.join(address) - zeros = ':0:0:0:0:0:0:' - while not zeros == '': - if zeros in address: - address = re.sub(r'%s' % zeros, r'::', address) - zeros = '' - else: - zeros = zeros[:-2] - if address == '0::0': - address = '::' - - return address - - def render_ipv6_address(bytestring): - address = ":".join(["%02s" % hex(ord(m))[2:] for m in bytestring]).replace(' ', '0').upper() - address = shorten_ipv6_adress(address) - - return address - - def render_ipv4_neighbor_id(nbrRtrId: str)-> str: - nbrRtrId = int(nbrRtrId) - firstoctet = nbrRtrId / (256*256*256) - nbrRtrId = nbrRtrId - (firstoctet *256*256*256) - secondocted = nbrRtrId / (256*256) - nbrRtrId = nbrRtrId - (secondocted * 256 * 256) - thirdorted = nbrRtrId / 256 - nbrRtrId = nbrRtrId - (thirdorted * 256) - nbrRtrId = '%d.%d.%d.%d' % (firstoctet, secondocted, thirdorted, nbrRtrId) - return nbrRtrId - def get_short_if_name(st): - names = {'ethernet': 'Eth', - 'fastethernet': 'Fa', - 'gigabitethernet': 'Gi', - 'tengigabitethernet': 'Te', - 'fortygigabitethernet': 'Fo', - 'hundredgigabitethernet': 'H', - 'port-channel': 'Po', - 'tunnel': 'T', - 'loopback': 'Lo', - } - for item in names.keys(): - if st.lower().startswith(item): - st = st.lower().replace(item, names.get(item)) - return st +def parse_ospfv3_virtuallink(string_table: List[StringTable]) -> Dict[str, OspfV3VirtualLink]: virtual_links = {} virtual_links_info, interfaces = string_table @@ -202,7 +133,7 @@ def parse_ospfv3_virtuallink(string_table: List[StringTable]) -> Dict[str, OspfV nbrLocalInterface = get_short_if_name(ifName) # virtual_links[f'{VirtNbrAddress} on {nbrLocalInterface}']= OspfV3VirtualLink( - virtual_links[VirtNbrAddress]= OspfV3VirtualLink( + virtual_links[VirtNbrAddress] = OspfV3VirtualLink( VirtNbrId=render_ipv4_neighbor_id(VirtNbrId), VirtNbrArea=int(VirtNbrArea), VirtNbrOptions=VirtNbrOptions, @@ -224,31 +155,19 @@ def discovery_ospfv3_virtuallink(section: Dict[str, OspfV3VirtualLink]) -> Disco def check_ospfv3_virtuallink(item, params, section: Dict[str, OspfV3VirtualLink]) -> CheckResult: - - def ospf_nbr_state(st: int)-> str: - names = {1: 'down', - 2: 'attempt', - 3: 'init', - 4: 'twoWay', - 5: 'exchangeStart', - 6: 'exchange', - 7: 'loading', - 8: 'full'} - return names.get(st, st) - try: virtual_link = section[item] except KeyError: yield Result(state=State.UNKNOWN, notice='Item not found in SNMP data') return - + nbrstatus = ospf_nbr_state(virtual_link.VirtNbrState) yield Result(state=State.OK, summary=f'Neighbor ID: {virtual_link.VirtNbrId}') - yield Result(state=State.OK, summary=f', Area: {virtual_link.VirtNbrArea}') + yield Result(state=State.OK, summary=f'Area: {virtual_link.VirtNbrArea}') nbrstate = virtual_link.VirtNbrState - + if nbrstate in params['critical_states']: yield Result(state=State.CRIT, notice='State: {nbrstatus}') elif nbrstate in params['warning_states']: @@ -258,14 +177,15 @@ def check_ospfv3_virtuallink(item, params, section: Dict[str, OspfV3VirtualLink] else: yield Result(state=State.UNKNOWN, notice='Invalid Output from Agent') - yield Metric(name='ospfv3_events', value=virtual_link.VirtNbrEvents) - yield Metric(name='ospfv3_lsretransqlen', value=virtual_link.VirtNbrLsRetransQLen) - yield Result(state=State.OK, notice=f'Virtual link options: {virtual_link.VirtNbrOptions}') yield Result(state=State.OK, notice=f'Virtual link hello suppressed: {virtual_link.VirtNbrHelloSuppressed}') yield Result(state=State.OK, notice=f'Virtual link helper status: {virtual_link.VirtNbrRestartHelperStatus}') yield Result(state=State.OK, notice=f'Virtual link helper age: {virtual_link.VirtNbrRestartHelperAge}') - yield Result(state=State.OK, notice=f'Virtual link helper exit reason: {virtual_link.VirtNbrRestartHelperExitReason}') + yield Result(state=State.OK, + notice=f'Virtual link helper exit reason: {virtual_link.VirtNbrRestartHelperExitReason}') + + yield Metric(name='ospfv3_events', value=virtual_link.VirtNbrEvents) + yield Metric(name='ospfv3_lsretransqlen', value=virtual_link.VirtNbrLsRetransQLen) register.snmp_section( diff --git a/agent_based/utils/ospfv3.py b/agent_based/utils/ospfv3.py new file mode 100644 index 0000000000000000000000000000000000000000..832cf90a73904364b51e6aa71c830edbf55e4108 --- /dev/null +++ b/agent_based/utils/ospfv3.py @@ -0,0 +1,306 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# License: GNU General Public License v2 +# +# Author: thl-cmk[at]outlook[dot]com +# URL : https://thl-cmk.hopto.org +# Date : 2021-09-17 +# +# include file, will be used with ospfv3_area, ospfv3_general, ospfv3_interface, ospfv3_neighbor, ospfv3_virtuallink +# +import re + + +def get_area_type(area_import_as_extern: str, area_summary: str) -> str: + areatype = 'UNKNOWN' + if int(area_import_as_extern) == 1 and int(area_summary) == 2: + areatype = 'normal' + if int(area_import_as_extern) == 2 and int(area_summary) == 1: + areatype = 'totaly subby' + if int(area_import_as_extern) == 2 and int(area_summary) == 2: + areatype = 'stubby' + if int(area_import_as_extern) == 3 and int(area_summary) == 2: + areatype = 'NSSA' + if int(area_import_as_extern) == 3 and int(area_summary) == 1: + areatype = 'totaly NSSA' + return areatype + + +def render_ipv4_neighbor_id(router_id: str) -> str: + """ + >>> from pprint import pprint + >>> pprint(render_ipv4_neighbor_id('50529054')) + 3.3.3.30 + """ + router_id = int(router_id) + firstoctet = router_id // (256 * 256 * 256) + router_id = router_id - (firstoctet * 256 * 256 * 256) + secondocted = router_id // (256 * 256) + router_id = router_id - (secondocted * 256 * 256) + thirdorted = router_id // 256 + router_id = router_id - (thirdorted * 256) + router_id = f'{firstoctet}.{secondocted}.{thirdorted}.{router_id}' + return router_id + + +_interface_displayhints = { + 'ethernet': 'eth', + 'fastethernet': 'Fa', + 'gigabitethernet': 'Gi', + 'tengigabitethernet': 'Te', + 'fortygigabitethernet': 'Fo', + 'hundredgigabitethernet': 'Hu', + 'port-channel': 'Po', + 'tunnel': 'Tu', + 'loopback': 'Lo', + 'cellular': 'Cel', + 'vlan': 'Vlan', + 'management': 'Ma', +} + + +def get_short_if_name(ifname: str) -> str: + """ + returns short interface name from long interface name + ifname: is the long interface name + :type ifname: str + """ + + for ifname_prefix in _interface_displayhints.keys(): + if ifname.lower().startswith(ifname_prefix.lower()): + ifname_short = _interface_displayhints[ifname_prefix] + return ifname.lower().replace(ifname_prefix.lower(), ifname_short, 1) + return ifname + + +def _shorten_ipv6_adress(address: str) -> str: + """ + >>> from pprint import pprint + >>> pprint(_shorten_ipv6_adress('20:03:00:00:00:00:00:00:01:92:01:68:00:00:00:01')) + 2003::192:168:0:1 + """ + # '20:03:00:00:00:00:00:00:01:92:01:68:00:00:00:01' + address = address.split(':') + span = 2 + address = [''.join(address[i:i + span]) for i in range(0, len(address), span)] + # ['2003', '0000', '0000', '0000', '0192', '0168', '0000', '0001'] + for m in range(0, len(address)): + address[m] = re.sub(r'^0{1,3}', r'', address[m]) + # ['2003', '0', '0', '0', '192', '168', '0', '1'] + address = ':'.join(address) + # '2003:0:0:0:192:168:0:1' + zeros = ':0:0:0:0:0:0:' + while not zeros == '': + if zeros in address: + address = address.replace(zeros, '::', 1) + zeros = '' + else: + zeros = zeros[:-2] + if address == '0::0': + address = '::' + # '2003::192:168:0:1' + return address + + +def render_ipv6_address(bytestring) -> str: + address = ':'.join([f'{hex(ord(m))[2:]:0>2}' for m in bytestring]).replace(' ', '0').upper() + address = _shorten_ipv6_adress(address) + + return address + + +def ospf_stub_router_advertisement(st: str) -> str: + names = { + '1': 'do Not Advertise', + '2': 'advertise', + } + return names.get(st, st) + + +def ospf_exit_reason(st: str) -> str: + names = { + '1': 'none', + '2': 'in Progress', + '3': 'completed', + '4': 'timed Out', + '5': 'topology Changed', + } + return names.get(st, st) + + +def ospf_restart_status(st: str) -> str: + names = { + '1': 'not Restarting', + '2': 'planned Restart', + '3': 'unplanned Restart', + } + return names.get(st, st) + + +def ospf_restart_support(st: str) -> str: + names = { + '1': 'none', + '2': 'planned Only', + '3': 'planned And Unplanned', + } + return names.get(st, st) + + +def ospf_admin_status(st: str) -> str: + names = { + '1': 'enabled', + '2': 'disabled', + } + return names.get(st, st) + + +def ospf_abr_asbr_status(st: str) -> str: + names = { + '1': 'yes', + '2': 'no', + } + return names.get(st, st) + + +def ospf_stub_router_support(st: str) -> str: + names = { + '1': 'yes', + '2': 'no', + } + return names.get(st, st) + + +def ospf_area_impotasextern(st: str) -> str: + names = { + '1': 'import External', + '2': 'import no External', + '3': 'import Nssa', + } + return names.get(st, st) + + +def ospf_area_summary(st: str) -> str: + names = { + '1': 'no Area Summary', + '2': 'send Area Summary', + } + return names.get(st, st) + + +def ospf_area_translatorrole(st: str) -> str: + names = { + '1': 'always', + '2': 'candidate', + } + return names.get(st, st) + + +def ospf_area_translatorrolestate(st: str) -> str: + names = { + '1': 'enabled', + '2': 'elected', + '3': 'disabled', + } + return names.get(st, st) + + +def ospf_area_submetrictype(st: str) -> str: + names = { + '1': 'ospfv3 Metric', + '2': 'comparable Cost', + '3': 'non Comparable', + } + return names.get(st, st) + + +def ospf_area_teeenabled(st: str) -> str: + names = { + '1': 'enabled', + } + return names.get(st, 'disabled') + + +def ospf_if_type(st: str) -> str: + names = { + '1': 'broadcast', + '2': 'nbma', + '3': 'pointToPoint', + '5': 'pointToMultipoint', + } + return names.get(st, st) + + +def ospf_if_admin_status(st: str) -> str: + names = { + '1': 'enabled', + '2': 'disabled', + } + return names.get(st, st) + + +def ospf_if_state(st: str) -> str: + names = { + '1': 'down', + '2': 'loopback', + '3': 'waiting', + '4': 'P2P', + '5': 'DR', + '6': 'BDR', + '7': 'other DR', + '8': 'standby', + } + return names.get(st, st) + + +def ospf_nbr_state(st: int) -> str: + names = { + 1: 'down', + 2: 'attempt', + 3: 'init', + 4: 'twoWay', + 5: 'exchangeStart', + 6: 'exchange', + 7: 'loading', + 8: 'full', + } + return names.get(st, st) + + +def ospf_nbr_addresstype(st: str) -> str: + names = { + '0': 'unknown', + '1': 'ipv4', + '2': 'ipv6', + '3': 'ipv4z', + '4': 'ipv6z', + '16': 'dns', + } + return names.get(st, st) + + +def ospf_nbr_hellosuppressed(st: str) -> str: + names = { + '1': 'true', + '2': 'false', + } + return names.get(st, st) + + +def ospf_nbr_helperstatus(st: str) -> str: + names = { + '1': 'not Helping', + '2': 'helping', + } + return names.get(st, st) + + +def ospf_nbr_helperexitreason(st: str) -> str: + names = { + '1': 'none', + '2': 'inProgress', + '3': 'completed', + '4': 'timedOut', + '5': 'topologyChanged', + } + return names.get(st, st) diff --git a/ospfv3.mkp b/ospfv3.mkp index 8fef4840fb4ed39cef766c46040cb98b66d7b03a..e46832ab2faabdf1ed8b4d742e190900e05650fa 100644 Binary files a/ospfv3.mkp and b/ospfv3.mkp differ diff --git a/packages/ospfv3 b/packages/ospfv3 index 5747a4d43c495823a20f07a5acfc6e0fe6e8a343..5ac9a2f96fac658de96e3b922bb343794d219c6c 100644 --- a/packages/ospfv3 +++ b/packages/ospfv3 @@ -5,10 +5,11 @@ 'ospfv3_general.py', 'ospfv3_interface.py', 'ospfv3_neighbor.py', - 'ospfv3_virtuallink.py'], + 'ospfv3_virtuallink.py', + 'utils/ospfv3.py'], 'web': ['plugins/metrics/ospfv3.py']}, 'name': 'ospfv3', - 'num_files': 6, + 'num_files': 7, 'title': 'Collection of OSPFv3 checks', 'version': '20210917.v0.2', 'version.min_required': '2.0.0', diff --git a/web/plugins/metrics/ospfv3.py b/web/plugins/metrics/ospfv3.py index 75b5e6a6e220f12a89911c98703e4b0139e56107..58e9e6c1a9b267bb1691554075eb4072a139cb28 100644 --- a/web/plugins/metrics/ospfv3.py +++ b/web/plugins/metrics/ospfv3.py @@ -7,7 +7,7 @@ # URL : https://thl-cmk.hopto.org # Date : 2019-11-02 # -# Cisco OSPFv3 metrics plugin +# OSPFv3 metrics plugin # from cmk.gui.i18n import _