diff --git a/bin/cmk-broker-test b/bin/cmk-broker-test index d6cee41b758..30f5a5e452b 100755 --- a/bin/cmk-broker-test +++ b/bin/cmk-broker-test @@ -92,7 +92,7 @@ def _callback_pong( def _command_pong() -> int: write("Establishing connection to local broker\n") - with Connection(APP_NAME, omd_root) as conn: + with Connection(APP_NAME, omd_root, omd_site()) as conn: channel = conn.channel(TestMessage) channel.queue_declare(queue=QUEUE_PING) write("Waiting for messages\n") @@ -128,7 +128,7 @@ def _make_callback_ping( def _command_ping(site_id: str) -> int: write("Establishing connection to local broker\n") - with Connection(APP_NAME, omd_root) as conn: + with Connection(APP_NAME, omd_root, omd_site()) as conn: channel = conn.channel(TestMessage) channel.queue_declare(queue=QUEUE_PONG) diff --git a/cmk/gui/wato/pages/sites.py b/cmk/gui/wato/pages/sites.py index c30eb4de7c8..2f330d80ebc 100644 --- a/cmk/gui/wato/pages/sites.py +++ b/cmk/gui/wato/pages/sites.py @@ -1335,7 +1335,9 @@ def _get_connection_status_icon_message( "The configuration checks against the local site" ) else: - connection_status = check_remote_connection(omd_root, remote_host, remote_port) + connection_status = check_remote_connection( + omd_root, remote_host, remote_port, site["id"] + ) except (MKTerminate, MKTimeout): raise except Exception as e: diff --git a/cmk/gui/watolib/piggyback_hub.py b/cmk/gui/watolib/piggyback_hub.py index c6d27a40984..62ed598a88e 100644 --- a/cmk/gui/watolib/piggyback_hub.py +++ b/cmk/gui/watolib/piggyback_hub.py @@ -7,6 +7,8 @@ from livestatus import SiteConfiguration, SiteId +from cmk.ccc.site import omd_site + from cmk.utils.hostaddress import HostName from cmk.utils.paths import omd_root @@ -42,7 +44,9 @@ def distribute_piggyback_hub_configs( dirty_sites: Collection[SiteId], # only needed in CME case. hosts_sites: Mapping[HostName, SiteId], ) -> None: - distribute_config(compute_new_config(global_settings, configured_sites, hosts_sites), omd_root) + distribute_config( + compute_new_config(global_settings, configured_sites, hosts_sites), omd_root, omd_site() + ) def compute_new_config( diff --git a/cmk/piggyback/hub/config.py b/cmk/piggyback/hub/config.py index cfe2234d373..f00a65aeecd 100644 --- a/cmk/piggyback/hub/config.py +++ b/cmk/piggyback/hub/config.py @@ -66,8 +66,10 @@ def load_config(paths: PiggybackHubPaths) -> PiggybackHubConfig: return PiggybackHubConfig(targets=persisted.targets) -def distribute_config(configs: Mapping[str, PiggybackHubConfig], omd_root: Path) -> None: +def distribute_config( + configs: Mapping[str, PiggybackHubConfig], omd_root: Path, omd_site: str +) -> None: for site_id, config in configs.items(): - with Connection(APP_NAME, omd_root) as conn: + with Connection(APP_NAME, omd_root, omd_site) as conn: channel = conn.channel(PiggybackHubConfig) channel.publish_for_site(site_id, config, routing=CONFIG_ROUTE) diff --git a/cmk/piggyback/hub/main.py b/cmk/piggyback/hub/main.py index c34a8d39a12..179094f65ad 100644 --- a/cmk/piggyback/hub/main.py +++ b/cmk/piggyback/hub/main.py @@ -42,6 +42,7 @@ class Arguments: pid_file: str log_file: str omd_root: str + omd_site: str def _parse_arguments(argv: list[str]) -> Arguments: @@ -63,6 +64,7 @@ def _parse_arguments(argv: list[str]) -> Arguments: parser.add_argument("pid_file", help="Path to the PID file") parser.add_argument("log_file", help="Path to the log file") parser.add_argument("omd_root", help="Site root path") + parser.add_argument("omd_site", help="Site name") args = parser.parse_args(argv[1:]) return Arguments( @@ -72,6 +74,7 @@ def _parse_arguments(argv: list[str]) -> Arguments: pid_file=args.pid_file, log_file=args.log_file, omd_root=args.omd_root, + omd_site=args.omd_site, ) @@ -93,13 +96,14 @@ def _setup_logging(args: Arguments) -> logging.Logger: def run_piggyback_hub( - logger: logging.Logger, omd_root: Path, crash_report_callback: Callable[[], str] + logger: logging.Logger, omd_root: Path, omd_site: str, crash_report_callback: Callable[[], str] ) -> int: reload_config = make_event() processes = ( ReceivingProcess( logger, omd_root, + omd_site, PiggybackPayload, save_payload_on_message(logger, omd_root), crash_report_callback, @@ -110,6 +114,7 @@ def run_piggyback_hub( ReceivingProcess( logger, omd_root, + omd_site, PiggybackHubConfig, save_config_on_message(logger, omd_root, reload_config), crash_report_callback, @@ -164,7 +169,7 @@ def dummy_crash_report(): try: with pid_file_lock(Path(args.pid_file)): - return run_piggyback_hub(logger, omd_root, crash_report_callback) + return run_piggyback_hub(logger, omd_root, args.omd_site, crash_report_callback) except Exception as exc: if args.debug: raise diff --git a/cmk/piggyback/hub/payload.py b/cmk/piggyback/hub/payload.py index 2ae9e6d4902..3656bf1d885 100644 --- a/cmk/piggyback/hub/payload.py +++ b/cmk/piggyback/hub/payload.py @@ -95,7 +95,7 @@ def run(self): failed_message = None try: while True: - with make_connection(self.omd_root, self.logger, self.task_name) as conn: + with make_connection(self.omd_root, self.site, self.logger, self.task_name) as conn: try: channel = conn.channel(PiggybackPayload) if failed_message is not None: diff --git a/cmk/piggyback/hub/utils.py b/cmk/piggyback/hub/utils.py index 711cb5b2388..21fad5b59a8 100644 --- a/cmk/piggyback/hub/utils.py +++ b/cmk/piggyback/hub/utils.py @@ -36,6 +36,7 @@ def __init__( self, logger: logging.Logger, omd_root: Path, + site: str, model: type[_ModelT], callback: Callable[[Channel[_ModelT], DeliveryTag, _ModelT], None], crash_report_callback: Callable[[], str], @@ -45,6 +46,7 @@ def __init__( super().__init__() self.logger = logger self.omd_root = omd_root + self.site = site self.model = model self.callback = callback self.crash_report_callback = crash_report_callback @@ -60,7 +62,7 @@ def run(self) -> None: ) try: while True: - with make_connection(self.omd_root, self.logger, self.task_name) as conn: + with make_connection(self.omd_root, self.site, self.logger, self.task_name) as conn: try: channel: Channel[_ModelT] = conn.channel(self.model) channel.queue_declare(queue=self.queue, message_ttl=self.message_ttl) @@ -80,14 +82,16 @@ def run(self) -> None: raise -def make_connection(omd_root: Path, logger: logging.Logger, task_name: str) -> Connection: +def make_connection( + omd_root: Path, omd_site: str, logger: logging.Logger, task_name: str +) -> Connection: retry_during_presumed_broker_restart = itertools.repeat(3, 20) retry_forever = itertools.repeat(60) for interval in itertools.chain(retry_during_presumed_broker_restart, retry_forever): try: # Note: We re-read the certificates here. - return Connection(APP_NAME, omd_root) + return Connection(APP_NAME, omd_root, omd_site) except ( # Certs could have changed SSLCertVerificationError, diff --git a/omd/packages/check_mk/skel/etc/init.d/piggyback-hub b/omd/packages/check_mk/skel/etc/init.d/piggyback-hub index 593ae7b355c..23959769e41 100755 --- a/omd/packages/check_mk/skel/etc/init.d/piggyback-hub +++ b/omd/packages/check_mk/skel/etc/init.d/piggyback-hub @@ -61,7 +61,7 @@ case "$1" in exit_with_code 0 'already running.' fi - if "$DAEMON" "$PIDFILE" "$LOGFILE" "$OMD_ROOT"; then + if "$DAEMON" "$PIDFILE" "$LOGFILE" "$OMD_ROOT" "$OMD_SITE"; then exit_with_code 0 'OK' else exit_with_code 1 'failed' diff --git a/packages/cmk-messaging/cmk/messaging/_config.py b/packages/cmk-messaging/cmk/messaging/_config.py index b866ea5d0ae..fe615556fbf 100644 --- a/packages/cmk-messaging/cmk/messaging/_config.py +++ b/packages/cmk-messaging/cmk/messaging/_config.py @@ -142,13 +142,13 @@ def multisite_cert_file(omd_root: Path, site: str) -> Path: def make_connection_params( - omd_root: Path, server: str, port: int, connection_name: str + omd_root: Path, server: str, port: int, omd_site: str, connection_name: str ) -> pika.ConnectionParameters: client_props: dict[str, str] = {"connection_name": connection_name} return pika.ConnectionParameters( host=server, port=port, - ssl_options=pika.SSLOptions(_make_ssl_context(omd_root)), + ssl_options=pika.SSLOptions(_make_ssl_context(omd_root), omd_site), credentials=pika.credentials.ExternalCredentials(), heartbeat=0, blocked_connection_timeout=300, @@ -158,7 +158,7 @@ def make_connection_params( def _make_ssl_context(omd_root: Path) -> ssl.SSLContext: context = ssl.create_default_context(cafile=trusted_cas_file(omd_root)) - context.check_hostname = False # the host name in the cert is the site name, not the server. + context.check_hostname = True context.verify_mode = ssl.CERT_REQUIRED context.load_cert_chain(site_cert_file(omd_root), site_key_file(omd_root)) return context diff --git a/packages/cmk-messaging/cmk/messaging/_connection.py b/packages/cmk-messaging/cmk/messaging/_connection.py index ff9f6e1779d..b2914c1cfc5 100644 --- a/packages/cmk-messaging/cmk/messaging/_connection.py +++ b/packages/cmk-messaging/cmk/messaging/_connection.py @@ -291,7 +291,7 @@ class Connection: ```python - with Connection(AppName("myapp"), Path("/omd/sites/mysite")) as conn: + with Connection(AppName("myapp"), Path("/omd/sites/mysite"), "mysite") as conn: channel = conn.channel(MyMessageModel) channel.publish_for_site("other_site", my_message_instance, RoutintKey("my_routing")) @@ -301,7 +301,7 @@ class Connection: ```python - with Connection(AppName("myapp"), Path("/omd/sites/mysite")) as conn: + with Connection(AppName("myapp"), Path("/omd/sites/mysite"), "mysite") as conn: channel = conn.channel(MyMessageModel) channel.queue_declare(QueueName("default")) # includes default binding channel.consume(my_message_handler_callback) @@ -313,12 +313,14 @@ class Connection: ```python - with Connection(AppName("myapp"), Path("/omd/sites/mysite"), "my-connection") as conn: + with Connection(AppName("myapp"), Path("/omd/sites/mysite"), , "mysite", "my-connection") as conn: ... """ - def __init__(self, app: AppName, omd_root: Path, connection_name: str | None = None) -> None: + def __init__( + self, app: AppName, omd_root: Path, omd_site: str, connection_name: str | None = None + ) -> None: """Create a connection for a specific app""" self.app: Final = app self._omd_root = omd_root @@ -328,6 +330,7 @@ def __init__(self, app: AppName, omd_root: Path, connection_name: str | None = N omd_root, "localhost", get_local_port(), + omd_site, connection_name if connection_name else app.value, ) ) @@ -360,7 +363,7 @@ def __exit__( def check_remote_connection( - omd_root: Path, server: str, port: int + omd_root: Path, server: str, port: int, omd_site: str ) -> ConnectionOK | ConnectionFailed: """ Check if a connection to a remote message broker can be established @@ -369,11 +372,14 @@ def check_remote_connection( omd_root: The OMD root path of the site to connect from server: Hostname or IP Address to connect to port: The message broker port to connect to + omd_site: The site id to connect to """ try: with pika.BlockingConnection( - make_connection_params(omd_root, server, port, f"check-connection-from-{omd_root.name}") + make_connection_params( + omd_root, server, port, omd_site, f"check-connection-from-{omd_root.name}" + ) ): return ConnectionOK() except AMQPConnectionError as exc: @@ -383,10 +389,15 @@ def check_remote_connection( else ConnectionFailed(str(exc)) ) except ssl.SSLError as exc: - return ( - ConnectionFailed("Invalid certificates") - if "certificate verify failed" in repr(exc).lower() - else ConnectionFailed(str(exc)) - ) + msg = repr(exc).lower() + if "hostname mismatch" in msg: + return ConnectionFailed( + "Hostname mismatch. You are probably connecting to the wrong site." + ) + elif "certificate verify failed" in msg: + return ConnectionFailed("Certificate verify failed") + + return ConnectionFailed(str(exc)) + except (socket.gaierror, RuntimeError) as exc: return ConnectionFailed(str(exc))