mongo-charms-single-kernel 1.8.9__py3-none-any.whl → 1.8.11__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.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mongo-charms-single-kernel
3
- Version: 1.8.9
3
+ Version: 1.8.11
4
4
  Summary: Shared and reusable code for Mongo-related charms
5
5
  License-Expression: Apache-2.0
6
6
  License-File: LICENSE
@@ -1,19 +1,19 @@
1
1
  single_kernel_mongo/__init__.py,sha256=yTtXuLHbaXGJ5IgR7PhhNOzmqlpqywkTNI4bmkNECQ4,421
2
2
  single_kernel_mongo/abstract_charm.py,sha256=x8LnydlO2hoiJBp_ijRUNrfOH1YrvpcZy5SpuYR1jdg,5762
3
3
  single_kernel_mongo/config/__init__.py,sha256=OGTmp5MZXk2ZGgElT0A1yVyQz6FB4JzjG34mbeIWG2k,128
4
- single_kernel_mongo/config/literals.py,sha256=OH5vzTYdDaPtyZ-Qope-cYpsdxN_GEa43ElIn_98T3Q,2113
4
+ single_kernel_mongo/config/literals.py,sha256=4U2ODGjBRzJ2RCFJmydkBUpaoAcf4XjPOduU1fOnvu8,2181
5
5
  single_kernel_mongo/config/models.py,sha256=MruFI2EJndfH3KaJ5iaNar1oyMrTfSZaTQ3yxTxllnc,6770
6
6
  single_kernel_mongo/config/relations.py,sha256=CisZvNUNEy27_oxEme_WpmZbN7DuDGfh4EUrAeoJprw,1096
7
7
  single_kernel_mongo/config/statuses.py,sha256=hJ-BB-o85DfnRwEU-_6SGzMzebmYbDZNSvcBmHvL2hc,25761
8
8
  single_kernel_mongo/core/__init__.py,sha256=K1XAyFSIkldkT-008Eeg_o7H_XveWaxRuXGJnwoB_DU,124
9
- single_kernel_mongo/core/abstract_upgrades_v3.py,sha256=AU_eiZ5PU76mcJWoXcZZRaVWCTAZqLyw0RXk3J3bxbQ,5744
9
+ single_kernel_mongo/core/abstract_upgrades_v3.py,sha256=yYmLobPTCW_vJnJxHLpcYFvhlUf1feIjGkdXRwsJFvg,6079
10
10
  single_kernel_mongo/core/k8s_workload.py,sha256=wp3plDVg6h8vfG8Zpi_p2mq_TNP_2uBlPMt0kWlWrgk,5442
11
11
  single_kernel_mongo/core/kubernetes_upgrades_v3.py,sha256=OdzU2g2m2_QI9fAzxaJKnAek5dEc9ZxQ05bgqIT7GHw,339
12
12
  single_kernel_mongo/core/machine_upgrades_v3.py,sha256=ae_ehbL_dK778qhF3YYy4BB7ir9uekKp0HIdtf_S41o,1961
13
- single_kernel_mongo/core/operator.py,sha256=3k5CNyvndaNMjkLYMGMajX1saVUEAxSJi98CAvzyitI,14760
13
+ single_kernel_mongo/core/operator.py,sha256=HMinX_KEzAhIg44wWV2fQJwXGzzIIMXfAFo41JT4YvM,15040
14
14
  single_kernel_mongo/core/secrets.py,sha256=SOS19OhzpWdPur7JpggJ84u333tNyapTEgf_kjDjD6M,6755
15
15
  single_kernel_mongo/core/structured_config.py,sha256=5M2za_9Kh7_8tLLS16BcIBxU6EmtlmMqVHF-AczPDYc,4434
16
- single_kernel_mongo/core/version_checker.py,sha256=q8HZZUvy-h3CKxcaCtBss6UvwoexD92OaLmru6ikuJ0,3711
16
+ single_kernel_mongo/core/version_checker.py,sha256=t5uTpNgejmFAWOZlcMzWMXJ3R_s5T3scGp_y6y7jG5g,3019
17
17
  single_kernel_mongo/core/vm_workload.py,sha256=7KUgc82DaWVaxx3UEypuLZ3AIR_dlnqDnB6sorhbArw,7043
18
18
  single_kernel_mongo/core/workload.py,sha256=EHQdsL9uLb4zREChobxa9QvlzT1a1efMLkV2wAjaBBI,10239
19
19
  single_kernel_mongo/events/__init__.py,sha256=xatr1vi0ZKdqF1X-L2vaRuz1vJHwxschJu0XYxd_zoM,126
@@ -41,17 +41,17 @@ single_kernel_mongo/lib/charms/tls_certificates_interface/v4/tls_certificates.py
41
41
  single_kernel_mongo/managers/__init__.py,sha256=EUhvtK85skMEcT3yacYwezyIW4ajsoC5SwxpZcmPZnM,145
42
42
  single_kernel_mongo/managers/backups.py,sha256=L5UrxCSoYEJI8dtWA4tikNvTo71IQJqtMamvgKxsTGQ,40176
43
43
  single_kernel_mongo/managers/cluster.py,sha256=FhqbWFuozstdXMB1cO7QYMDMguhCrGSQY-uISuZaNaM,22557
44
- single_kernel_mongo/managers/config.py,sha256=F4qszxKV5A8ZPlpRXFWm5xXnjRFEqM5eouSCnLP4hqQ,18609
44
+ single_kernel_mongo/managers/config.py,sha256=5rgFw53XEDKhvJEADFmKxFa-Nv6AdPRSY5P8yh43caI,18660
45
45
  single_kernel_mongo/managers/k8s.py,sha256=I9NNaUKYlOGt6JoTa3gicqzPdO9yPWgO4tPgGBac1uQ,11036
46
46
  single_kernel_mongo/managers/ldap.py,sha256=xDyfWZWdrku1WY1phAJELPZAwynBM1Q2bXRA2gOyQto,15823
47
- single_kernel_mongo/managers/mongo.py,sha256=SMGion-lciKU9REzI7HTHs_R8rMafngbZzS7BfAWybc,24326
48
- single_kernel_mongo/managers/mongodb_operator.py,sha256=fcBSmV3ELs5x3NYhBAVN_iIYk1cwS7snP7-0mmOm8oY,56703
49
- single_kernel_mongo/managers/mongos_operator.py,sha256=ZVW7eIsQo0DmK4VzYruDlMsQkKL_ju4TtJkU4FXGIJo,25475
47
+ single_kernel_mongo/managers/mongo.py,sha256=tMYGP3q04L1CFdfsiLiLeOmAixuSzcTwhTL3yXZeePw,24401
48
+ single_kernel_mongo/managers/mongodb_operator.py,sha256=zfeOJ1CCq6kEEPOeOjeqbX3xhYXP1rFbW4MQXMaZsdc,56564
49
+ single_kernel_mongo/managers/mongos_operator.py,sha256=nKnSgbwWROCKUNnhmlbpYhkGN20P633KUXkG8Mp-Xzc,25854
50
50
  single_kernel_mongo/managers/observability.py,sha256=j5Nt5Wv43HaYVcr2f6Y_DqHJaP5XhUMjjh7Gg8JwsZI,3584
51
- single_kernel_mongo/managers/sharding.py,sha256=l2HYRdziu3yHq9mS8xuH5EwQHNG9Bz4HnVwHKPw2gqs,47461
51
+ single_kernel_mongo/managers/sharding.py,sha256=KKFktjr-j_86HRSZK4DWhuwOImhja_k8A3fAliwcTtE,47497
52
52
  single_kernel_mongo/managers/tls.py,sha256=-r0hj2b5LuHh-2Md1ask3CdICC09A5yiYzC6OjGuTpY,15834
53
- single_kernel_mongo/managers/upgrade_v3.py,sha256=Wci00SC1Ey599T0VefWHbfsl3nnqUVNru7RU3qJnCbY,19673
54
- single_kernel_mongo/managers/upgrade_v3_status.py,sha256=IRo4Geyv3mUmqy8QgnD4qWzQaTHLiGkMkKD1dC4ZZq4,5770
53
+ single_kernel_mongo/managers/upgrade_v3.py,sha256=NL_b32yqJIN_w00DvGppyvZWgMzNemGxI3UW-tYd6wk,20990
54
+ single_kernel_mongo/managers/upgrade_v3_status.py,sha256=Pa_-tsLVru0l36u4U3lhGE8683bWuJOGKdhAjiKkNvU,5765
55
55
  single_kernel_mongo/observability_rules/__init__.py,sha256=VuClFh0iGrw64cP4JppbSotFRyGpNVGmT8oD8pAbJoM,146
56
56
  single_kernel_mongo/observability_rules/grafana_dashboards/MongoDB_Cluster_Summary.json,sha256=z1mqwwTqot3lJogtinuCFMwecmPuInUsuOVSeHq9tj4,42626
57
57
  single_kernel_mongo/observability_rules/grafana_dashboards/MongoDB_ReplSet_Summary.json,sha256=qYyPM__vsL52jzUlC9ta9GkTZoKMZCmSN1AJoOy0wis,110603
@@ -61,11 +61,11 @@ single_kernel_mongo/observability_rules/vm_prometheus_alert_rules/percona-mongod
61
61
  single_kernel_mongo/state/__init__.py,sha256=V5TWoUtibFiyVO0BqPHnZOZrLNTIIgiVm3vmrhw8tS4,145
62
62
  single_kernel_mongo/state/abstract_state.py,sha256=2bSGXu0KehBw_XIu7THWZEVzrX6C8-73_9mlUrfEMXg,2471
63
63
  single_kernel_mongo/state/app_peer_state.py,sha256=ul2Z4EBFBm2HW58UaDFrR0mgj6cE8O5zWPzlTPRl8Cs,7501
64
- single_kernel_mongo/state/charm_state.py,sha256=-g-Ag5zbfmyM9-caXsE_j2xWeNb2s3P_FwUbdqNZHUY,30279
64
+ single_kernel_mongo/state/charm_state.py,sha256=P6q7GiMzJH99434XjWlkXIGzDeNzi6wW4PY1Z-4DycI,30370
65
65
  single_kernel_mongo/state/cluster_state.py,sha256=CmtC2ztAl02K_UEzix-jnObHri72m1pplzUbO7HKLB8,3228
66
- single_kernel_mongo/state/config_server_state.py,sha256=u9mr_-OCuIgbadHDLNxVkzL23qigVAn84GbnSemg-yo,4109
66
+ single_kernel_mongo/state/config_server_state.py,sha256=8gtCacXYEsw1-F968yRdaMQd6IBgbywy0qZv0XJs_kA,4155
67
67
  single_kernel_mongo/state/ldap_state.py,sha256=7XxjYoFMI8vujlqbCj5JyqigIlmYc-ebL9e0MEDW23Q,7915
68
- single_kernel_mongo/state/models.py,sha256=Ipfy2OdCekL1bIBr22Cb-pJiYhQdNvLIZYR4wPmc30g,592
68
+ single_kernel_mongo/state/models.py,sha256=eZUeHWa21BPJXfkr78ra9kqcmvwtGQUcJ6iGD_4BiGQ,608
69
69
  single_kernel_mongo/state/tls_state.py,sha256=CVNvMHmsX83wgStOHwWTOqqApv9LTm4lJLQFDqoNFSQ,3413
70
70
  single_kernel_mongo/state/unit_peer_state.py,sha256=99Qn6DkKXO_y5isuLXICfrQeVg3uqy0uW_48g7WqGK0,4080
71
71
  single_kernel_mongo/templates/__init__.py,sha256=8-zJnYHONfuTjeihx1ZL34URMW6c_MwJaIMBJgoPGTc,141
@@ -78,14 +78,14 @@ single_kernel_mongo/utils/helpers.py,sha256=N99hZq9USaWdi87XU9JR2W8SP9KfdAOaJy5f
78
78
  single_kernel_mongo/utils/mongo_config.py,sha256=tU7dGUZPSWdfttUn868vi_q5y6EWvGN2SREfexM8pxU,4134
79
79
  single_kernel_mongo/utils/mongo_connection.py,sha256=330gz1Ha5WdfdfxYmci1jVRnrRswtomoukn3AASSXCU,28540
80
80
  single_kernel_mongo/utils/mongo_error_codes.py,sha256=mM_KHTR3b9UA4BaxmzSlCVrFUNhRAc458ndBvJ4fg_8,479
81
- single_kernel_mongo/utils/mongodb_users.py,sha256=7Ckkkuy9eYeOHpNyk291P-rpH0Flk8KKCa3gkdE3BYI,6575
81
+ single_kernel_mongo/utils/mongodb_users.py,sha256=gPko6V244iSVhMxnCYll77azswhwLQZyzJ9RQATAg8E,6709
82
82
  single_kernel_mongo/workload/__init__.py,sha256=NCTTPCH9hbyi5pNO6UUfChpHh7h82xQ28aVAFIRlBOM,3225
83
83
  single_kernel_mongo/workload/backup_workload.py,sha256=7OugmoBE1SR3H8BUFYkIjtKv52bAk8oC2Q1CrCELOwg,1932
84
84
  single_kernel_mongo/workload/log_rotate_workload.py,sha256=VmWUJ_mqxN4v_IAFHw6lLCofUMqom24E2bFjaK12dck,3029
85
85
  single_kernel_mongo/workload/mongodb_workload.py,sha256=UHXVUQI1FyAhnP2TTLKiTFWWrUUaX-On4wDIsT5DXvQ,1527
86
86
  single_kernel_mongo/workload/mongos_workload.py,sha256=p1ZjqbGTokcxNnqKCvCIUQvmDvkOcN8pRvkPfA7Rgeg,1815
87
87
  single_kernel_mongo/workload/monitor_workload.py,sha256=dw-F3Y11_jpqI30Hg30-y6kxFFXGnHcSbgdAAJE8C8Q,1793
88
- mongo_charms_single_kernel-1.8.9.dist-info/METADATA,sha256=Nh_SFhIekPoSscT6kfdNC-Ui8vdQ9TeUF47jeAebrr0,5310
89
- mongo_charms_single_kernel-1.8.9.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
90
- mongo_charms_single_kernel-1.8.9.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
91
- mongo_charms_single_kernel-1.8.9.dist-info/RECORD,,
88
+ mongo_charms_single_kernel-1.8.11.dist-info/METADATA,sha256=_rkAURoIDKm5j4qVfPmanT8wanCloQBTjrZh1jqdyRo,5311
89
+ mongo_charms_single_kernel-1.8.11.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
90
+ mongo_charms_single_kernel-1.8.11.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
91
+ mongo_charms_single_kernel-1.8.11.dist-info/RECORD,,
@@ -51,13 +51,13 @@ class MongoPorts(IntEnum):
51
51
  class InternalUsernames(str, Enum):
52
52
  """The allowed internal usernames."""
53
53
 
54
- OPERATOR = "operator"
55
- BACKUP = "backup"
56
- MONITOR = "monitor"
57
- LOGROTATE = "logrotate"
54
+ CHARMED_OPERATOR = "charmed-operator"
55
+ CHARMED_BACKUP = "charmed-backup"
56
+ CHARMED_STATS = "charmed-stats"
57
+ CHARMED_LOGROTATE = "charmed-logrotate"
58
58
 
59
59
 
60
- SECRETS_APP = [f"{user}-password" for user in InternalUsernames] + ["keyfile"]
60
+ SECRETS_APP = [f"{username}-password" for username in InternalUsernames] + ["keyfile"]
61
61
 
62
62
  VERSIONS_FILE = Path("refresh_versions.toml")
63
63
 
@@ -4,6 +4,7 @@ import abc
4
4
  import dataclasses
5
5
  import logging
6
6
 
7
+ import charm_ as charm_api
7
8
  import charm_refresh
8
9
  import poetry.core.constraints.version as poetry_version
9
10
  from tenacity import RetryError
@@ -12,9 +13,7 @@ from typing_extensions import override
12
13
  from single_kernel_mongo.config.literals import CharmKind
13
14
  from single_kernel_mongo.config.models import BackupState
14
15
  from single_kernel_mongo.core.operator import OperatorProtocol
15
- from single_kernel_mongo.exceptions import (
16
- FailedToMovePrimaryError,
17
- )
16
+ from single_kernel_mongo.exceptions import FailedToMovePrimaryError
18
17
  from single_kernel_mongo.managers.upgrade_v3 import MongoDBUpgradesManager
19
18
  from single_kernel_mongo.state.charm_state import CharmState
20
19
 
@@ -108,6 +107,15 @@ class MongoDBRefresh(charm_refresh.CharmSpecificCommon, abc.ABC):
108
107
  logger.error("Cluster cannot read/write to replicas")
109
108
  raise charm_refresh.PrecheckFailed("Cluster is not able to read/write to replicas")
110
109
 
110
+ if not (
111
+ isinstance(charm_api.event, charm_api.ActionEvent)
112
+ and charm_api.event.action == "pre-refresh-check"
113
+ ):
114
+ logger.info(
115
+ "Not checking the compatibility version, this can only run in manual pre-refresh-check."
116
+ )
117
+ return
118
+
111
119
  fcv = self.state.app_peer_data.feature_compatibility_version
112
120
  if not self.upgrades_manager.is_feature_compatibility_version(fcv):
113
121
  logger.info(
@@ -393,3 +393,10 @@ class OperatorProtocol(ABC, Object, ManagerStatusProtocol):
393
393
  return
394
394
 
395
395
  Path(self.state.paths.conf_path).mkdir(exist_ok=True)
396
+
397
+ def instantiate_keyfile(self):
398
+ """Instantiate the keyfile."""
399
+ if not (keyfile := self.state.get_keyfile()):
400
+ raise Exception("Waiting for leader unit to generate keyfile contents")
401
+
402
+ self.workload.write(self.workload.paths.keyfile, keyfile)
@@ -42,14 +42,6 @@ class VersionChecker:
42
42
  "-locally built" if self.version_checker.is_local_charm(self.charm.app.name) else ""
43
43
  )
44
44
  try:
45
- # This part needs some explanation: On VM, if we are running this
46
- # during the pre-refresh hook that happens after the upgrade, all
47
- # charm codes have been refreshed.
48
- # We want to check our version against the already upgraded config server, so
49
- # we use the current revision that stores the revision of the
50
- # former charm until that unit is fully upgraded.
51
- old_version = self.version_checker.version
52
- self.version_checker.version = self.state.unit_peer_data.current_revision
53
45
  if self.version_checker.are_related_apps_valid():
54
46
  return None
55
47
  except NoVersionError as e:
@@ -61,10 +53,6 @@ class VersionChecker:
61
53
  current_charms_version, local_identifier
62
54
  )
63
55
 
64
- finally:
65
- # Always restore the former version.
66
- self.version_checker.version = old_version
67
-
68
56
  if self.state.is_role(MongoDBRoles.SHARD):
69
57
  config_server_revision = self.version_checker.get_version_of_related_app(
70
58
  self.state.config_server_name
@@ -28,7 +28,11 @@ from single_kernel_mongo.core.structured_config import MongoConfigModel, MongoDB
28
28
  from single_kernel_mongo.core.workload import WorkloadBase
29
29
  from single_kernel_mongo.exceptions import WorkloadServiceError
30
30
  from single_kernel_mongo.state.charm_state import CharmState
31
- from single_kernel_mongo.utils.mongodb_users import BackupUser, LogRotateUser, MonitorUser
31
+ from single_kernel_mongo.utils.mongodb_users import (
32
+ CharmedBackupUser,
33
+ CharmedLogRotateUser,
34
+ CharmedStatsUser,
35
+ )
32
36
  from single_kernel_mongo.workload import (
33
37
  get_logrotate_workload_for_substrate,
34
38
  get_mongodb_exporter_workload_for_substrate,
@@ -135,7 +139,7 @@ class BackupConfigManager(CommonConfigManager):
135
139
  logger.info("Not starting PBM yet. Shard not added to config-server")
136
140
  return
137
141
 
138
- if not self.state.get_user_password(BackupUser):
142
+ if not self.state.get_user_password(CharmedBackupUser):
139
143
  logger.info("No password found.")
140
144
  return
141
145
 
@@ -184,7 +188,7 @@ class LogRotateConfigManager(CommonConfigManager):
184
188
  logger.info("DB is not initialised.")
185
189
  return
186
190
 
187
- if not self.state.get_user_password(LogRotateUser):
191
+ if not self.state.get_user_password(CharmedLogRotateUser):
188
192
  logger.info("No password found.")
189
193
  return
190
194
 
@@ -224,17 +228,17 @@ class MongoDBExporterConfigManager(CommonConfigManager):
224
228
 
225
229
  @override
226
230
  def build_parameters(self) -> list[list[str]]:
227
- return [[self.state.monitor_config.uri]]
231
+ return [[self.state.stats_config.uri]]
228
232
 
229
233
  def configure_and_restart(self):
230
234
  """Exposes the endpoint to mongodb_exporter."""
231
235
  if not self.state.db_initialised:
232
236
  return
233
237
 
234
- if not self.state.get_user_password(MonitorUser):
238
+ if not self.state.get_user_password(CharmedStatsUser):
235
239
  return
236
240
 
237
- if not self.workload.active() or self.get_environment() != self.state.monitor_config.uri:
241
+ if not self.workload.active() or self.get_environment() != self.state.stats_config.uri:
238
242
  try:
239
243
  # Always enable the service
240
244
  self.workload.stop()
@@ -52,11 +52,11 @@ from single_kernel_mongo.utils.mongo_config import (
52
52
  from single_kernel_mongo.utils.mongo_connection import MongoConnection, NotReadyError
53
53
  from single_kernel_mongo.utils.mongodb_users import (
54
54
  OPERATOR_ROLE,
55
- BackupUser,
56
- LogRotateUser,
55
+ CharmedBackupUser,
56
+ CharmedLogRotateUser,
57
+ CharmedOperatorUser,
58
+ CharmedStatsUser,
57
59
  MongoDBUser,
58
- MonitorUser,
59
- OperatorUser,
60
60
  )
61
61
 
62
62
  if TYPE_CHECKING:
@@ -138,12 +138,12 @@ class MongoManager(Object, ManagerStatusProtocol):
138
138
 
139
139
  def initialise_charm_admin_users(self) -> None:
140
140
  """First initialisation of each user."""
141
- self.initialise_operator_user()
142
- self.initialise_user(MonitorUser)
143
- self.initialise_user(BackupUser)
144
- self.initialise_user(LogRotateUser)
141
+ self.initialise_charmed_operator_user()
142
+ self.initialise_user(CharmedStatsUser)
143
+ self.initialise_user(CharmedBackupUser)
144
+ self.initialise_user(CharmedLogRotateUser)
145
145
 
146
- def initialise_operator_user(self):
146
+ def initialise_charmed_operator_user(self):
147
147
  """Creates initial admin user for MongoDB.
148
148
 
149
149
  Initial admin user can be created only through localhost connection.
@@ -154,7 +154,7 @@ class MongoManager(Object, ManagerStatusProtocol):
154
154
  It is needed to install mongodb-clients inside charm container to make
155
155
  this function work correctly.
156
156
  """
157
- if self.state.app_peer_data.is_user_created(OperatorUser.username):
157
+ if self.state.app_peer_data.is_user_created(CharmedOperatorUser.username):
158
158
  return
159
159
  config = self.state.mongo_config
160
160
  cmd = [
@@ -169,7 +169,7 @@ class MongoManager(Object, ManagerStatusProtocol):
169
169
  '})"',
170
170
  ]
171
171
  self.workload.run_bin_command("mongodb://localhost/admin", cmd, input=config.password)
172
- self.state.app_peer_data.set_user_created(OperatorUser.username)
172
+ self.state.app_peer_data.set_user_created(CharmedOperatorUser.username)
173
173
 
174
174
  def initialise_user(self, user: MongoDBUser):
175
175
  """Creates a user and sets its role on the MongoDB database."""
@@ -33,10 +33,7 @@ from single_kernel_mongo.config.models import (
33
33
  PasswordManagementContext,
34
34
  PasswordManagementState,
35
35
  )
36
- from single_kernel_mongo.config.relations import (
37
- ExternalRequirerRelations,
38
- RelationNames,
39
- )
36
+ from single_kernel_mongo.config.relations import ExternalRequirerRelations, RelationNames
40
37
  from single_kernel_mongo.config.statuses import (
41
38
  BackupStatuses,
42
39
  CharmStatuses,
@@ -100,12 +97,12 @@ from single_kernel_mongo.state.charm_state import CharmState
100
97
  from single_kernel_mongo.utils.helpers import is_valid_ldap_options, is_valid_ldapusertodnmapping
101
98
  from single_kernel_mongo.utils.mongo_connection import MongoConnection, NotReadyError
102
99
  from single_kernel_mongo.utils.mongodb_users import (
103
- BackupUser,
100
+ CharmedBackupUser,
101
+ CharmedLogRotateUser,
102
+ CharmedOperatorUser,
103
+ CharmedStatsUser,
104
104
  InternalUsers,
105
- LogRotateUser,
106
105
  MongoDBUser,
107
- MonitorUser,
108
- OperatorUser,
109
106
  get_user_from_username,
110
107
  validate_charm_user_password_config,
111
108
  )
@@ -236,7 +233,7 @@ class MongoDBOperator(OperatorProtocol, Object):
236
233
  raise
237
234
 
238
235
  self.upgrades_status_manager = MongoDBUpgradesStatusManager(
239
- state=self.state, workload=self.workload, refresh=self.refresh
236
+ self, state=self.state, workload=self.workload, refresh=self.refresh
240
237
  )
241
238
 
242
239
  self.sysctl_config = sysctl.Config(name=self.charm.app.name)
@@ -274,13 +271,13 @@ class MongoDBOperator(OperatorProtocol, Object):
274
271
  if not self.refresh:
275
272
  return
276
273
 
274
+ # Update the version across all relations so that we can notify other units
275
+ self.cross_app_version_checker.set_version_across_all_relations()
276
+
277
277
  if self.state.app_peer_data.feature_compatibility_version == FEATURE_VERSION:
278
278
  # We have already run all this logic before, no need to run it again.
279
279
  return
280
280
 
281
- # Update the version across all relations so that we can notify other units
282
- self.cross_app_version_checker.set_version_across_all_relations()
283
-
284
281
  if (
285
282
  self.state.is_role(MongoDBRoles.CONFIG_SERVER)
286
283
  and not self.cross_app_version_checker.are_related_apps_valid()
@@ -324,12 +321,15 @@ class MongoDBOperator(OperatorProtocol, Object):
324
321
 
325
322
  if not refresh.workload_allowed_to_start:
326
323
  return
324
+
327
325
  logger.info("Restarting workloads")
328
326
  # always apply the current charm revision's config
329
327
  self._configure_workloads()
330
328
  self.start_charm_services()
331
329
 
332
- self.state.unit_peer_data.current_revision = self.cross_app_version_checker.version
330
+ if self.charm.unit.is_leader():
331
+ # Update the version across all relations so that we can notify other units
332
+ self.cross_app_version_checker.set_version_across_all_relations()
333
333
 
334
334
  if self.name == CharmKind.MONGOD:
335
335
  self._restart_related_services()
@@ -391,13 +391,13 @@ class MongoDBOperator(OperatorProtocol, Object):
391
391
  """The ordered list of components for this operator."""
392
392
  return (
393
393
  self,
394
+ self.upgrades_status_manager,
394
395
  self.mongo_manager,
395
396
  self.tls_manager,
396
397
  self.shard_manager,
397
398
  self.config_server_manager,
398
399
  self.backup_manager,
399
400
  self.ldap_manager,
400
- self.upgrades_status_manager,
401
401
  )
402
402
 
403
403
  # BEGIN: Handlers.
@@ -480,7 +480,7 @@ class MongoDBOperator(OperatorProtocol, Object):
480
480
  if not self.mongo_manager.mongod_ready():
481
481
  raise WorkloadNotReadyError
482
482
 
483
- self.state.statuses.set(CharmStatuses.ACTIVE_IDLE.value, scope="unit", component=self.name)
483
+ self.state.statuses.clear(scope="unit", component=self.name)
484
484
 
485
485
  try:
486
486
  self._initialise_replica_set()
@@ -503,7 +503,7 @@ class MongoDBOperator(OperatorProtocol, Object):
503
503
  logger.error("Could not restart the related services.")
504
504
  return
505
505
 
506
- self.state.statuses.set(CharmStatuses.ACTIVE_IDLE.value, scope="unit", component=self.name)
506
+ self.state.statuses.clear(scope="unit", component=self.name)
507
507
 
508
508
  @override
509
509
  def prepare_for_shutdown(self) -> None: # pragma: nocover
@@ -719,10 +719,10 @@ class MongoDBOperator(OperatorProtocol, Object):
719
719
 
720
720
  Adds the unit as a replica to the MongoDB replica set.
721
721
  """
722
- # Changing the monitor or the backup password will lead to non-leader
723
- # units receiving a relation changed event. We must update the monitor
724
- # and pbm URI if the password changes so that COS/pbm can continue to
725
- # work.
722
+ # Changing the charmed-stats or the charmed-backup password will lead
723
+ # to non-leader units receiving a relation changed event. We must update
724
+ # the monitor and pbm URI if the password changes so that COS/pbm can
725
+ # continue to work.
726
726
  if self.state.db_initialised and self.workload.active():
727
727
  self.mongodb_exporter_config_manager.configure_and_restart()
728
728
  self.backup_manager.configure_and_restart()
@@ -912,16 +912,18 @@ class MongoDBOperator(OperatorProtocol, Object):
912
912
  def update_single_user_password(self, user: MongoDBUser, new_password: str) -> None:
913
913
  """Set password in Mongod and restart the appropriate services."""
914
914
  self.mongo_manager.set_user_password(user, new_password)
915
- if user == BackupUser:
915
+ if user == CharmedBackupUser:
916
916
  # Update and restart PBM Agent.
917
917
  self.backup_manager.configure_and_restart()
918
- if user == MonitorUser:
918
+ if user == CharmedStatsUser:
919
919
  # Update and restart mongodb exporter.
920
920
  self.mongodb_exporter_config_manager.configure_and_restart()
921
- if user == LogRotateUser:
921
+ if user == CharmedLogRotateUser:
922
922
  # Update and restart logrotate.
923
923
  self.logrotate_config_manager.configure_and_restart()
924
- if user in (OperatorUser, BackupUser) and self.state.is_role(MongoDBRoles.CONFIG_SERVER):
924
+ if user in (CharmedOperatorUser, CharmedBackupUser) and self.state.is_role(
925
+ MongoDBRoles.CONFIG_SERVER
926
+ ):
925
927
  self.config_server_manager.update_credentials(
926
928
  user.password_key_name,
927
929
  new_password,
@@ -1151,13 +1153,6 @@ class MongoDBOperator(OperatorProtocol, Object):
1151
1153
  # Sets directory permissions
1152
1154
  self.set_permissions()
1153
1155
 
1154
- def instantiate_keyfile(self):
1155
- """Instantiate the keyfile."""
1156
- if not (keyfile := self.state.get_keyfile()):
1157
- raise Exception("Waiting for leader unit to generate keyfile contents")
1158
-
1159
- self.workload.write(self.workload.paths.keyfile, keyfile)
1160
-
1161
1156
  def _initialise_replica_set(self):
1162
1157
  """Helpful method to initialise the replica set and the users.
1163
1158
 
@@ -20,12 +20,7 @@ from ops.model import Relation, Unit
20
20
  from pymongo.errors import PyMongoError
21
21
  from typing_extensions import override
22
22
 
23
- from single_kernel_mongo.config.literals import (
24
- CharmKind,
25
- MongoPorts,
26
- Scope,
27
- Substrates,
28
- )
23
+ from single_kernel_mongo.config.literals import CharmKind, MongoPorts, Scope, Substrates
29
24
  from single_kernel_mongo.config.models import ROLES
30
25
  from single_kernel_mongo.config.relations import ExternalRequirerRelations, RelationNames
31
26
  from single_kernel_mongo.config.statuses import CharmStatuses, MongosStatuses
@@ -57,9 +52,7 @@ from single_kernel_mongo.managers.upgrade_v3 import MongoDBUpgradesManager
57
52
  from single_kernel_mongo.managers.upgrade_v3_status import MongoDBUpgradesStatusManager
58
53
  from single_kernel_mongo.state.app_peer_state import AppPeerDataKeys
59
54
  from single_kernel_mongo.state.charm_state import CharmState
60
- from single_kernel_mongo.workload import (
61
- get_mongos_workload_for_substrate,
62
- )
55
+ from single_kernel_mongo.workload import get_mongos_workload_for_substrate
63
56
  from single_kernel_mongo.workload.mongos_workload import MongosWorkload
64
57
 
65
58
  if TYPE_CHECKING:
@@ -137,7 +130,7 @@ class MongosOperator(OperatorProtocol, Object):
137
130
  sys.exit()
138
131
 
139
132
  self.upgrades_status_manager = MongoDBUpgradesStatusManager(
140
- self.state, self.workload, self.refresh
133
+ self, self.state, self.workload, self.refresh
141
134
  )
142
135
 
143
136
  # LDAP Manager, which covers both send-ca-cert interface and ldap interface.
@@ -169,6 +162,9 @@ class MongosOperator(OperatorProtocol, Object):
169
162
 
170
163
  Checks if unit is healthy and allow the next unit to update.
171
164
  """
165
+ if not self.state.db_initialised:
166
+ return
167
+
172
168
  if not refresh.workload_allowed_to_start:
173
169
  return
174
170
 
@@ -178,7 +174,7 @@ class MongosOperator(OperatorProtocol, Object):
178
174
  self._configure_workloads()
179
175
  self.start_charm_services()
180
176
 
181
- logger.debug("Running post refresh checks to verify monogs is not broken after refresh")
177
+ logger.debug("Running post refresh checks to verify mongos is not broken after refresh")
182
178
  if not self.state.db_initialised:
183
179
  refresh.next_unit_allowed_to_refresh = True
184
180
  return
@@ -232,6 +228,12 @@ class MongosOperator(OperatorProtocol, Object):
232
228
 
233
229
  self.mongos_config_manager.set_environment()
234
230
 
231
+ # Instantiate the keyfile
232
+ try:
233
+ self.instantiate_keyfile()
234
+ except Exception:
235
+ logger.info("Not instantiating as we don't have a keyfile yet.")
236
+
235
237
  @override
236
238
  def prepare_for_startup(self) -> None:
237
239
  """For this case, we don't start any service.
@@ -248,19 +250,24 @@ class MongosOperator(OperatorProtocol, Object):
248
250
 
249
251
  if self.refresh.in_progress:
250
252
  # Bypass the regular start if refresh is in progress
253
+ logger.info("Refresh in progress, skipping regular start")
251
254
  return
252
255
 
253
256
  self._configure_workloads()
254
257
 
255
- # start hooks are fired before relation hooks and `mongos` requires a config-server in
258
+ if self.state.mongos_cluster_relation:
259
+ self.instantiate_keyfile()
260
+ self.start_charm_services()
261
+ return
262
+
263
+ # start hooks that are fired before relation hooks and `mongos` requires a config-server in
256
264
  # order to start. Wait to receive config-server info from the relation event before
257
265
  # starting `mongos` daemon
258
- if not self.state.mongos_cluster_relation:
259
- self.state.statuses.add(
260
- MongosStatuses.MISSING_CONF_SERVER_REL.value,
261
- scope="unit",
262
- component=self.name,
263
- )
266
+ self.state.statuses.add(
267
+ MongosStatuses.MISSING_CONF_SERVER_REL.value,
268
+ scope="unit",
269
+ component=self.name,
270
+ )
264
271
 
265
272
  @override
266
273
  def update_secrets_and_restart(self, secret_label: str, secret_id: str) -> None:
@@ -18,9 +18,7 @@ from data_platform_helpers.advanced_statuses.models import StatusObject
18
18
  from data_platform_helpers.advanced_statuses.protocol import ManagerStatusProtocol
19
19
  from data_platform_helpers.advanced_statuses.types import Scope
20
20
  from ops.framework import Object
21
- from ops.model import (
22
- Relation,
23
- )
21
+ from ops.model import Relation
24
22
  from pymongo.errors import (
25
23
  NotPrimaryError,
26
24
  OperationFailure,
@@ -37,10 +35,7 @@ from single_kernel_mongo.config.literals import (
37
35
  )
38
36
  from single_kernel_mongo.config.models import BackupState
39
37
  from single_kernel_mongo.config.relations import RelationNames
40
- from single_kernel_mongo.config.statuses import (
41
- ConfigServerStatuses,
42
- ShardStatuses,
43
- )
38
+ from single_kernel_mongo.config.statuses import ConfigServerStatuses, ShardStatuses
44
39
  from single_kernel_mongo.core.structured_config import MongoDBRoles
45
40
  from single_kernel_mongo.exceptions import (
46
41
  BalancerNotEnabledError,
@@ -62,9 +57,9 @@ from single_kernel_mongo.state.tls_state import SECRET_CA_LABEL
62
57
  from single_kernel_mongo.utils.mongo_connection import MongoConnection, NotReadyError
63
58
  from single_kernel_mongo.utils.mongo_error_codes import MongoErrorCodes
64
59
  from single_kernel_mongo.utils.mongodb_users import (
65
- BackupUser,
60
+ CharmedBackupUser,
61
+ CharmedOperatorUser,
66
62
  MongoDBUser,
67
- OperatorUser,
68
63
  )
69
64
  from single_kernel_mongo.workload.mongodb_workload import MongoDBWorkload
70
65
 
@@ -108,10 +103,10 @@ class ConfigServerManager(Object, ManagerStatusProtocol):
108
103
  )
109
104
  relation_data = {
110
105
  AppShardingComponentKeys.OPERATOR_PASSWORD.value: self.state.get_user_password(
111
- OperatorUser
106
+ CharmedOperatorUser
112
107
  ),
113
108
  AppShardingComponentKeys.BACKUP_PASSWORD.value: self.state.get_user_password(
114
- BackupUser
109
+ CharmedBackupUser
115
110
  ),
116
111
  AppShardingComponentKeys.KEY_FILE.value: self.state.get_keyfile(),
117
112
  AppShardingComponentKeys.HOST.value: json.dumps(sorted(self.state.internal_hosts)),
@@ -195,11 +190,8 @@ class ConfigServerManager(Object, ManagerStatusProtocol):
195
190
  # Note: we permit this logic based on status since we aren't checking
196
191
  # self.charm.unit.status`, instead `get_cluster_mismatched_revision_status` directly
197
192
  # computes the revision check.
198
- if (
199
- rev_status
200
- := self.dependent.cluster_version_checker.get_cluster_mismatched_revision_status()
201
- ):
202
- self.state.statuses.add(rev_status, scope="app", component=self.dependent.name)
193
+ if self.dependent.cluster_version_checker.get_cluster_mismatched_revision_status():
194
+ # The status will be added during the get status
203
195
  raise DeferrableFailedHookChecksError("Mismatched versions in the cluster")
204
196
 
205
197
  def assert_pass_hook_checks(self, relation: Relation, leaving: bool = False) -> None:
@@ -476,8 +468,8 @@ class ConfigServerManager(Object, ManagerStatusProtocol):
476
468
  if not hosts:
477
469
  return unreachable_hosts
478
470
 
479
- # use a URI that is not dependent on the operator password, as we are not guaranteed
480
- # that the shard has received the password yet.
471
+ # use a URI that is not dependent on the charmed-operator password, as we are
472
+ # not guaranteed that the shard has received the password yet.
481
473
  # To check if the shard is ready, we check the entire replica set for readiness
482
474
  uri = f"mongodb://{','.join(hosts)}"
483
475
  if not self.dependent.mongo_manager.mongod_ready(uri, direct=False):
@@ -526,11 +518,8 @@ class ShardManager(Object, ManagerStatusProtocol):
526
518
  # Note: we permit this logic based on status since we aren't checking
527
519
  # self.charm.unit.status`, instead `get_cluster_mismatched_revision_status` directly
528
520
  # computes the revision check.
529
- if (
530
- rev_status
531
- := self.dependent.cluster_version_checker.get_cluster_mismatched_revision_status()
532
- ):
533
- self.state.statuses.add(rev_status, scope="app", component=self.dependent.name)
521
+ if self.dependent.cluster_version_checker.get_cluster_mismatched_revision_status():
522
+ # The status will be added during the get status
534
523
  raise DeferrableFailedHookChecksError("Mismatched versions in the cluster")
535
524
 
536
525
  def assert_pass_hook_checks(self, relation: Relation, is_leaving: bool = False) -> None:
@@ -637,7 +626,7 @@ class ShardManager(Object, ManagerStatusProtocol):
637
626
  self.state.app_peer_data.mongos_hosts = self.state.shard_state.mongos_hosts
638
627
 
639
628
  def handle_secret_changed(self, secret_label: str | None) -> None:
640
- """Update operator and backup user passwords when rotation occurs.
629
+ """Update charmed-operator and charmed-backup user passwords when rotation occurs.
641
630
 
642
631
  Changes in secrets do not re-trigger a relation changed event, so it is necessary to listen
643
632
  to secret changes events.
@@ -665,7 +654,9 @@ class ShardManager(Object, ManagerStatusProtocol):
665
654
  backup_password = self.state.shard_state.backup_password
666
655
 
667
656
  if not operator_password or not backup_password:
668
- raise WaitingForSecretsError("Missing operator password or backup password")
657
+ raise WaitingForSecretsError(
658
+ "Missing charmed-operator password or charmed-backup password"
659
+ )
669
660
  self.sync_cluster_passwords(operator_password, backup_password)
670
661
 
671
662
  # Add the certificate if it is present
@@ -764,7 +755,10 @@ class ShardManager(Object, ManagerStatusProtocol):
764
755
  )
765
756
  raise NotReadyError
766
757
 
767
- for user, password in ((OperatorUser, operator_password), (BackupUser, backup_password)):
758
+ for user, password in (
759
+ (CharmedOperatorUser, operator_password),
760
+ (CharmedBackupUser, backup_password),
761
+ ):
768
762
  try:
769
763
  self.update_password(user=user, new_password=password)
770
764
  except SetPasswordError:
@@ -888,7 +882,7 @@ class ShardManager(Object, ManagerStatusProtocol):
888
882
  )
889
883
  return False
890
884
 
891
- config = self.state.mongos_config_for_user(OperatorUser, set(mongos_hosts))
885
+ config = self.state.mongos_config_for_user(CharmedOperatorUser, set(mongos_hosts))
892
886
 
893
887
  drained = shard_name not in self.dependent.mongo_manager.get_draining_shards(
894
888
  config=config, shard_name=shard_name
@@ -927,9 +921,13 @@ class ShardManager(Object, ManagerStatusProtocol):
927
921
 
928
922
  def should_synchronise_cluster_passwords(self) -> bool:
929
923
  """Decides if we should synchronise cluster passwords or not."""
930
- if self.state.shard_state.operator_password != self.state.get_user_password(OperatorUser):
924
+ if self.state.shard_state.operator_password != self.state.get_user_password(
925
+ CharmedOperatorUser
926
+ ):
931
927
  return True
932
- if self.state.shard_state.backup_password != self.state.get_user_password(BackupUser):
928
+ if self.state.shard_state.backup_password != self.state.get_user_password(
929
+ CharmedBackupUser
930
+ ):
933
931
  return True
934
932
  return False
935
933
 
@@ -11,14 +11,11 @@ from tenacity import Retrying, retry, stop_after_attempt, wait_fixed
11
11
  from single_kernel_mongo.core.operator import OperatorProtocol
12
12
  from single_kernel_mongo.core.structured_config import MongoDBRoles
13
13
  from single_kernel_mongo.core.workload import WorkloadBase
14
- from single_kernel_mongo.exceptions import (
15
- BalancerStillRunningError,
16
- ClusterNotHealthyError,
17
- )
14
+ from single_kernel_mongo.exceptions import BalancerStillRunningError, ClusterNotHealthyError
18
15
  from single_kernel_mongo.state.charm_state import CharmState
19
16
  from single_kernel_mongo.utils.mongo_config import MongoConfiguration
20
17
  from single_kernel_mongo.utils.mongo_connection import MongoConnection
21
- from single_kernel_mongo.utils.mongodb_users import OperatorUser
18
+ from single_kernel_mongo.utils.mongodb_users import CharmedOperatorUser
22
19
 
23
20
  logger = logging.getLogger()
24
21
 
@@ -60,6 +57,26 @@ class MongoDBUpgradesManager:
60
57
  )
61
58
  return False
62
59
 
60
+ def are_shards_accessible(self) -> bool:
61
+ """Checks if all nodes are responsive to a simple ping, fails otherwise."""
62
+ mongos_config = self.get_cluster_mongos()
63
+ for replica_set_config in self.get_all_replica_set_configs_in_cluster(mongos_config):
64
+ for single_host in replica_set_config.hosts:
65
+ if single_host != self.state.unit_peer_data.internal_address:
66
+ logger.info(f"Checking if shard {single_host} is responding to ping")
67
+ single_replica_config = self.state.mongodb_config_for_user(
68
+ CharmedOperatorUser,
69
+ hosts={single_host},
70
+ replset=replica_set_config.replset,
71
+ )
72
+ try:
73
+ with MongoConnection(single_replica_config, direct=True) as mongod:
74
+ mongod.client.admin.command("ping")
75
+ except PyMongoError as e:
76
+ logger.info(f"{single_host} does not respond to ping: {e}")
77
+ return False
78
+ return True
79
+
63
80
  def are_nodes_healthy(self) -> bool:
64
81
  """Returns true if all nodes in the MongoDB deployment are healthy."""
65
82
  if self.state.is_sharding_component and not self.state.has_sharding_integration:
@@ -68,6 +85,9 @@ class MongoDBUpgradesManager:
68
85
  return self.are_replica_set_nodes_healthy(self.state.mongo_config)
69
86
 
70
87
  mongos_config = self.get_cluster_mongos()
88
+ if not self.are_shards_accessible():
89
+ return False
90
+
71
91
  if not self.are_shards_healthy(mongos_config):
72
92
  logger.info(
73
93
  "One or more individual shards are not healthy - do not proceed with refresh."
@@ -93,7 +113,7 @@ class MongoDBUpgradesManager:
93
113
  self.state.mongos_config
94
114
  if self.state.is_role(MongoDBRoles.CONFIG_SERVER)
95
115
  else self.state.mongos_config_for_user(
96
- OperatorUser, hosts=set(self.state.shard_state.mongos_hosts)
116
+ CharmedOperatorUser, hosts=set(self.state.shard_state.mongos_hosts)
97
117
  )
98
118
  )
99
119
 
@@ -142,7 +162,7 @@ class MongoDBUpgradesManager:
142
162
  config_server_hosts = self.state.app_peer_data.mongos_hosts
143
163
  mongodb_configurations = [
144
164
  self.state.mongodb_config_for_user(
145
- OperatorUser,
165
+ CharmedOperatorUser,
146
166
  hosts=set(config_server_hosts),
147
167
  replset=self.state.config_server_name,
148
168
  )
@@ -163,7 +183,7 @@ class MongoDBUpgradesManager:
163
183
  shard_hosts = shard_entry["host"].split("/")[1]
164
184
  parsed_ips = {host.split(":")[0] for host in shard_hosts.split(",")}
165
185
  return self.state.mongodb_config_for_user(
166
- OperatorUser, parsed_ips, replset=shard_entry[SHARD_NAME_INDEX]
186
+ CharmedOperatorUser, parsed_ips, replset=shard_entry[SHARD_NAME_INDEX]
167
187
  )
168
188
 
169
189
  def get_random_write_and_collection(self) -> tuple[str, str, str]:
@@ -242,6 +262,8 @@ class MongoDBUpgradesManager:
242
262
  secondary_config = copy.deepcopy(mongodb_config)
243
263
 
244
264
  for replica_ip in mongodb_config.hosts:
265
+ if replica_ip == self.state.unit_peer_data.internal_address:
266
+ continue
245
267
  secondary_config.hosts = {replica_ip}
246
268
  with MongoConnection(secondary_config, direct=True) as direct_secondary:
247
269
  db = direct_secondary.client[db_name]
@@ -400,7 +422,7 @@ class MongoDBUpgradesManager:
400
422
  for replica_set_config in self.get_all_replica_set_configs_in_cluster(mongos_config):
401
423
  for single_host in replica_set_config.hosts:
402
424
  single_replica_config = self.state.mongodb_config_for_user(
403
- OperatorUser,
425
+ CharmedOperatorUser,
404
426
  hosts={single_host},
405
427
  replset=replica_set_config.replset,
406
428
  standalone=True,
@@ -426,7 +448,7 @@ class MongoDBUpgradesManager:
426
448
  config = self.state.mongo_config
427
449
  for host in config.hosts:
428
450
  single_unit_config = self.state.mongodb_config_for_user(
429
- OperatorUser, hosts={host}, replset=config.replset, standalone=True
451
+ CharmedOperatorUser, hosts={host}, replset=config.replset, standalone=True
430
452
  )
431
453
  with MongoConnection(single_unit_config) as mongod:
432
454
  version = mongod.client.admin.command(
@@ -10,6 +10,7 @@ from ops.model import ActiveStatus, BlockedStatus, MaintenanceStatus, StatusBase
10
10
 
11
11
  from single_kernel_mongo.config.literals import Substrates
12
12
  from single_kernel_mongo.config.statuses import CharmStatuses, UpgradeStatuses
13
+ from single_kernel_mongo.core.operator import OperatorProtocol
13
14
  from single_kernel_mongo.core.workload import WorkloadBase
14
15
  from single_kernel_mongo.exceptions import DeployedWithoutTrustError
15
16
  from single_kernel_mongo.state.charm_state import CharmState
@@ -23,8 +24,13 @@ class MongoDBUpgradesStatusManager(ManagerStatusProtocol):
23
24
  name: str = "upgrades"
24
25
 
25
26
  def __init__(
26
- self, state: CharmState, workload: WorkloadBase, refresh: charm_refresh.Common | None
27
+ self,
28
+ dependent: OperatorProtocol,
29
+ state: CharmState,
30
+ workload: WorkloadBase,
31
+ refresh: charm_refresh.Common | None,
27
32
  ) -> None:
33
+ self.dependent = dependent
28
34
  self.state = state
29
35
  self.workload = workload
30
36
  self.refresh = refresh
@@ -73,10 +79,7 @@ class MongoDBUpgradesStatusManager(ManagerStatusProtocol):
73
79
  return status_list
74
80
 
75
81
  if self.refresh.in_progress and not self.refresh.next_unit_allowed_to_refresh:
76
- if not self.dependent.mongo_manager.mongod_ready():
77
- status_list.append(UpgradeStatuses.HEALTH_CHECK_FAILED.value)
78
- else:
79
- status_list.append(UpgradeStatuses.CLUSTER_CHECK_FAILED.value)
82
+ status_list.append(UpgradeStatuses.HEALTH_CHECK_FAILED.value)
80
83
 
81
84
  if refresh_unit_status := self.refresh.unit_status_higher_priority:
82
85
  unit_status = self._convert_ops_status_to_advanced_status(refresh_unit_status)
@@ -73,12 +73,12 @@ from single_kernel_mongo.utils.mongo_config import MongoConfiguration
73
73
  from single_kernel_mongo.utils.mongo_connection import MongoConnection
74
74
  from single_kernel_mongo.utils.mongo_error_codes import MongoErrorCodes
75
75
  from single_kernel_mongo.utils.mongodb_users import (
76
- BackupUser,
76
+ CharmedBackupUser,
77
+ CharmedLogRotateUser,
78
+ CharmedOperatorUser,
79
+ CharmedStatsUser,
77
80
  InternalUsers,
78
- LogRotateUser,
79
81
  MongoDBUser,
80
- MonitorUser,
81
- OperatorUser,
82
82
  RoleNames,
83
83
  )
84
84
 
@@ -725,35 +725,35 @@ class CharmState(Object, StatusesStateProtocol):
725
725
 
726
726
  @property
727
727
  def backup_config(self) -> MongoConfiguration:
728
- """Mongo Configuration for the backup user."""
729
- return self.mongodb_config_for_user(BackupUser, standalone=True)
728
+ """Mongo Configuration for the charmed-backup user."""
729
+ return self.mongodb_config_for_user(CharmedBackupUser, standalone=True)
730
730
 
731
731
  @property
732
- def monitor_config(self) -> MongoConfiguration:
733
- """Mongo Configuration for the monitoring user."""
734
- return self.mongodb_config_for_user(MonitorUser, hosts=self.internal_hosts)
732
+ def stats_config(self) -> MongoConfiguration:
733
+ """Mongo Configuration for the charmed-stats user."""
734
+ return self.mongodb_config_for_user(CharmedStatsUser, hosts=self.internal_hosts)
735
735
 
736
736
  @property
737
737
  def logrotate_config(self) -> MongoConfiguration:
738
- """Mongo Configuration for the logrotate user."""
739
- return self.mongodb_config_for_user(LogRotateUser, standalone=True)
738
+ """Mongo Configuration for the charmed-logrotate user."""
739
+ return self.mongodb_config_for_user(CharmedLogRotateUser, standalone=True)
740
740
 
741
741
  @property
742
742
  def operator_config(self) -> MongoConfiguration:
743
- """Mongo Configuration for the operator user."""
744
- return self.mongodb_config_for_user(OperatorUser, hosts=self.internal_hosts)
743
+ """Mongo Configuration for the charmed-operator user."""
744
+ return self.mongodb_config_for_user(CharmedOperatorUser, hosts=self.internal_hosts)
745
745
 
746
746
  @property
747
747
  def remote_mongos_config(self) -> MongoConfiguration:
748
748
  """Mongos Configuration for the remote mongos server."""
749
749
  mongos_hosts = self.app_peer_data.mongos_hosts
750
- return self.mongos_config_for_user(OperatorUser, set(mongos_hosts))
750
+ return self.mongos_config_for_user(CharmedOperatorUser, set(mongos_hosts))
751
751
 
752
752
  @property
753
753
  def mongos_config(self) -> MongoConfiguration:
754
754
  """Mongos Configuration for the admin mongos user."""
755
755
  if self.charm_role.name == CharmKind.MONGOD:
756
- return self.mongos_config_for_user(OperatorUser, self.internal_hosts)
756
+ return self.mongos_config_for_user(CharmedOperatorUser, self.internal_hosts)
757
757
  username, password = self.get_user_credentials()
758
758
  database = self.app_peer_data.database
759
759
  port: int | None = MongoPorts.MONGOS_PORT.value
@@ -18,8 +18,8 @@ class AppShardingComponentKeys(str, Enum):
18
18
  """Config Server State Model for the application."""
19
19
 
20
20
  DATABASE = "database"
21
- OPERATOR_PASSWORD = "operator-password"
22
- BACKUP_PASSWORD = "backup-password"
21
+ OPERATOR_PASSWORD = "charmed-operator-password"
22
+ BACKUP_PASSWORD = "charmed-backup-password"
23
23
  HOST = "host"
24
24
  KEY_FILE = "key-file"
25
25
  INT_CA_SECRET = "int-ca-secret"
@@ -32,8 +32,8 @@ class AppShardingComponentKeys(str, Enum):
32
32
 
33
33
 
34
34
  SECRETS_FIELDS = [
35
- "operator-password",
36
- "backup-password",
35
+ "charmed-operator-password",
36
+ "charmed-backup-password",
37
37
  "key-file",
38
38
  "int-ca-secret",
39
39
  "ext-ca-secret",
@@ -93,14 +93,14 @@ class AppShardingComponentState(AbstractRelationState[Data]):
93
93
 
94
94
  @property
95
95
  def operator_password(self) -> str | None:
96
- """Returns the operator password."""
96
+ """Returns the charmed-operator password."""
97
97
  if not self.relation:
98
98
  return None
99
99
  return self.relation_data.get(AppShardingComponentKeys.OPERATOR_PASSWORD.value, None)
100
100
 
101
101
  @property
102
102
  def backup_password(self) -> str | None:
103
- """Returns the operator password."""
103
+ """Returns the charmed-backup password."""
104
104
  if not self.relation:
105
105
  return None
106
106
  return self.relation_data.get(AppShardingComponentKeys.BACKUP_PASSWORD.value, None)
@@ -20,7 +20,7 @@ class ConfigServerData(ProviderData, RequirerData): # type: ignore[misc]
20
20
  "tls-ca",
21
21
  "uris",
22
22
  "key-file",
23
- "operator-password",
24
- "backup-password",
23
+ "charmed-operator-password",
24
+ "charmed-backup-password",
25
25
  "int-ca-secret",
26
26
  ]
@@ -129,14 +129,14 @@ class MongoDBUser(BaseModel):
129
129
  return self.hosts
130
130
 
131
131
 
132
- OperatorUser = MongoDBUser(
133
- username=InternalUsernames.OPERATOR,
132
+ CharmedOperatorUser = MongoDBUser(
133
+ username=InternalUsernames.CHARMED_OPERATOR,
134
134
  database_name=SystemDBS.ADMIN,
135
135
  roles={RoleNames.DEFAULT},
136
136
  )
137
137
 
138
- MonitorUser = MongoDBUser(
139
- username=InternalUsernames.MONITOR,
138
+ CharmedStatsUser = MongoDBUser(
139
+ username=InternalUsernames.CHARMED_STATS,
140
140
  database_name=SystemDBS.ADMIN,
141
141
  roles={RoleNames.MONITOR},
142
142
  privileges={
@@ -154,16 +154,16 @@ MonitorUser = MongoDBUser(
154
154
  hosts={LOCALHOST}, # MongoDB Exporter can only connect to one replica.
155
155
  )
156
156
 
157
- BackupUser = MongoDBUser(
158
- username=InternalUsernames.BACKUP,
157
+ CharmedBackupUser = MongoDBUser(
158
+ username=InternalUsernames.CHARMED_BACKUP,
159
159
  roles={RoleNames.BACKUP},
160
160
  privileges={"resource": {"anyResource": True}, "actions": ["anyAction"]},
161
161
  mongodb_role="pbmAnyAction",
162
162
  hosts={LOCALHOST}, # pbm cannot make a direct connection if multiple hosts are used
163
163
  )
164
164
 
165
- LogRotateUser = MongoDBUser(
166
- username=InternalUsernames.LOGROTATE,
165
+ CharmedLogRotateUser = MongoDBUser(
166
+ username=InternalUsernames.CHARMED_LOGROTATE,
167
167
  database_name=SystemDBS.ADMIN,
168
168
  roles={RoleNames.LOGROTATE},
169
169
  privileges={"resource": {"cluster": True}, "actions": ["logRotate"]},
@@ -172,10 +172,10 @@ LogRotateUser = MongoDBUser(
172
172
  )
173
173
 
174
174
  InternalUsers = (
175
- OperatorUser,
176
- BackupUser,
177
- MonitorUser,
178
- LogRotateUser,
175
+ CharmedOperatorUser,
176
+ CharmedBackupUser,
177
+ CharmedStatsUser,
178
+ CharmedLogRotateUser,
179
179
  )
180
180
 
181
181
 
@@ -185,14 +185,14 @@ def get_user_from_username(username: str) -> MongoDBUser:
185
185
  Raises:
186
186
  ValueError: If the username is not one of the known users.
187
187
  """
188
- if username == OperatorUser.username:
189
- return OperatorUser
190
- if username == MonitorUser.username:
191
- return MonitorUser
192
- if username == BackupUser.username:
193
- return BackupUser
194
- if username == LogRotateUser.username:
195
- return LogRotateUser
188
+ if username == CharmedOperatorUser.username:
189
+ return CharmedOperatorUser
190
+ if username == CharmedStatsUser.username:
191
+ return CharmedStatsUser
192
+ if username == CharmedBackupUser.username:
193
+ return CharmedBackupUser
194
+ if username == CharmedLogRotateUser.username:
195
+ return CharmedLogRotateUser
196
196
  raise ValueError(f"Unknown user: {username}")
197
197
 
198
198