diff --git a/bgp_peer-2.0.1-20230611.mkp b/bgp_peer-2.0.1-20230611.mkp new file mode 100644 index 0000000000000000000000000000000000000000..322502aab47095cb19f46e0dcd836ddf4b8f97a3 Binary files /dev/null and b/bgp_peer-2.0.1-20230611.mkp differ diff --git a/bgp_peer-2.2.1-20230612.mkp b/bgp_peer-2.2.1-20230612.mkp new file mode 100644 index 0000000000000000000000000000000000000000..516ed8629448dc176edecabe4598ca217129752a Binary files /dev/null and b/bgp_peer-2.2.1-20230612.mkp differ diff --git a/gui/wato/bgp_peer.py b/gui/wato/bgp_peer.py new file mode 100644 index 0000000000000000000000000000000000000000..81489703db3d893e578d5d6cc06b47273a5f514c --- /dev/null +++ b/gui/wato/bgp_peer.py @@ -0,0 +1,250 @@ +#!/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 : 2017-12-25 +# +# Check_MK bgp_peers WATO plugin +# +# 2021-03-27: rewrite for CMK 2.0 +# 2021-08-21: modified for bgp_peer plugin (from cisco_bgp_peer) +# 2021-08-29: removed htmloutput and infotext_values option +# 2022-04-02: added bgp neighbour states +# 2022-04-29: added upper/lower prefix limit +# 2022-05-09: added discovery rule set +# 2022-05-11: added remote_as to build_item +# 2022-09-05: added internal_item to avoid warnings on cmk updates (THX to Jay2k1 for reporting the issue) + +from cmk.gui.i18n import _ +from cmk.gui.valuespec import ( + Dictionary, + Integer, + TextAscii, + ListOf, + Tuple, + TextUnicode, + MonitoringState, + ListChoice, +) + +from cmk.gui.plugins.wato.utils import ( + CheckParameterRulespecWithItem, + rulespec_registry, + RulespecGroupCheckParametersNetworking, + HostRulespec, + RulespecGroupCheckParametersDiscovery, +) + + +def _parameter_valuespec_bgp_peer(): + return Dictionary( + elements=[ + ('minuptime', + Tuple( + title=_('Minimum uptime for peer'), + orientation='horizontal', + help=_('Set the time in seconds, a peer must be up before the peer is considered sable.'), + elements=[ + Integer(title=_('Warning below'), unit='seconds', default_value=7200, minvalue=0), + Integer(title=_('Critical below'), unit='seconds', default_value=3600, minvalue=0) + ], + )), + ('accepted_prefixes_upper_levels', + Tuple( + title=_('Accepted prefixes upper levels'), + help=_('The values from WATO are preferred to the values from the device.'), + orientation='horizontal', + elements=[ + Integer(title=_('Warning at'), minvalue=0, unit=_('prefixes'), size=5), + Integer(title=_('Critical at'), minvalue=0, unit=_('prefixes'), size=5), + ], + )), + ('accepted_prefixes_lower_levels', + Tuple( + title=_('Accepted prefixes lower levels'), + orientation='horizontal', + elements=[ + Integer(title=_('Warning below'), minvalue=0, unit=_('prefixes'), size=5), + Integer(title=_('Critical below'), minvalue=0, unit=_('prefixes'), size=5), + ], + )), + ('peernotfound', + MonitoringState( + default_value=2, + title=_('State if peer is no not found.'), + help=_('Default monitoring state if the peer is not found in the SNMP data') + )), + ('admindown', + MonitoringState( + default_value=1, + title=_('State if peer is admin shutdown.'), + help=_('Monitoring state if the peer is admin shutdown') + )), + ('neighborstate', + Dictionary( + title=_('State to report for BGP neighbor state'), + help=_('Map each BGP state to a CheckMK monitoring state'), + elements=[ + ('1', + MonitoringState( + title=_('1 - idle'), + help=_( + 'This is the first stage of the BGP FSM. BGP detects a start event, tries to initiate a ' + 'TCP connection to the BGP peer, and also listens for a new connect from a peer router. ' + 'If an error causes BGP to go back to the Idle state for a second time, the ' + 'ConnectRetryTimer is set to 60 seconds and must decrement to zero before the connection ' + 'is initiated again. Further failures to leave the Idle state result in the ' + 'ConnectRetryTimer doubling in length from the previous time. ' + 'Default monitoring state is "CRIT"'), + default_value=2, + )), + ('2', + MonitoringState( + title=_('2 - connect'), + help=_( + 'In this state, BGP initiates the TCP connection. If the 3-way TCP handshake completes, ' + 'the established BGP Session BGP process resets the ConnectRetryTimer and sends the Open ' + 'message to the neighbor, and then changes to the OpenSent State.' + 'Default monitoring state is "WARN"'), + default_value=1, + )), + ('3', + MonitoringState( + title=_('3 - active'), + help=_('In this state, BGP starts a new 3-way TCP handshake. If a connection is established, ' + 'an Open message is sent, the Hold Timer is set to 4 minutes, and the state moves to ' + 'OpenSent. If this attempt for TCP connection fails, the state moves back to the Connect ' + 'state and resets the ConnectRetryTimer. ' + 'Default monitoring state is "WARN"'), + default_value=1, + )), + ('4', + MonitoringState( + title=_('4 - opensent'), + help=_( + 'In this state, an Open message has been sent from the originating router and is awaiting ' + 'an Open message from the other router. After the originating router receives the OPEN ' + 'message from the other router, both OPEN messages are checked for errors. If the Open ' + 'messages do not have any errors, the Hold Time is negotiated (using the lower value), ' + 'and a KEEPALIVE message is sent (assuming the value is not set to zero). The connection ' + 'state is then moved to OpenConfirm. If an error is found in the OPEN message, a ' + 'Notification message is sent, and the state is moved back to Idle.' + ' Default monitoring state is "WARN"'), + default_value=1, + )), + ('5', + MonitoringState( + title=_('5 - openconfirm'), + help=_('In this state, BGP waits for a Keepalive or Notification message. Upon receipt of a ' + 'neighbor’s Keepalive, the state is moved to Established. If the hold timer expires, a ' + 'stop event occurs, or a Notification message is received, and the state is moved to ' + 'Idle. ' + 'Default monitoring state is "WARN"'), + default_value=1, + )), + ('6', + MonitoringState( + title=_('6 - established'), + help=_( + 'In this state, the BGP session is established. BGP neighbors exchange routes via Update ' + 'messages. As Update and Keepalive messages are received, the Hold Timer is reset. If the ' + 'Hold Timer expires, an error is detected and BGP moves the neighbor back to the Idle ' + 'state. ' + 'Default monitoring state is "OK"'), + default_value=0, + )), + ])), + ('noprefixlimit', + MonitoringState( + default_value=1, + title=_('State if no admin prefix limit/warn threshold is configured.'), + help=_('The admin prefix limit and warn threshold needs to be configured on the device. ' + 'For example: "neighbor 172.17.10.10 maximum-prefix 10000 80". The threshold is in percentage ' + 'of the prefix limit.') + )), + ('peer_list', + ListOf( + Tuple( + orientation='horizontal', + elements=[ + TextUnicode( + title=_('BGP Peer'), + help=_('The configured value must match a BGP item reported by the monitored ' + 'device. For example: "10.194.115.98" or "2A10:1CD0:1020:135::20 IPv6 Unicast"'), + allow_empty=False, + size=50, + ), + TextUnicode( + title=_('BGP Peer Alias'), + help=_('You can configure an individual alias here for the BGP peer matching ' + 'the text configured in the "BGP Peer IP-address" field. The alias will ' + 'be shown in the check info'), + size=50, + ), + MonitoringState( + default_value=2, + title=_('State if not found'), + help=_('You can configure an individual state if the BGP peer matching the text ' + 'configured in the "BGP Peer IP-address" field is not found') + ), + ]), + add_label=_('Add BGP peer'), + movable=False, + title=_('BGP Peers'), + )), + ('internal_item', # added by plugin discovery function + TextUnicode()), + ], + hidden_keys=['internal_item'], + ) + + +rulespec_registry.register( + CheckParameterRulespecWithItem( + check_group_name='bgp_peer', + group=RulespecGroupCheckParametersNetworking, + item_spec=lambda: TextAscii(title=_('BGP peer'), ), + match_type='dict', + parameter_valuespec=_parameter_valuespec_bgp_peer, + title=lambda: _('BGP peer'), + )) + + +def _valuespec_discovery_bgp_peer(): + item_parts = [ + # ('remote_address', 'Peer remote address'), + ('remote_as', 'Remote AS'), + ('address_family', 'Address family'), + ('routing_instance', 'Routing instance/VRF'), + + ] + return Dictionary( + title=_('BGP peer'), + elements=[ + ('build_item', + ListChoice( + title=_('Information not to use in the item name'), + help=_( + 'The Peer remote address is always used as the item name. By default the check will add the ' + 'address-family and the routing instance/VRF if available. You can decide to not use these ' + 'additional information in the item name. Do so only if your peers have only one address-' + 'family configured and you don\'t have the same peer remote address in different routing ' + 'instances/VRFs configured.' + ), + choices=item_parts, + default_value=['remote_as'], + )), + ], + ) + + +rulespec_registry.register( + HostRulespec( + group=RulespecGroupCheckParametersDiscovery, + match_type='dict', + name='discovery_bgp_peer', + valuespec=_valuespec_discovery_bgp_peer, + )) diff --git a/gui/wato/inv_bgp_peer.py b/gui/wato/inv_bgp_peer.py new file mode 100644 index 0000000000000000000000000000000000000000..f4832c661908036a3d309eb0b9f13b8dcba7db90 --- /dev/null +++ b/gui/wato/inv_bgp_peer.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Author: thl-cmk[at]outlook[dot]com +# URL : https://thl-cmk.hopto.org +# Date : 2022-04-24 +# +# 2022-04-24: added option for BGP down time +# added option to remove some columns from inventory +# 2022-04-28: added Whois options + +from cmk.gui.i18n import _ +from cmk.gui.plugins.wato.utils import ( + HostRulespec, + rulespec_registry, +) +from cmk.gui.valuespec import ( + Dictionary, + ListChoice, + Age, + DropdownChoice, + Integer, +) + +from cmk.gui.plugins.wato.inventory import ( + RulespecGroupInventory, +) + + +def _valuespec_inv_bgp_peer(): + removecolumns = [ + # ('remote_as', 'Remote AS'), + # ('remote_id', 'Remote ID'), + # ('local_addr', 'Local address'), + # ('local_as', 'Local AS'), + # ('local_id', 'Local ID'), + ('address_family', 'Address family'), + ('last_error', 'Last error'), + ('last_error_code', 'Last error code'), + # ('prev_state', 'Previous state'), + ('as_name', 'Remote AS name'), + ('as_org_name', 'Remote AS Org Name'), + ('bgp_type', 'Type'), + ('version', 'Version'), + ] + + return Dictionary( + title=_('BGP peer'), + elements=[ + ('not_in_service_time', + Age( + title=_('Time peer is not up until considered not in service'), + default_value=2592000, # 30 days in seconds, + )), + ('remove_columns', + ListChoice( + title=_('List of columns to remove'), + help=_('Information to remove from inventory'), + choices=removecolumns, + default_value=[], + )), + ('whois_enable', + Dictionary( + title=_('Add whois data to the inventory'), + help=_( + 'The whois data will be fetched via RDAP from the registries. For this the the plugin tries to' + 'find the best registry via the RDAP bootstrap data from https://data.iana.org/rdap/asn.json.' + 'The query it self will go to the found registry via http(s). Note: the request might be get ' + 'redirected if there a different authoritative registry for the ASn' + ), + elements=[ + ('whois_rir', + DropdownChoice( + title='Preferred RIR to fetch whois data', + help=_( + 'This registry will be used if the plugin can not determine the authoritative registry ' + 'based on the bootstrap data.' + ), + choices=[ + ('afrinic', _('AFRINIC (https://rdap.afrinic.net/rdap)')), + ('apnic', _('APNIC (https://rdap.apnic.net)')), + ('arin', _('ARIN (https://rdap.arin.net/registry)')), + ('ripe', _('RIPE (https://rdap.db.ripe.net)')), + ('lacnic', _('LACNIC (https://rdap.apnic.net)')), + ] + )), + ('whois_timeout', + Integer( + title='Timeout for connections to RIRs', + help=_('The connection timeout for each whois request.'), + default_value=5, + minvalue=1, + unit=_('seconds'), + )), + ] + )), + ], + ) + + +rulespec_registry.register( + HostRulespec( + group=RulespecGroupInventory, + match_type='dict', + name='inv_parameters:inv_bgp_peer', + valuespec=_valuespec_inv_bgp_peer, + ))