mongo-charms-single-kernel 1.8.8__py3-none-any.whl → 1.8.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of mongo-charms-single-kernel might be problematic. Click here for more details.

Files changed (28) hide show
  1. {mongo_charms_single_kernel-1.8.8.dist-info → mongo_charms_single_kernel-1.8.9.dist-info}/METADATA +1 -1
  2. {mongo_charms_single_kernel-1.8.8.dist-info → mongo_charms_single_kernel-1.8.9.dist-info}/RECORD +27 -27
  3. single_kernel_mongo/config/literals.py +7 -0
  4. single_kernel_mongo/config/relations.py +2 -1
  5. single_kernel_mongo/config/statuses.py +127 -20
  6. single_kernel_mongo/core/operator.py +7 -0
  7. single_kernel_mongo/core/structured_config.py +2 -0
  8. single_kernel_mongo/core/workload.py +10 -4
  9. single_kernel_mongo/events/cluster.py +5 -0
  10. single_kernel_mongo/events/sharding.py +3 -1
  11. single_kernel_mongo/events/tls.py +183 -157
  12. single_kernel_mongo/exceptions.py +0 -8
  13. single_kernel_mongo/lib/charms/tls_certificates_interface/v4/tls_certificates.py +1995 -0
  14. single_kernel_mongo/managers/cluster.py +70 -28
  15. single_kernel_mongo/managers/config.py +14 -8
  16. single_kernel_mongo/managers/mongo.py +1 -1
  17. single_kernel_mongo/managers/mongodb_operator.py +44 -22
  18. single_kernel_mongo/managers/mongos_operator.py +16 -20
  19. single_kernel_mongo/managers/sharding.py +154 -127
  20. single_kernel_mongo/managers/tls.py +223 -206
  21. single_kernel_mongo/state/charm_state.py +39 -16
  22. single_kernel_mongo/state/cluster_state.py +8 -0
  23. single_kernel_mongo/state/config_server_state.py +9 -0
  24. single_kernel_mongo/state/tls_state.py +39 -12
  25. single_kernel_mongo/utils/helpers.py +4 -19
  26. single_kernel_mongo/lib/charms/tls_certificates_interface/v3/tls_certificates.py +0 -2123
  27. {mongo_charms_single_kernel-1.8.8.dist-info → mongo_charms_single_kernel-1.8.9.dist-info}/WHEEL +0 -0
  28. {mongo_charms_single_kernel-1.8.8.dist-info → mongo_charms_single_kernel-1.8.9.dist-info}/licenses/LICENSE +0 -0
@@ -105,6 +105,9 @@ class ClusterProvider(Object):
105
105
  if int_tls_ca := self.state.tls.get_secret(label_name=SECRET_CA_LABEL, internal=True):
106
106
  relation_data[ClusterStateKeys.INT_CA_SECRET.value] = int_tls_ca
107
107
 
108
+ if ext_tls_ca := self.state.tls.get_secret(label_name=SECRET_CA_LABEL, internal=False):
109
+ relation_data[ClusterStateKeys.EXT_CA_SECRET.value] = ext_tls_ca
110
+
108
111
  if hashed_data := self.dependent.ldap_manager.get_hash():
109
112
  relation_data[ClusterStateKeys.LDAP_HASH.value] = hashed_data
110
113
 
@@ -253,19 +256,19 @@ class ClusterRequirer(Object):
253
256
 
254
257
  def assert_pass_hook_checks(self) -> None:
255
258
  """Runs pre-hook checks, raises if one fails."""
256
- mongos_has_tls, config_server_has_tls = self.tls_status()
257
- match (mongos_has_tls, config_server_has_tls):
259
+ mongos_peer_tls, config_server_peer_tls = self.mongos_and_config_server_peer_tls_status()
260
+ match (mongos_peer_tls, config_server_peer_tls):
258
261
  case False, True:
259
262
  raise DeferrableFailedHookChecksError(
260
- "Config-Server uses TLS but mongos does not. Please synchronise encryption method."
263
+ "Config-Server uses peer TLS but mongos does not. Please synchronise encryption method."
261
264
  )
262
265
  case True, False:
263
266
  raise DeferrableFailedHookChecksError(
264
- "Mongos uses TLS but config-server does not. Please synchronise encryption method."
267
+ "Mongos uses peer TLS but config-server does not. Please synchronise encryption method."
265
268
  )
266
269
  case _:
267
270
  pass
268
- if self.is_waiting_to_request_certs():
271
+ if self.dependent.tls_manager.is_waiting_for_a_cert():
269
272
  raise DeferrableFailedHookChecksError(
270
273
  "Mongos was waiting for config-server to enable TLS. Wait for TLS to be enabled until starting mongos."
271
274
  )
@@ -431,10 +434,10 @@ class ClusterRequirer(Object):
431
434
  with MongoConnection(self.state.mongo_config) as mongo:
432
435
  mongo.drop_user(mongo.config.username)
433
436
 
434
- def is_ca_compatible(self) -> bool:
435
- """Returns true if both the mongos and the config-server use the same CA.
437
+ def is_peer_ca_compatible(self) -> bool:
438
+ """Returns true if both the mongos and the config-server use the same peer CA.
436
439
 
437
- Using the same CA is a requirement for sharded clusters.
440
+ Using the same peer CA is a requirement for sharded clusters.
438
441
  """
439
442
  if not self.state.mongos_cluster_relation:
440
443
  return True
@@ -445,38 +448,77 @@ class ClusterRequirer(Object):
445
448
 
446
449
  return config_server_tls_ca == mongos_tls_ca
447
450
 
448
- def is_waiting_to_request_certs(self) -> bool:
449
- """Returns True if mongos has been waiting for config server in order to request certs."""
450
- if not self.state.tls_relation:
451
- return False
452
- mongos_tls_ca = self.state.tls.get_secret(internal=True, label_name=SECRET_CA_LABEL)
451
+ def is_client_ca_compatible(self) -> bool:
452
+ """Returns true if both the mongos and the config-server use the same client CA.
453
453
 
454
- # our CA is none until certs have been requested. We cannot request certs until integrated
455
- # to config-server.
456
- return not mongos_tls_ca
454
+ Using the same client CA is a requirement for sharded clusters.
455
+ """
456
+ if not self.state.mongos_cluster_relation:
457
+ return True
458
+ config_server_tls_ca = self.state.cluster.external_ca_secret
459
+ mongos_tls_ca = self.state.tls.get_secret(internal=False, label_name=SECRET_CA_LABEL)
460
+ if not config_server_tls_ca or not mongos_tls_ca:
461
+ return True
457
462
 
458
- def tls_status(self) -> tuple[bool, bool]:
459
- """Returns the TLS integration status for mongos and config-server."""
463
+ return config_server_tls_ca == mongos_tls_ca
464
+
465
+ def mongos_and_config_server_peer_tls_status(self) -> tuple[bool, bool]:
466
+ """Returns the peer TLS integration status for mongos and config-server."""
460
467
  if self.state.mongos_cluster_relation:
461
- mongos_has_tls = self.state.tls_relation is not None
468
+ mongos_has_tls = self.state.peer_tls_relation is not None
462
469
  config_server_has_tls = self.state.cluster.internal_ca_secret is not None
463
470
  return mongos_has_tls, config_server_has_tls
464
471
 
465
472
  return False, False
466
473
 
467
- def get_tls_statuses(self) -> StatusObject | None:
468
- """Return statuses relevant to TLS."""
469
- mongos_has_tls, config_server_has_tls = self.tls_status()
470
- match (mongos_has_tls, config_server_has_tls):
474
+ def mongos_and_config_server_client_tls_status(self) -> tuple[bool, bool]:
475
+ """Returns the client TLS integration status for mongos and config-server."""
476
+ if self.state.mongos_cluster_relation:
477
+ mongos_has_tls = self.state.client_tls_relation is not None
478
+ config_server_has_tls = self.state.cluster.external_ca_secret is not None
479
+ return mongos_has_tls, config_server_has_tls
480
+
481
+ return False, False
482
+
483
+ def get_tls_status(self, internal: bool):
484
+ """Computes the TLS status for the scope.
485
+
486
+ Args:
487
+ internal: (bool) if true, represents the internal TLS, otherwise external TLS.
488
+ """
489
+ if internal:
490
+ shard_tls, config_server_tls = self.mongos_and_config_server_peer_tls_status()
491
+ is_ca_compatible = self.is_peer_ca_compatible()
492
+ else:
493
+ shard_tls, config_server_tls = self.mongos_and_config_server_client_tls_status()
494
+ is_ca_compatible = self.is_client_ca_compatible()
495
+
496
+ match (shard_tls, config_server_tls):
471
497
  case False, True:
472
- return MongosStatuses.MISSING_TLS_REL.value
498
+ logger.warning(
499
+ "Config-Server uses peer TLS but mongos does not. Please synchronise encryption method."
500
+ )
501
+ return MongosStatuses.missing_tls(internal=internal)
473
502
  case True, False:
474
- return MongosStatuses.INVALID_TLS_REL.value
503
+ logger.warning(
504
+ "Mongos uses peer TLS but config-server does not. Please synchronise encryption method."
505
+ )
506
+ return MongosStatuses.invalid_tls(internal=internal)
475
507
  case _:
476
508
  pass
477
- if not self.is_ca_compatible():
509
+
510
+ if not is_ca_compatible:
478
511
  logger.error(
479
- "mongos is integrated to a different CA than the config server. Please use the same CA for all cluster components."
512
+ "Mongos is integrated to a different CA than the config server. Please use the same CA for all cluster components."
480
513
  )
481
- return MongosStatuses.CA_MISMATCH.value
514
+ return MongosStatuses.incompatible_ca(internal=internal)
515
+
482
516
  return None
517
+
518
+ def tls_statuses(self) -> list[StatusObject]:
519
+ """Return statuses relevant to TLS."""
520
+ statuses = []
521
+ for internal in True, False:
522
+ if status := self.get_tls_status(internal=internal):
523
+ statuses.append(status)
524
+ return statuses
@@ -269,7 +269,7 @@ class MongoConfigManager(FileBasedConfigManager, ABC):
269
269
  self.binding_ips,
270
270
  self.port_parameter,
271
271
  self.auth_parameter,
272
- self.tls_parameters,
272
+ self.client_tls_parameters,
273
273
  self.log_options,
274
274
  self.audit_options,
275
275
  self.ldap_parameters,
@@ -332,16 +332,20 @@ class MongoConfigManager(FileBasedConfigManager, ABC):
332
332
  def auth_parameter(self) -> dict[str, Any]:
333
333
  """The auth mode."""
334
334
  cmd = {"security": {"authorization": "enabled"}} if self.auth else {}
335
- if self.state.tls.internal_enabled and self.state.tls.external_enabled:
335
+ if self.state.tls.peer_enabled:
336
336
  return always_merger.merge(
337
337
  cmd,
338
338
  {
339
339
  "security": {"clusterAuthMode": "x509"},
340
340
  "net": {
341
341
  "tls": {
342
+ "mode": "preferTLS",
342
343
  "allowInvalidCertificates": True,
343
- "clusterCAFile": f"{self.workload.paths.int_ca_file}",
344
+ "certificateKeyFile": f"{self.workload.paths.int_pem_file}",
345
+ "CAFile": f"{self.workload.paths.int_ca_file}",
346
+ "disabledProtocols": "TLS1_0,TLS1_1",
344
347
  "clusterFile": f"{self.workload.paths.int_pem_file}",
348
+ "clusterCAFile": f"{self.workload.paths.int_ca_file}",
345
349
  "clusterAuthX509": {
346
350
  "attributes": f"O={self.state.get_subject_name()}",
347
351
  },
@@ -360,10 +364,11 @@ class MongoConfigManager(FileBasedConfigManager, ABC):
360
364
  )
361
365
 
362
366
  @property
363
- def tls_parameters(self) -> dict[str, Any]:
364
- """The TLS external parameters."""
365
- if self.state.tls.external_enabled:
366
- return {
367
+ def client_tls_parameters(self) -> dict[str, Any]:
368
+ """The client TLS parameters."""
369
+ params = {}
370
+ if self.state.tls.client_enabled:
371
+ params = {
367
372
  "net": {
368
373
  "tls": {
369
374
  "CAFile": f"{self.workload.paths.ext_ca_file}",
@@ -373,7 +378,8 @@ class MongoConfigManager(FileBasedConfigManager, ABC):
373
378
  }
374
379
  },
375
380
  }
376
- return {}
381
+
382
+ return params
377
383
 
378
384
  @property
379
385
  @abstractmethod
@@ -530,7 +530,7 @@ class MongoManager(Object, ManagerStatusProtocol):
530
530
  return charm_statuses
531
531
 
532
532
  except ServerSelectionTimeoutError as e:
533
- # Usually it is du to ReplicaSetNoPrimary
533
+ # Usually it is due to ReplicaSetNoPrimary
534
534
  logger.debug(f"Got error {e} while checking replica set status")
535
535
  return [MongodStatuses.WAITING_ELECTION.value]
536
536
  except AutoReconnect as e:
@@ -33,7 +33,10 @@ from single_kernel_mongo.config.models import (
33
33
  PasswordManagementContext,
34
34
  PasswordManagementState,
35
35
  )
36
- from single_kernel_mongo.config.relations import ExternalRequirerRelations, RelationNames
36
+ from single_kernel_mongo.config.relations import (
37
+ ExternalRequirerRelations,
38
+ RelationNames,
39
+ )
37
40
  from single_kernel_mongo.config.statuses import (
38
41
  BackupStatuses,
39
42
  CharmStatuses,
@@ -47,7 +50,7 @@ from single_kernel_mongo.core.kubernetes_upgrades_v3 import KubernetesMongoDBRef
47
50
  from single_kernel_mongo.core.machine_upgrades_v3 import MachineMongoDBRefresh
48
51
  from single_kernel_mongo.core.operator import OperatorProtocol
49
52
  from single_kernel_mongo.core.secrets import generate_secret_label
50
- from single_kernel_mongo.core.structured_config import MongoDBRoles
53
+ from single_kernel_mongo.core.structured_config import MongoDBCharmConfig, MongoDBRoles
51
54
  from single_kernel_mongo.core.version_checker import VersionChecker
52
55
  from single_kernel_mongo.events.backups import BackupEventsHandler
53
56
  from single_kernel_mongo.events.cluster import ClusterConfigServerEventHandler
@@ -167,12 +170,7 @@ class MongoDBOperator(OperatorProtocol, Object):
167
170
  self.state,
168
171
  container,
169
172
  )
170
- self.tls_manager = TLSManager(
171
- self,
172
- self.workload,
173
- self.state,
174
- self.substrate,
175
- )
173
+ self.tls_manager = TLSManager(self, self.workload, self.state)
176
174
  self.mongo_manager = MongoManager(
177
175
  self,
178
176
  self.workload,
@@ -345,7 +343,8 @@ class MongoDBOperator(OperatorProtocol, Object):
345
343
  return
346
344
 
347
345
  @property
348
- def config(self):
346
+ @override
347
+ def config(self) -> MongoDBCharmConfig:
349
348
  """Returns the actual config."""
350
349
  return self.charm.parsed_config
351
350
 
@@ -393,6 +392,7 @@ class MongoDBOperator(OperatorProtocol, Object):
393
392
  return (
394
393
  self,
395
394
  self.mongo_manager,
395
+ self.tls_manager,
396
396
  self.shard_manager,
397
397
  self.config_server_manager,
398
398
  self.backup_manager,
@@ -487,7 +487,9 @@ class MongoDBOperator(OperatorProtocol, Object):
487
487
  except (NotReadyError, PyMongoError, WorkloadExecError) as e:
488
488
  logger.error(f"Deferring on start: error={e}")
489
489
  self.state.statuses.add(
490
- MongodStatuses.WAITING_REPL_SET_INIT.value, scope="unit", component=self.name
490
+ MongodStatuses.WAITING_REPL_SET_INIT.value,
491
+ scope="unit",
492
+ component=self.name,
491
493
  )
492
494
  raise
493
495
 
@@ -879,22 +881,17 @@ class MongoDBOperator(OperatorProtocol, Object):
879
881
  @override
880
882
  def update_status(self) -> None:
881
883
  """Status update Handler."""
882
- # TODO update the usage of this once the spec is approved and we have a consistent way of
883
- # handling statuses
884
884
  if self.basic_statuses():
885
885
  logger.info("Early return invalid statuses.")
886
886
  return
887
887
 
888
+ if self.state.is_role(MongoDBRoles.SHARD) and self._should_skip_because_of_incomplete_tls():
889
+ return
890
+
888
891
  if self.cluster_version_checker.get_cluster_mismatched_revision_status():
889
892
  logger.info("Early return, cluster mismatch version.")
890
893
  return
891
894
 
892
- if self.state.is_role(MongoDBRoles.SHARD):
893
- shard_has_tls, config_server_has_tls = self.shard_manager.tls_status()
894
- if config_server_has_tls and not shard_has_tls:
895
- logger.info("Shard is missing TLS.")
896
- return
897
-
898
895
  if not self.mongo_manager.mongod_ready():
899
896
  logger.info("Mongod not ready.")
900
897
  return
@@ -1055,7 +1052,9 @@ class MongoDBOperator(OperatorProtocol, Object):
1055
1052
  except WorkloadServiceError as e:
1056
1053
  logger.error("An exception occurred when starting mongod agent, error: %s.", str(e))
1057
1054
  self.charm.state.statuses.add(
1058
- MongoDBStatuses.WAITING_FOR_MONGODB_START.value, scope="unit", component=self.name
1055
+ MongoDBStatuses.WAITING_FOR_MONGODB_START.value,
1056
+ scope="unit",
1057
+ component=self.name,
1059
1058
  )
1060
1059
  raise
1061
1060
 
@@ -1075,7 +1074,9 @@ class MongoDBOperator(OperatorProtocol, Object):
1075
1074
  self.backup_manager.configure_and_restart()
1076
1075
  except WorkloadServiceError:
1077
1076
  self.state.statuses.add(
1078
- BackupStatuses.WAITING_FOR_PBM_START.value, scope="unit", component=self.name
1077
+ BackupStatuses.WAITING_FOR_PBM_START.value,
1078
+ scope="unit",
1079
+ component=self.name,
1079
1080
  )
1080
1081
  raise
1081
1082
 
@@ -1116,7 +1117,10 @@ class MongoDBOperator(OperatorProtocol, Object):
1116
1117
  logger.error("Charm is in sharding mode. Does not support %s interface.", rel_name)
1117
1118
  return MongoDBStatuses.INVALID_CFG_SRV_ON_SHARD_REL.value
1118
1119
  if self.state.is_role(MongoDBRoles.CONFIG_SERVER) and rel_name == RelationNames.SHARDING:
1119
- logger.error("Charm is in config-server mode. Does not support %s interface.", rel_name)
1120
+ logger.error(
1121
+ "Charm is in config-server mode. Does not support %s interface.",
1122
+ rel_name,
1123
+ )
1120
1124
  return MongoDBStatuses.INVALID_SHARD_ON_CFG_SRV_REL.value
1121
1125
  if not self.state.is_role(MongoDBRoles.CONFIG_SERVER) and rel_name == RelationNames.CLUSTER:
1122
1126
  logger.error("Charm is not a config-server, cannot integrate mongos")
@@ -1136,7 +1140,9 @@ class MongoDBOperator(OperatorProtocol, Object):
1136
1140
  self.build_local_tls_directory()
1137
1141
 
1138
1142
  # Push TLS files if necessary
1139
- self.tls_manager.push_tls_files_to_workload()
1143
+ for internal in [True, False]:
1144
+ self.tls_manager.push_tls_files_to_workload(internal)
1145
+
1140
1146
  self.ldap_manager.save_certificates(self.state.ldap.chain)
1141
1147
 
1142
1148
  # Update licenses
@@ -1354,3 +1360,19 @@ class MongoDBOperator(OperatorProtocol, Object):
1354
1360
  scope="app",
1355
1361
  component=self.name,
1356
1362
  )
1363
+
1364
+ def _should_skip_because_of_incomplete_tls(self) -> bool:
1365
+ """Checks if the update status hook needs skipping due to an incomplete TLS integration."""
1366
+ shard_has_peer_tls, config_server_has_peer_tls = (
1367
+ self.shard_manager.shard_and_config_server_peer_tls_status()
1368
+ )
1369
+ if config_server_has_peer_tls and not shard_has_peer_tls:
1370
+ logger.info("Shard is missing peer TLS.")
1371
+ return True
1372
+ shard_has_client_tls, config_server_has_client_tls = (
1373
+ self.shard_manager.shard_and_config_server_client_tls_status()
1374
+ )
1375
+ if config_server_has_client_tls and not shard_has_client_tls:
1376
+ logger.info("Shard is missing client TLS.")
1377
+ return True
1378
+ return False
@@ -104,12 +104,7 @@ class MongosOperator(OperatorProtocol, Object):
104
104
  self.state,
105
105
  self.substrate,
106
106
  )
107
- self.tls_manager = TLSManager(
108
- self,
109
- self.workload,
110
- self.state,
111
- self.substrate,
112
- )
107
+ self.tls_manager = TLSManager(self, self.workload, self.state)
113
108
  self.cluster_manager = ClusterRequirer(
114
109
  self, self.workload, self.state, self.substrate, RelationNames.CLUSTER
115
110
  )
@@ -201,9 +196,10 @@ class MongosOperator(OperatorProtocol, Object):
201
196
  @property
202
197
  def components(self) -> tuple[ManagerStatusProtocol, ...]:
203
198
  """The ordered list of components for this operator."""
204
- return (self, self.ldap_manager, self.upgrades_status_manager)
199
+ return (self, self.tls_manager, self.ldap_manager, self.upgrades_status_manager)
205
200
 
206
201
  @property
202
+ @override
207
203
  def config(self) -> MongosCharmConfig:
208
204
  """Returns the actual config."""
209
205
  return self.charm.parsed_config
@@ -222,8 +218,8 @@ class MongosOperator(OperatorProtocol, Object):
222
218
  # Instantiate the local directory for k8s
223
219
  self.build_local_tls_directory()
224
220
 
225
- # Push certificates
226
- self.tls_manager.push_tls_files_to_workload()
221
+ for internal in [True, False]:
222
+ self.tls_manager.push_tls_files_to_workload(internal)
227
223
 
228
224
  # Save LDAP certificates
229
225
  self.ldap_manager.save_certificates(self.state.ldap.chain)
@@ -301,8 +297,7 @@ class MongosOperator(OperatorProtocol, Object):
301
297
  component=self.name,
302
298
  )
303
299
  self.update_k8s_external_services()
304
-
305
- self.tls_manager.update_tls_sans()
300
+ self.tls_events.refresh_certificates()
306
301
  self.share_connection_info()
307
302
 
308
303
  @override
@@ -345,7 +340,7 @@ class MongosOperator(OperatorProtocol, Object):
345
340
  # our SANS as necessary.
346
341
  # The connection info will be updated when we receive the new certificates.
347
342
  if self.substrate == Substrates.K8S:
348
- self.tls_manager.update_tls_sans()
343
+ self.tls_events.refresh_certificates()
349
344
 
350
345
  @override
351
346
  def new_peer(self) -> None:
@@ -390,11 +385,10 @@ class MongosOperator(OperatorProtocol, Object):
390
385
  self.mongos_config_manager.configure_and_restart(force=force)
391
386
  except WorkloadServiceError as e:
392
387
  logger.error("An exception occurred when starting mongos agent, error: %s.", str(e))
393
- self.charm.status_handler.set_running_status(
388
+ self.charm.state.statuses.add(
394
389
  MongosStatuses.WAITING_FOR_MONGOS_START.value,
395
390
  scope="unit",
396
- statuses_state=self.state.statuses,
397
- component_name=self.name,
391
+ component=self.name,
398
392
  )
399
393
  raise
400
394
 
@@ -579,8 +573,9 @@ class MongosOperator(OperatorProtocol, Object):
579
573
  )
580
574
  return False
581
575
 
582
- if status := self.cluster_manager.get_tls_statuses():
583
- logger.info(f"Invalid TLS integration: {status.message}")
576
+ if statuses := self.cluster_manager.tls_statuses():
577
+ for status in statuses:
578
+ logger.info(f"Invalid TLS integration: {status.message}")
584
579
  return False
585
580
 
586
581
  if not self.is_mongos_running():
@@ -618,10 +613,11 @@ class MongosOperator(OperatorProtocol, Object):
618
613
  # don't bother checking remaining statuses if no config-server is present
619
614
  return charm_statuses
620
615
 
621
- if status := self.cluster_manager.get_tls_statuses():
622
- logger.info(f"Invalid TLS integration: {status.message}")
616
+ if statuses := self.cluster_manager.tls_statuses():
617
+ for status in statuses:
618
+ logger.info(f"Invalid TLS integration: {status.message}")
623
619
  # if TLS is misconfigured we will get redherrings on the remaining messages
624
- charm_statuses.append(status)
620
+ charm_statuses += statuses
625
621
  return charm_statuses
626
622
 
627
623
  if self.state.mongos_cluster_relation and not self.state.cluster.config_server_uri: