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.
- {mongo_charms_single_kernel-1.8.9.dist-info → mongo_charms_single_kernel-1.8.11.dist-info}/METADATA +1 -1
- {mongo_charms_single_kernel-1.8.9.dist-info → mongo_charms_single_kernel-1.8.11.dist-info}/RECORD +19 -19
- single_kernel_mongo/config/literals.py +5 -5
- single_kernel_mongo/core/abstract_upgrades_v3.py +11 -3
- single_kernel_mongo/core/operator.py +7 -0
- single_kernel_mongo/core/version_checker.py +0 -12
- single_kernel_mongo/managers/config.py +10 -6
- single_kernel_mongo/managers/mongo.py +11 -11
- single_kernel_mongo/managers/mongodb_operator.py +26 -31
- single_kernel_mongo/managers/mongos_operator.py +25 -18
- single_kernel_mongo/managers/sharding.py +27 -29
- single_kernel_mongo/managers/upgrade_v3.py +32 -10
- single_kernel_mongo/managers/upgrade_v3_status.py +8 -5
- single_kernel_mongo/state/charm_state.py +15 -15
- single_kernel_mongo/state/config_server_state.py +6 -6
- single_kernel_mongo/state/models.py +2 -2
- single_kernel_mongo/utils/mongodb_users.py +20 -20
- {mongo_charms_single_kernel-1.8.9.dist-info → mongo_charms_single_kernel-1.8.11.dist-info}/WHEEL +0 -0
- {mongo_charms_single_kernel-1.8.9.dist-info → mongo_charms_single_kernel-1.8.11.dist-info}/licenses/LICENSE +0 -0
{mongo_charms_single_kernel-1.8.9.dist-info → mongo_charms_single_kernel-1.8.11.dist-info}/RECORD
RENAMED
|
@@ -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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
48
|
-
single_kernel_mongo/managers/mongodb_operator.py,sha256=
|
|
49
|
-
single_kernel_mongo/managers/mongos_operator.py,sha256=
|
|
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=
|
|
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=
|
|
54
|
-
single_kernel_mongo/managers/upgrade_v3_status.py,sha256=
|
|
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
|
|
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=
|
|
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=
|
|
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=
|
|
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.
|
|
89
|
-
mongo_charms_single_kernel-1.8.
|
|
90
|
-
mongo_charms_single_kernel-1.8.
|
|
91
|
-
mongo_charms_single_kernel-1.8.
|
|
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
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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"{
|
|
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
|
|
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(
|
|
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(
|
|
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.
|
|
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(
|
|
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.
|
|
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
|
-
|
|
56
|
-
|
|
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.
|
|
142
|
-
self.initialise_user(
|
|
143
|
-
self.initialise_user(
|
|
144
|
-
self.initialise_user(
|
|
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
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
723
|
-
# units receiving a relation changed event. We must update
|
|
724
|
-
# and pbm URI if the password changes so that COS/pbm can
|
|
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 ==
|
|
915
|
+
if user == CharmedBackupUser:
|
|
916
916
|
# Update and restart PBM Agent.
|
|
917
917
|
self.backup_manager.configure_and_restart()
|
|
918
|
-
if user ==
|
|
918
|
+
if user == CharmedStatsUser:
|
|
919
919
|
# Update and restart mongodb exporter.
|
|
920
920
|
self.mongodb_exporter_config_manager.configure_and_restart()
|
|
921
|
-
if user ==
|
|
921
|
+
if user == CharmedLogRotateUser:
|
|
922
922
|
# Update and restart logrotate.
|
|
923
923
|
self.logrotate_config_manager.configure_and_restart()
|
|
924
|
-
if user in (
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
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
|
-
|
|
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
|
-
|
|
106
|
+
CharmedOperatorUser
|
|
112
107
|
),
|
|
113
108
|
AppShardingComponentKeys.BACKUP_PASSWORD.value: self.state.get_user_password(
|
|
114
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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(
|
|
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 (
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
|
733
|
-
"""Mongo Configuration for the
|
|
734
|
-
return self.mongodb_config_for_user(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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)
|
|
@@ -129,14 +129,14 @@ class MongoDBUser(BaseModel):
|
|
|
129
129
|
return self.hosts
|
|
130
130
|
|
|
131
131
|
|
|
132
|
-
|
|
133
|
-
username=InternalUsernames.
|
|
132
|
+
CharmedOperatorUser = MongoDBUser(
|
|
133
|
+
username=InternalUsernames.CHARMED_OPERATOR,
|
|
134
134
|
database_name=SystemDBS.ADMIN,
|
|
135
135
|
roles={RoleNames.DEFAULT},
|
|
136
136
|
)
|
|
137
137
|
|
|
138
|
-
|
|
139
|
-
username=InternalUsernames.
|
|
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
|
-
|
|
158
|
-
username=InternalUsernames.
|
|
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
|
-
|
|
166
|
-
username=InternalUsernames.
|
|
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
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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 ==
|
|
189
|
-
return
|
|
190
|
-
if username ==
|
|
191
|
-
return
|
|
192
|
-
if username ==
|
|
193
|
-
return
|
|
194
|
-
if username ==
|
|
195
|
-
return
|
|
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
|
|
{mongo_charms_single_kernel-1.8.9.dist-info → mongo_charms_single_kernel-1.8.11.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|