From d4092c1f9e2ee0ec296f6eb4fe466e503c082a40 Mon Sep 17 00:00:00 2001 From: "th.l" <thl-cmk@outlook.com> Date: Mon, 23 Dec 2024 17:22:19 +0100 Subject: [PATCH] fixed handling of anchors --- README.md | 2 +- mkp/bgp_topology-0.0.2-20241223.mkp | Bin 0 -> 9178 bytes .../bgp_topology/constants.py | 9 +- .../bgp_topology/lib/bgp_topology.py | 217 +++++++----------- .../server_side_calls/bgp_topology.py | 1 + source/packages/bgp_topology | 2 +- 6 files changed, 87 insertions(+), 144 deletions(-) create mode 100644 mkp/bgp_topology-0.0.2-20241223.mkp diff --git a/README.md b/README.md index 9e11d58..b3c8c04 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[PACKAGE]: ../../raw/master/mkp/bgp_topology-0.0.1-20240722.mkp "bgp_topology-0.0.1-20240722.mkp" +[PACKAGE]: ../../raw/master/mkp/bgp_topology-0.0.2-20241223.mkp "bgp_topology-0.0.2-20241223.mkp" # Title A short description about the plugin diff --git a/mkp/bgp_topology-0.0.2-20241223.mkp b/mkp/bgp_topology-0.0.2-20241223.mkp new file mode 100644 index 0000000000000000000000000000000000000000..aab7e559ec5897b550f05275b7ade84e77783b3a GIT binary patch literal 9178 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 E1OLnj_y7O^ literal 0 HcmV?d00001 diff --git a/source/cmk_addons_plugins/bgp_topology/constants.py b/source/cmk_addons_plugins/bgp_topology/constants.py index 1213084..98a65ee 100644 --- a/source/cmk_addons_plugins/bgp_topology/constants.py +++ b/source/cmk_addons_plugins/bgp_topology/constants.py @@ -10,13 +10,17 @@ # 2024-07-16: copied from bgp_topology/lib/ruleset_names.py +__AUTHOR__ = 'thl-cmk[at]outlook[dot]com' +__URL__ = 'https://thl-cmk.hopto.org/gitlab/checkmk/vendor-independent/bgp_topology' +__USAGE__ = '~/local/lib/python3/cmk_addons/plugins/bgp_topology/libexec/check_bgp_topology --make-default' +__VERSION__ = '0.0.2-20241223' from typing import Final ARG_PARSER_ANCHOR: Final[str] = '--bgp-anchor' -ARG_PARSER_ANCHOR_AS: Final[str] = 'bgp-as' +ARG_PARSER_ANCHOR_AS: Final[str] = 'as' ARG_PARSER_ANCHOR_BOTH: Final[str] = 'both' -ARG_PARSER_ANCHOR_ID: Final[str] = 'bgp-id' +ARG_PARSER_ANCHOR_ID: Final[str] = 'id' ARG_PARSER_EMBLEM_AS: Final[str] = '--bgp-emblem-as' ARG_PARSER_EMBLEM_ID: Final[str] = '--bgp-emblem-id' ARG_PARSER_HOST: Final[str] = '--host' @@ -24,6 +28,7 @@ ARG_PARSER_MAKE_DEFAULT: Final[str] = '--make-default' ARG_PARSER_NONE: Final[str] = 'none' ARG_PARSER_SITES_EXCLUDE: Final[str] = '--exclude-sites' ARG_PARSER_SITES_INCLUDE: Final[str] = '--include-sites' +ARG_PARSER_DEBUG: Final[str] = '--debug' BGP_PEER_LOCAL_ADDR: Final[str] = 'local_addr' BGP_PEER_LOCAL_AS: Final[str] = 'local_as' diff --git a/source/cmk_addons_plugins/bgp_topology/lib/bgp_topology.py b/source/cmk_addons_plugins/bgp_topology/lib/bgp_topology.py index 76e4d0a..9b5f42d 100644 --- a/source/cmk_addons_plugins/bgp_topology/lib/bgp_topology.py +++ b/source/cmk_addons_plugins/bgp_topology/lib/bgp_topology.py @@ -9,30 +9,15 @@ # File : bgp_topology/lib/bgp_topology.py # 2024-07-20: moved to lib -> is now an active check +# 2024-12-23: moved arg parser to lib/args.py +# fixed handling of anchors -__AUTHOR__ = 'thl-cmk[at]outlook[dot]com' -__URL__ = 'https://thl-cmk.hopto.org/gitlab/checkmk/vendor-independent/bgp_topology' -__USAGE__ = '/local/lib/python3/cmk_addons/plugins/bgp_topology/libexec/check_bgp_topology --make-default' -__VERSION__ = '0.0.1-20240721' - -from argparse import ArgumentParser, Namespace, RawTextHelpFormatter from collections.abc import MutableMapping, MutableSequence, Sequence from dataclasses import dataclass from time import time_ns from cmk.agent_based.v2 import render from cmk_addons.plugins.bgp_topology.constants import ( - ARG_PARSER_ANCHOR, - ARG_PARSER_ANCHOR_AS, - ARG_PARSER_ANCHOR_BOTH, - ARG_PARSER_ANCHOR_ID, - ARG_PARSER_EMBLEM_AS, - ARG_PARSER_EMBLEM_ID, - ARG_PARSER_HOST, - ARG_PARSER_MAKE_DEFAULT, - ARG_PARSER_NONE, - ARG_PARSER_SITES_EXCLUDE, - ARG_PARSER_SITES_INCLUDE, BGP_PEER_LOCAL_ADDR, BGP_PEER_LOCAL_AS, BGP_PEER_LOCAL_ID, @@ -41,19 +26,20 @@ from cmk_addons.plugins.bgp_topology.constants import ( BGP_PEER_REMOTE_ID, BGP_PEER_STATE, BGP_PEER_UPTIME, - EMBLEM_BGP_AS, - EMBLEM_BGP_ID, METRIC_TIME_TAKEN, PARAM_BGP_EXT_ANCHOR_AS, PARAM_BGP_EXT_ANCHOR_BOTH, PARAM_BGP_EXT_ANCHOR_ID, TOPOLOGY_NAME, ) +from cmk_addons.plugins.bgp_topology.lib.args import ( + Params, + parse_arguments, +) from cmk_addons.plugins.bgp_topology.lib.utils import ( BASE_TOPO_PATH, LiveStatusConnection, Metric, - OMD_ROOT, TopoConnections, TopoObjects, add_dummy_topologies, @@ -67,16 +53,6 @@ from cmk_addons.plugins.bgp_topology.lib.utils import ( ) -class Params(Namespace): - bgp_anchor: str - make_default: bool = False - bgp_emblem_as: str = EMBLEM_BGP_AS - bgp_emblem_id: str = EMBLEM_BGP_ID - include_sites: Sequence[str] | None = None - exclude_sites: Sequence[str] | None = None - host: str = '' - - @dataclass(frozen=True) class BgpPeer: host: str @@ -104,7 +80,7 @@ class BgpPeer: value = None key: str | None = get_bgp_peer_clean_key(key) value: str | None = get_bgp_peer_clean_value(key, value) - if key is not None and value is not None: + if key is not None and value not in [None, '0.0.0.0']: bgp_peer[key] = value return cls( @@ -122,6 +98,51 @@ class BgpPeer: ) +def add_bgp_anchor( + bgp_anchor : str, + bgp_peer: BgpPeer, + objects: TopoObjects, + connections: TopoConnections, + emblem_as: str, + emblem_id: str, +): + ext_bgp_host_as: str | None = None + ext_bgp_host_id: str | None = None + if bgp_anchor in [ + PARAM_BGP_EXT_ANCHOR_BOTH, + PARAM_BGP_EXT_ANCHOR_AS, + ] and bgp_peer.remote_as is not None: + ext_bgp_host_as: str = f'BGP-AS: {bgp_peer.remote_as}' + objects.add_host( + host=ext_bgp_host_as, + link2core=False, + emblem=emblem_as, + ) + if bgp_anchor in [ + PARAM_BGP_EXT_ANCHOR_BOTH, + PARAM_BGP_EXT_ANCHOR_ID + ] and bgp_peer.remote_id is not None: + ext_bgp_host_id: str = f'BGP-ID: {bgp_peer.remote_id}' + objects.add_host( + host=ext_bgp_host_id, + link2core=False, + emblem=emblem_id + ) + connections.add_connection( + right=ext_bgp_host_id, + left=get_service(bgp_peer.host, bgp_peer.service), + left_state=bgp_peer.state + ) + if ext_bgp_host_as is not None: + connections.add_connection(ext_bgp_host_id, ext_bgp_host_as) + + if ext_bgp_host_as is not None and ext_bgp_host_id is None: + connections.add_connection( + right=get_service(bgp_peer.host, bgp_peer.service), + left=ext_bgp_host_as, + right_state=bgp_peer.state, + ) + def create_bgp_topology(params: Params | None) -> int: start_time = time_ns() @@ -151,10 +172,12 @@ def create_bgp_topology(params: Params | None) -> int: query: str = ( 'GET services\n' 'Columns: host_name state description long_plugin_output\n' - 'Filter: description ~ BGP peer\n' + 'Filter: description ~ BGP [Pp]eer\n' 'OutputFormat: python3\n' ) if (raw_bgp_peers := ls_connection.query(query=query)) is not None: + if params.debug: + print(raw_bgp_peers) bgp_peers: MutableSequence[BgpPeer] = [ BgpPeer.parse(host, state, service, raw_peer_data) for host, state, service, raw_peer_data in raw_bgp_peers ] @@ -170,18 +193,19 @@ def create_bgp_topology(params: Params | None) -> int: left_state=bgp_peer.state ) - if bgp_peer.local_address is not None: + if bgp_peer.local_address not in [None]: if bgp_peers_by_local_addr.get(bgp_peer.local_address) is None: bgp_peers_by_local_addr[bgp_peer.local_address]: MutableSequence[BgpPeer] = [] bgp_peers_by_local_addr[bgp_peer.local_address].append(bgp_peer) else: - bgp_peers_by_local_addr['0.0.0.0'].append(bgp_peer) + bgp_peers_by_local_addr['0.0.0.0'].append(bgp_peer) # find connections for bgp_peer in bgp_peers: if (peer_list := bgp_peers_by_local_addr.get(bgp_peer.remote_address)) is not None: for peer in peer_list: - if bgp_peer.local_as == peer.remote_as and bgp_peer.local_as is not None: + # local_as is not available in the built-in plugins + # if bgp_peer.local_as == peer.remote_as and bgp_peer.local_as is not None: if bgp_peer.local_id == peer.remote_id and bgp_peer.local_id is not None: if bgp_peer.local_address == peer.remote_address and bgp_peer.local_address is not None: connections.add_connection( @@ -194,42 +218,24 @@ def create_bgp_topology(params: Params | None) -> int: # if there is no peer_list the peer is either external (to checkmk) or the connection is not # established, so we have no local address or remote id else: - ext_bgp_host_as: str | None = None - ext_bgp_host_id: str | None = None - if bgp_anchor in [ - PARAM_BGP_EXT_ANCHOR_BOTH, - PARAM_BGP_EXT_ANCHOR_AS, - ] and bgp_peer.remote_as is not None: - ext_bgp_host_as: str = f'BGP-AS: {bgp_peer.remote_as}' - objects.add_host( - host=ext_bgp_host_as, - link2core=False, - emblem=emblem_as, - ) - if bgp_anchor in [ - PARAM_BGP_EXT_ANCHOR_BOTH, - PARAM_BGP_EXT_ANCHOR_ID - ] and bgp_peer.remote_id is not None: - ext_bgp_host_id: str = f'BGP-ID: {bgp_peer.remote_id}' - objects.add_host( - host=ext_bgp_host_id, - link2core=False, - emblem=emblem_id - ) - connections.add_connection( - right=ext_bgp_host_id, - left=get_service(bgp_peer.host, bgp_peer.service), - left_state=bgp_peer.state - ) - if ext_bgp_host_as is not None: - connections.add_connection(ext_bgp_host_id, ext_bgp_host_as) - - if ext_bgp_host_as is not None and ext_bgp_host_id is None: - connections.add_connection( - right=get_service(bgp_peer.host, bgp_peer.service), - left=ext_bgp_host_as, - right_state=bgp_peer.state, - ) + add_bgp_anchor( + bgp_anchor=bgp_anchor, + bgp_peer=bgp_peer, + objects=objects, + connections=connections, + emblem_as=emblem_as, + emblem_id=emblem_id, + ) + + for bgp_peer in bgp_peers_by_local_addr['0.0.0.0']: + add_bgp_anchor( + bgp_anchor=bgp_anchor, + bgp_peer=bgp_peer, + objects=objects, + connections=connections, + emblem_as=emblem_as, + emblem_id=emblem_id, + ) connections.topo_connections.sort() data_set = { @@ -270,75 +276,6 @@ def create_bgp_topology(params: Params | None) -> int: return 0 -def parse_arguments(argv: Sequence[str]) -> Params: - parser = ArgumentParser( - prog='bgp_topology', - formatter_class=RawTextHelpFormatter, - description=f"""Create BGP peer network topology for Checkmk""", - epilog=f""" -Example usage: -{OMD_ROOT}/{__USAGE__} - -Version: {__VERSION__} | Written by {__AUTHOR__} -for more information see: {__URL__} - """ - ) - parser.add_argument( - ARG_PARSER_ANCHOR, - choices=[ - ARG_PARSER_ANCHOR_BOTH, - ARG_PARSER_ANCHOR_AS, - ARG_PARSER_ANCHOR_ID, - ARG_PARSER_NONE, - ], - default=ARG_PARSER_ANCHOR_BOTH, - help='Anchor for external BGP objects (default: %(default)s).', - ) - parser.add_argument( - ARG_PARSER_EMBLEM_AS, - type=str, - default=EMBLEM_BGP_AS, - help='Emblem to use for BGP-AS objects (default: %(default)s).', - ) - parser.add_argument( - ARG_PARSER_EMBLEM_ID, - type=str, - default=EMBLEM_BGP_ID, - help='Emblem to use for BGP-ID objects (default: %(default)s).', - ) - parser.add_argument( - ARG_PARSER_MAKE_DEFAULT, - action='store_const', const=True, - default=False, - help='Make this topology the default (default: %(default)s).', - ) - parser.add_argument( - ARG_PARSER_HOST, - type=str, - help="""The name of the Checkmk host to which the plugin is attached. This is set -automatically by Checkmk. If a site filter is active, the host name is -appended to the subdirectory where the topology is stored (“BGP†becomes -“BGP_host_nameâ€). This way we can have more than one BGP topology without -overwriting each other.""", - ) - site_filter = parser.add_mutually_exclusive_group() - site_filter.add_argument( - ARG_PARSER_SITES_INCLUDE, - type=str, - nargs='+', - help=f"""List of Checkmk site names to include in the topology creation. -Can not used together with {ARG_PARSER_SITES_EXCLUDE}""", - ) - site_filter.add_argument( - ARG_PARSER_SITES_EXCLUDE, - type=str, - nargs='+', - help=f"""List of Checkmk site names to exclude from the topology creation. -Can not used together with {ARG_PARSER_SITES_INCLUDE}""", - ) - - return parser.parse_args(argv) - def main(argv: Sequence[str] | None = None) -> int: return create_bgp_topology(parse_arguments(argv=argv)) diff --git a/source/cmk_addons_plugins/bgp_topology/server_side_calls/bgp_topology.py b/source/cmk_addons_plugins/bgp_topology/server_side_calls/bgp_topology.py index 37baa8e..e023007 100644 --- a/source/cmk_addons_plugins/bgp_topology/server_side_calls/bgp_topology.py +++ b/source/cmk_addons_plugins/bgp_topology/server_side_calls/bgp_topology.py @@ -56,6 +56,7 @@ FILTER_SITES = ( tuple[Literal['include_sites'], Sequence[str]] ) + class BgpAnchorType: anchor_both: str = PARAM_BGP_EXT_ANCHOR_BOTH anchor_as: str = PARAM_BGP_EXT_ANCHOR_AS diff --git a/source/packages/bgp_topology b/source/packages/bgp_topology index 7ebfba5..acc7bf8 100644 --- a/source/packages/bgp_topology +++ b/source/packages/bgp_topology @@ -10,7 +10,7 @@ 'bgp_topology/graphing/bgp_topology.py']}, 'name': 'bgp_topology', 'title': 'BGP peer topology', - 'version': '0.0.1-20240722', + 'version': '0.0.2-20241223', 'version.min_required': '2.3.0b1', 'version.packaged': 'cmk-mkp-tool 0.2.0', 'version.usable_until': '2.4.0b1'} -- GitLab