Skip to content

Commit

Permalink
piggyback-hub: enable sitename verification
Browse files Browse the repository at this point in the history
Change-Id: I6e0fb5eb15679936eb38f95bcb5cde208d0a6080
  • Loading branch information
DavidGerva committed Jan 22, 2025
1 parent 68c2f9c commit a8e7863
Show file tree
Hide file tree
Showing 10 changed files with 55 additions and 27 deletions.
4 changes: 2 additions & 2 deletions bin/cmk-broker-test
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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)

Expand Down
4 changes: 3 additions & 1 deletion cmk/gui/wato/pages/sites.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
6 changes: 5 additions & 1 deletion cmk/gui/watolib/piggyback_hub.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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(
Expand Down
6 changes: 4 additions & 2 deletions cmk/piggyback/hub/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
9 changes: 7 additions & 2 deletions cmk/piggyback/hub/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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(
Expand All @@ -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,
)


Expand All @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion cmk/piggyback/hub/payload.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
10 changes: 7 additions & 3 deletions cmk/piggyback/hub/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion omd/packages/check_mk/skel/etc/init.d/piggyback-hub
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
6 changes: 3 additions & 3 deletions packages/cmk-messaging/cmk/messaging/_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand Down
33 changes: 22 additions & 11 deletions packages/cmk-messaging/cmk/messaging/_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"))
Expand All @@ -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)
Expand All @@ -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
Expand All @@ -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,
)
)
Expand Down Expand Up @@ -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
Expand All @@ -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:
Expand All @@ -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))

0 comments on commit a8e7863

Please sign in to comment.