mongo-charms-single-kernel 1.8.6__py3-none-any.whl → 1.8.7__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.6.dist-info → mongo_charms_single_kernel-1.8.7.dist-info}/METADATA +2 -1
- {mongo_charms_single_kernel-1.8.6.dist-info → mongo_charms_single_kernel-1.8.7.dist-info}/RECORD +38 -39
- single_kernel_mongo/abstract_charm.py +8 -0
- single_kernel_mongo/config/literals.py +1 -20
- single_kernel_mongo/config/relations.py +0 -1
- single_kernel_mongo/config/statuses.py +10 -57
- single_kernel_mongo/core/abstract_upgrades_v3.py +149 -0
- single_kernel_mongo/core/k8s_workload.py +2 -2
- single_kernel_mongo/core/kubernetes_upgrades_v3.py +17 -0
- single_kernel_mongo/core/machine_upgrades_v3.py +54 -0
- single_kernel_mongo/core/operator.py +25 -4
- single_kernel_mongo/core/version_checker.py +7 -6
- single_kernel_mongo/core/vm_workload.py +30 -13
- single_kernel_mongo/core/workload.py +17 -19
- single_kernel_mongo/events/backups.py +3 -3
- single_kernel_mongo/events/cluster.py +1 -1
- single_kernel_mongo/events/database.py +1 -1
- single_kernel_mongo/events/lifecycle.py +5 -4
- single_kernel_mongo/events/tls.py +7 -4
- single_kernel_mongo/exceptions.py +4 -24
- single_kernel_mongo/managers/cluster.py +8 -8
- single_kernel_mongo/managers/config.py +5 -3
- single_kernel_mongo/managers/ldap.py +2 -1
- single_kernel_mongo/managers/mongo.py +48 -9
- single_kernel_mongo/managers/mongodb_operator.py +195 -67
- single_kernel_mongo/managers/mongos_operator.py +95 -35
- single_kernel_mongo/managers/sharding.py +4 -4
- single_kernel_mongo/managers/tls.py +54 -27
- single_kernel_mongo/managers/upgrade_v3.py +452 -0
- single_kernel_mongo/managers/upgrade_v3_status.py +133 -0
- single_kernel_mongo/state/app_peer_state.py +12 -2
- single_kernel_mongo/state/charm_state.py +31 -141
- single_kernel_mongo/state/config_server_state.py +0 -33
- single_kernel_mongo/state/unit_peer_state.py +10 -0
- single_kernel_mongo/utils/helpers.py +0 -6
- single_kernel_mongo/utils/mongo_config.py +32 -8
- single_kernel_mongo/core/abstract_upgrades.py +0 -890
- single_kernel_mongo/core/kubernetes_upgrades.py +0 -194
- single_kernel_mongo/core/machine_upgrades.py +0 -188
- single_kernel_mongo/events/upgrades.py +0 -157
- single_kernel_mongo/managers/upgrade.py +0 -334
- single_kernel_mongo/state/upgrade_state.py +0 -134
- {mongo_charms_single_kernel-1.8.6.dist-info → mongo_charms_single_kernel-1.8.7.dist-info}/WHEEL +0 -0
- {mongo_charms_single_kernel-1.8.6.dist-info → mongo_charms_single_kernel-1.8.7.dist-info}/licenses/LICENSE +0 -0
|
@@ -23,7 +23,6 @@ from pymongo.errors import (
|
|
|
23
23
|
|
|
24
24
|
from single_kernel_mongo.config.literals import (
|
|
25
25
|
SECRETS_UNIT,
|
|
26
|
-
SNAP,
|
|
27
26
|
CharmKind,
|
|
28
27
|
MongoPorts,
|
|
29
28
|
Scope,
|
|
@@ -67,13 +66,8 @@ from single_kernel_mongo.state.tls_state import TLSState
|
|
|
67
66
|
from single_kernel_mongo.state.unit_peer_state import (
|
|
68
67
|
UnitPeerReplicaSet,
|
|
69
68
|
)
|
|
70
|
-
from single_kernel_mongo.state.upgrade_state import (
|
|
71
|
-
AppUpgradePeerData,
|
|
72
|
-
UnitUpgradePeerData,
|
|
73
|
-
)
|
|
74
69
|
from single_kernel_mongo.utils.helpers import (
|
|
75
70
|
generate_relation_departed_key,
|
|
76
|
-
unit_number,
|
|
77
71
|
)
|
|
78
72
|
from single_kernel_mongo.utils.mongo_config import MongoConfiguration
|
|
79
73
|
from single_kernel_mongo.utils.mongo_connection import MongoConnection
|
|
@@ -143,12 +137,6 @@ class CharmState(Object, StatusesStateProtocol):
|
|
|
143
137
|
self.ldap_peer_relation_name,
|
|
144
138
|
)
|
|
145
139
|
|
|
146
|
-
self.upgrade_app_interface = DataPeerData(
|
|
147
|
-
self.model, relation_name=RelationNames.UPGRADE_VERSION.value
|
|
148
|
-
)
|
|
149
|
-
self.upgrade_unit_interface = DataPeerUnitData(
|
|
150
|
-
self.model, relation_name=RelationNames.UPGRADE_VERSION.value
|
|
151
|
-
)
|
|
152
140
|
self.paths = MongoPaths(self.charm_role)
|
|
153
141
|
|
|
154
142
|
self.k8s_manager = K8sManager(
|
|
@@ -184,6 +172,13 @@ class CharmState(Object, StatusesStateProtocol):
|
|
|
184
172
|
return set()
|
|
185
173
|
return self.peer_relation.units
|
|
186
174
|
|
|
175
|
+
@property
|
|
176
|
+
def reverse_order_peer_units(self) -> list[Unit]:
|
|
177
|
+
"""Units sorted in reverse order."""
|
|
178
|
+
return sorted(
|
|
179
|
+
self.peers_units, key=lambda unit: int(unit.name.split("/")[-1]), reverse=True
|
|
180
|
+
)
|
|
181
|
+
|
|
187
182
|
@property
|
|
188
183
|
def client_relations(self) -> set[Relation]:
|
|
189
184
|
"""The set of client relations.
|
|
@@ -196,11 +191,6 @@ class CharmState(Object, StatusesStateProtocol):
|
|
|
196
191
|
return set(self.model.relations[RelationNames.MONGOS_PROXY.value])
|
|
197
192
|
return set(self.model.relations[RelationNames.DATABASE.value])
|
|
198
193
|
|
|
199
|
-
@property
|
|
200
|
-
def upgrade_relation(self) -> Relation | None:
|
|
201
|
-
"""The set of upgrade relations."""
|
|
202
|
-
return self.model.get_relation(RelationNames.UPGRADE_VERSION.value)
|
|
203
|
-
|
|
204
194
|
@property
|
|
205
195
|
def mongos_cluster_relation(self) -> Relation | None:
|
|
206
196
|
"""The Mongos side of the cluster relation."""
|
|
@@ -283,48 +273,6 @@ class CharmState(Object, StatusesStateProtocol):
|
|
|
283
273
|
k8s_manager=self.k8s_manager,
|
|
284
274
|
)
|
|
285
275
|
|
|
286
|
-
@property
|
|
287
|
-
def unit_upgrade_peer_data(self) -> UnitUpgradePeerData:
|
|
288
|
-
"""This unit upgrade databag."""
|
|
289
|
-
return UnitUpgradePeerData(
|
|
290
|
-
relation=self.upgrade_relation,
|
|
291
|
-
data_interface=self.upgrade_unit_interface,
|
|
292
|
-
component=self.model.unit,
|
|
293
|
-
substrate=self.substrate,
|
|
294
|
-
)
|
|
295
|
-
|
|
296
|
-
@property
|
|
297
|
-
def app_upgrade_peer_data(self) -> AppUpgradePeerData:
|
|
298
|
-
"""The app upgrade databag."""
|
|
299
|
-
return AppUpgradePeerData(
|
|
300
|
-
relation=self.upgrade_relation,
|
|
301
|
-
data_interface=self.upgrade_app_interface,
|
|
302
|
-
component=self.model.app,
|
|
303
|
-
substrate=self.substrate,
|
|
304
|
-
)
|
|
305
|
-
|
|
306
|
-
@property
|
|
307
|
-
def units_upgrade_peer_data(self) -> list[UnitUpgradePeerData]:
|
|
308
|
-
"""Grabs all units in the current peer relation, including this unit.
|
|
309
|
-
|
|
310
|
-
Returns:
|
|
311
|
-
Sorted list of UnitUpgradePeerData in the current upgrade relation,
|
|
312
|
-
including this unit.
|
|
313
|
-
"""
|
|
314
|
-
_units = []
|
|
315
|
-
for unit, data_interface in self.upgrade_units_data_interfaces.items():
|
|
316
|
-
_units.append(
|
|
317
|
-
UnitUpgradePeerData(
|
|
318
|
-
relation=self.upgrade_relation,
|
|
319
|
-
data_interface=data_interface,
|
|
320
|
-
component=unit,
|
|
321
|
-
substrate=self.substrate,
|
|
322
|
-
)
|
|
323
|
-
)
|
|
324
|
-
_units.append(self.unit_upgrade_peer_data)
|
|
325
|
-
|
|
326
|
-
return sorted(_units, key=unit_number, reverse=True)
|
|
327
|
-
|
|
328
276
|
@property
|
|
329
277
|
def units(self) -> set[UnitPeerReplicaSet]:
|
|
330
278
|
"""Grabs all units in the current peer relation, including this unit.
|
|
@@ -432,63 +380,6 @@ class CharmState(Object, StatusesStateProtocol):
|
|
|
432
380
|
def db_initialised(self, other: bool):
|
|
433
381
|
self.app_peer_data.db_initialised = other
|
|
434
382
|
|
|
435
|
-
@property
|
|
436
|
-
def unit_workload_container_versions(self) -> dict[str, str]:
|
|
437
|
-
"""{Unit name: unique identifier for unit's workload container version}.
|
|
438
|
-
|
|
439
|
-
If and only if this version changes, the workload will restart (during upgrade or
|
|
440
|
-
rollback).
|
|
441
|
-
|
|
442
|
-
On Kubernetes, the workload & charm are upgraded together
|
|
443
|
-
On machines, the charm is upgraded before the workload
|
|
444
|
-
|
|
445
|
-
VM: container version is the snap revision.
|
|
446
|
-
K8S: container version is the stateful set hash.
|
|
447
|
-
|
|
448
|
-
This identifier should be comparable to `_app_workload_container_version` to determine if
|
|
449
|
-
the unit & app are the same workload container version.
|
|
450
|
-
"""
|
|
451
|
-
if self.substrate == Substrates.K8S:
|
|
452
|
-
return self.k8s_manager.list_revisions()
|
|
453
|
-
return {
|
|
454
|
-
unit.name: unit.snap_revision
|
|
455
|
-
for unit in self.units_upgrade_peer_data
|
|
456
|
-
if unit.snap_revision
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
@property
|
|
460
|
-
def unit_workload_container_version(self) -> str | None:
|
|
461
|
-
"""Installed snap revision for this unit."""
|
|
462
|
-
if self.substrate == Substrates.K8S:
|
|
463
|
-
return self.k8s_manager.list_revisions().get(self.model.unit.name)
|
|
464
|
-
return self.unit_upgrade_peer_data.snap_revision
|
|
465
|
-
|
|
466
|
-
@unit_workload_container_version.setter
|
|
467
|
-
def unit_workload_container_version(self, value: str):
|
|
468
|
-
if self.substrate == Substrates.VM:
|
|
469
|
-
self.unit_upgrade_peer_data.snap_revision = value
|
|
470
|
-
|
|
471
|
-
@property
|
|
472
|
-
def app_workload_container_version(self) -> str:
|
|
473
|
-
"""Unique identifier for the app's workload container version.
|
|
474
|
-
|
|
475
|
-
This should match the workload version in the current Juju app charm version.
|
|
476
|
-
|
|
477
|
-
This identifier should be comparable to `_unit_workload_container_versions` to determine if
|
|
478
|
-
the app & unit are the same workload container version.
|
|
479
|
-
"""
|
|
480
|
-
if self.substrate == Substrates.K8S:
|
|
481
|
-
return self.k8s_manager.get_revision()
|
|
482
|
-
return SNAP.revision
|
|
483
|
-
|
|
484
|
-
@property
|
|
485
|
-
def upgrade_in_progress(self) -> bool:
|
|
486
|
-
"""Is the charm in upgrade?"""
|
|
487
|
-
app_version = self.app_workload_container_version
|
|
488
|
-
unit_versions = self.unit_workload_container_versions
|
|
489
|
-
logger.debug(f"Upgrade in progress check: {app_version = } / {unit_versions = }")
|
|
490
|
-
return any(version != app_version for version in unit_versions.values())
|
|
491
|
-
|
|
492
383
|
@property
|
|
493
384
|
def bind_address(self) -> IPv4Address | IPv6Address | str:
|
|
494
385
|
"""The network binding address from the peer relation."""
|
|
@@ -541,18 +432,6 @@ class CharmState(Object, StatusesStateProtocol):
|
|
|
541
432
|
for unit in self.peers_units
|
|
542
433
|
}
|
|
543
434
|
|
|
544
|
-
@property
|
|
545
|
-
def upgrade_units_data_interfaces(self) -> dict[Unit, DataPeerOtherUnitData]:
|
|
546
|
-
"""The cluster peer relation."""
|
|
547
|
-
return {
|
|
548
|
-
unit: DataPeerOtherUnitData(
|
|
549
|
-
model=self.model,
|
|
550
|
-
unit=unit,
|
|
551
|
-
relation_name=RelationNames.UPGRADE_VERSION.value,
|
|
552
|
-
)
|
|
553
|
-
for unit in self.peers_units
|
|
554
|
-
}
|
|
555
|
-
|
|
556
435
|
@property
|
|
557
436
|
def formatted_socket_path(self) -> str:
|
|
558
437
|
"""URL encoded socket path.
|
|
@@ -657,6 +536,17 @@ class CharmState(Object, StatusesStateProtocol):
|
|
|
657
536
|
)
|
|
658
537
|
return None
|
|
659
538
|
|
|
539
|
+
def get_subject_name(self) -> str:
|
|
540
|
+
"""Generate the subject name for CSR."""
|
|
541
|
+
# In sharded MongoDB deployments it is a requirement that all subject names match across
|
|
542
|
+
# all cluster components. The config-server name is the source of truth across mongos and
|
|
543
|
+
# shard deployments.
|
|
544
|
+
if self.is_role(MongoDBRoles.REPLICATION) or self.is_role(MongoDBRoles.CONFIG_SERVER):
|
|
545
|
+
return self.model.app.name
|
|
546
|
+
# until integrated with config-server use current app name as
|
|
547
|
+
# subject name
|
|
548
|
+
return self.config_server_name or self.model.app.name
|
|
549
|
+
|
|
660
550
|
def generate_config_server_db(self) -> str:
|
|
661
551
|
"""Generates the config server DB URI."""
|
|
662
552
|
replica_set_name = self.model.app.name
|
|
@@ -709,19 +599,16 @@ class CharmState(Object, StatusesStateProtocol):
|
|
|
709
599
|
self.unit_peer_data.update({rel_departed_key: json.dumps(scaling_down)})
|
|
710
600
|
return scaling_down
|
|
711
601
|
|
|
712
|
-
@property
|
|
713
|
-
def upgrade_resumed(self) -> bool:
|
|
714
|
-
"""Whether the user has resumed upgrade with juju action."""
|
|
715
|
-
if self.substrate == Substrates.K8S:
|
|
716
|
-
return self.k8s_manager.get_partition() < unit_number(self.units_upgrade_peer_data[0])
|
|
717
|
-
return self.app_upgrade_peer_data.upgrade_resumed
|
|
718
|
-
|
|
719
602
|
def is_shard_added_to_cluster(self) -> bool:
|
|
720
603
|
"""Returns true if the shard has been added to the clusted."""
|
|
721
604
|
# this information is required in order to check if we have been added
|
|
722
605
|
if not self.config_server_name or not self.app_peer_data.mongos_hosts:
|
|
723
606
|
return False
|
|
724
607
|
|
|
608
|
+
# We can't check if we don't have a valid certificate
|
|
609
|
+
if self.shard_state.internal_ca_secret is not None and not self.tls.external_enabled:
|
|
610
|
+
return False
|
|
611
|
+
|
|
725
612
|
try:
|
|
726
613
|
# check our ability to use connect to mongos
|
|
727
614
|
with MongoConnection(self.remote_mongos_config) as mongos:
|
|
@@ -778,8 +665,9 @@ class CharmState(Object, StatusesStateProtocol):
|
|
|
778
665
|
hosts=hosts or user.hosts,
|
|
779
666
|
port=MongoPorts.MONGODB_PORT.value,
|
|
780
667
|
roles=user.roles,
|
|
781
|
-
|
|
782
|
-
|
|
668
|
+
tls_enabled=self.tls.external_enabled,
|
|
669
|
+
tls_external_keyfile=self.paths.ext_pem_file,
|
|
670
|
+
tls_external_ca=self.paths.ext_ca_file,
|
|
783
671
|
standalone=standalone,
|
|
784
672
|
)
|
|
785
673
|
|
|
@@ -807,8 +695,9 @@ class CharmState(Object, StatusesStateProtocol):
|
|
|
807
695
|
hosts=hosts or user.hosts,
|
|
808
696
|
port=MongoPorts.MONGOS_PORT.value,
|
|
809
697
|
roles=user.roles,
|
|
810
|
-
|
|
811
|
-
|
|
698
|
+
tls_enabled=self.tls.external_enabled,
|
|
699
|
+
tls_external_keyfile=self.paths.ext_pem_file,
|
|
700
|
+
tls_external_ca=self.paths.ext_ca_file,
|
|
812
701
|
)
|
|
813
702
|
|
|
814
703
|
@property
|
|
@@ -862,8 +751,9 @@ class CharmState(Object, StatusesStateProtocol):
|
|
|
862
751
|
# unlike the vm mongos charm, the K8s charm does not communicate with the unix socket
|
|
863
752
|
port=port,
|
|
864
753
|
roles={RoleNames.ADMIN},
|
|
865
|
-
|
|
866
|
-
|
|
754
|
+
tls_enabled=self.tls.external_enabled,
|
|
755
|
+
tls_external_keyfile=self.paths.ext_pem_file,
|
|
756
|
+
tls_external_ca=self.paths.ext_ca_file,
|
|
867
757
|
)
|
|
868
758
|
|
|
869
759
|
@property
|
|
@@ -39,12 +39,6 @@ SECRETS_FIELDS = [
|
|
|
39
39
|
]
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
class UnitShardingComponentKeys(str, Enum):
|
|
43
|
-
"""Config Server State Model for the unit."""
|
|
44
|
-
|
|
45
|
-
STATUS_READY_FOR_UPGRADE = "status-shows-ready-for-upgrade"
|
|
46
|
-
|
|
47
|
-
|
|
48
42
|
class AppShardingComponentState(AbstractRelationState[Data]):
|
|
49
43
|
"""The stored state for the ConfigServer Relation."""
|
|
50
44
|
|
|
@@ -120,30 +114,3 @@ class UnitShardingComponentState(AbstractRelationState[Data]):
|
|
|
120
114
|
def __init__(self, relation: Relation | None, data_interface: Data, component: Unit):
|
|
121
115
|
super().__init__(relation, data_interface=data_interface, component=component)
|
|
122
116
|
self.data_interface = data_interface
|
|
123
|
-
|
|
124
|
-
@property
|
|
125
|
-
def status_ready_for_upgrade(self) -> bool:
|
|
126
|
-
"""Returns true if the shard is ready for upgrade.
|
|
127
|
-
|
|
128
|
-
Legacy: for old upgrades that require status from shards.
|
|
129
|
-
"""
|
|
130
|
-
if not self.relation:
|
|
131
|
-
return True
|
|
132
|
-
# We get directly the data in the unit because it's hidden otherwise
|
|
133
|
-
return json.loads(
|
|
134
|
-
self.relation.data[self.component].get(
|
|
135
|
-
UnitShardingComponentKeys.STATUS_READY_FOR_UPGRADE.value, "false"
|
|
136
|
-
)
|
|
137
|
-
)
|
|
138
|
-
|
|
139
|
-
@status_ready_for_upgrade.setter
|
|
140
|
-
def status_ready_for_upgrade(self, value: bool):
|
|
141
|
-
"""Sets old status.
|
|
142
|
-
|
|
143
|
-
Legacy: for old upgrades that require status from shards.
|
|
144
|
-
"""
|
|
145
|
-
if not self.relation:
|
|
146
|
-
raise Exception("No databag to write in")
|
|
147
|
-
self.relation.data[self.component][
|
|
148
|
-
UnitShardingComponentKeys.STATUS_READY_FOR_UPGRADE.value
|
|
149
|
-
] = json.dumps(value)
|
|
@@ -23,6 +23,7 @@ class UnitPeerRelationKeys(str, Enum):
|
|
|
23
23
|
INGRESS_ADDRESS = "ingress-address"
|
|
24
24
|
EGRESS_SUBNETS = "egress-subnets"
|
|
25
25
|
DRAINED = "drained"
|
|
26
|
+
CURRENT_REVISION = "current_revision"
|
|
26
27
|
|
|
27
28
|
|
|
28
29
|
class UnitPeerReplicaSet(AbstractRelationState[DataPeerUnitData]):
|
|
@@ -112,3 +113,12 @@ class UnitPeerReplicaSet(AbstractRelationState[DataPeerUnitData]):
|
|
|
112
113
|
if not isinstance(value, bool):
|
|
113
114
|
raise ValueError(f"drained value is not boolean but {value}")
|
|
114
115
|
self.update({UnitPeerRelationKeys.DRAINED.value: json.dumps(value)})
|
|
116
|
+
|
|
117
|
+
@property
|
|
118
|
+
def current_revision(self) -> str:
|
|
119
|
+
"""The revision of the charm that's running before the upgrade."""
|
|
120
|
+
return self.relation_data.get(UnitPeerRelationKeys.CURRENT_REVISION, "-1")
|
|
121
|
+
|
|
122
|
+
@current_revision.setter
|
|
123
|
+
def current_revision(self, value: str):
|
|
124
|
+
self.update({UnitPeerRelationKeys.CURRENT_REVISION.value: value})
|
|
@@ -14,7 +14,6 @@ from pydantic import ValidationError
|
|
|
14
14
|
from single_kernel_mongo.config.literals import CharmKind, Substrates
|
|
15
15
|
from single_kernel_mongo.core.structured_config import LdapUserToDnMapping
|
|
16
16
|
from single_kernel_mongo.exceptions import InvalidCharmKindError
|
|
17
|
-
from single_kernel_mongo.state.upgrade_state import UnitUpgradePeerData
|
|
18
17
|
|
|
19
18
|
logger = getLogger(__name__)
|
|
20
19
|
|
|
@@ -62,11 +61,6 @@ def hostname_from_shardname(host: str) -> str:
|
|
|
62
61
|
return host.split("/")[0]
|
|
63
62
|
|
|
64
63
|
|
|
65
|
-
def unit_number(unit: UnitUpgradePeerData) -> int:
|
|
66
|
-
"""Gets the unit number from a unit upgrade peer data."""
|
|
67
|
-
return int(unit.component.name.split("/")[-1])
|
|
68
|
-
|
|
69
|
-
|
|
70
64
|
def is_valid_ldapusertodnmapping(ldap_user_to_dn_mapping: str) -> bool:
|
|
71
65
|
"""Validates the mapping, returning a boolean."""
|
|
72
66
|
if not ldap_user_to_dn_mapping:
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
from dataclasses import dataclass
|
|
6
6
|
from itertools import chain
|
|
7
|
+
from pathlib import Path
|
|
7
8
|
from urllib.parse import quote_plus, urlencode
|
|
8
9
|
|
|
9
10
|
from single_kernel_mongo.config.literals import MongoPorts
|
|
@@ -35,8 +36,9 @@ class MongoConfiguration:
|
|
|
35
36
|
password: str
|
|
36
37
|
hosts: set[str]
|
|
37
38
|
roles: set[str]
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
tls_enabled: bool
|
|
40
|
+
tls_external_keyfile: Path = Path("")
|
|
41
|
+
tls_external_ca: Path = Path("")
|
|
40
42
|
port: int | None = None
|
|
41
43
|
replset: str | None = None
|
|
42
44
|
standalone: bool = False
|
|
@@ -63,27 +65,38 @@ class MongoConfiguration:
|
|
|
63
65
|
return {}
|
|
64
66
|
|
|
65
67
|
@property
|
|
66
|
-
def
|
|
67
|
-
"""
|
|
68
|
+
def tls_config(self) -> dict:
|
|
69
|
+
"""TLS Config."""
|
|
70
|
+
if not self.tls_enabled:
|
|
71
|
+
return {}
|
|
72
|
+
return {
|
|
73
|
+
"tls": "true",
|
|
74
|
+
"tlsCertificateKeyFile": f"{self.tls_external_keyfile}",
|
|
75
|
+
"tlsCaFile": f"{self.tls_external_ca}",
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
def _uri(self, tls: bool):
|
|
68
79
|
if self.port == MongoPorts.MONGOS_PORT and self.replset:
|
|
69
80
|
raise AmbiguousConfigError("Mongos cannot support replica set")
|
|
70
81
|
|
|
71
82
|
if self.standalone and not self.port:
|
|
72
83
|
raise AmbiguousConfigError("Standalone connection needs a port")
|
|
73
84
|
|
|
85
|
+
tls_config = self.tls_config if tls else {}
|
|
86
|
+
auth_source = self.formatted_auth_source
|
|
87
|
+
|
|
74
88
|
if self.standalone:
|
|
75
89
|
return (
|
|
76
90
|
f"mongodb://{quote_plus(self.username)}:"
|
|
77
91
|
f"{quote_plus(self.password)}@"
|
|
78
|
-
f"localhost:{self.port}/?
|
|
92
|
+
f"localhost:{self.port}/?{urlencode(auth_source | tls_config)}"
|
|
79
93
|
)
|
|
80
94
|
|
|
81
95
|
complete_hosts = ",".join(sorted(self.formatted_hosts))
|
|
82
96
|
replset = self.formatted_replset
|
|
83
|
-
auth_source = self.formatted_auth_source
|
|
84
97
|
|
|
85
98
|
# Dict of all parameters.
|
|
86
|
-
parameters = replset | auth_source
|
|
99
|
+
parameters = replset | auth_source | tls_config
|
|
87
100
|
|
|
88
101
|
return (
|
|
89
102
|
f"mongodb://{quote_plus(self.username)}:"
|
|
@@ -92,6 +105,16 @@ class MongoConfiguration:
|
|
|
92
105
|
f"{urlencode(parameters)}"
|
|
93
106
|
)
|
|
94
107
|
|
|
108
|
+
@property
|
|
109
|
+
def uri(self) -> str:
|
|
110
|
+
"""Return URI concatenated from fields."""
|
|
111
|
+
return self._uri(tls=True)
|
|
112
|
+
|
|
113
|
+
@property
|
|
114
|
+
def uri_without_tls(self) -> str:
|
|
115
|
+
"""Return URI concatenated from fields without tls params."""
|
|
116
|
+
return self._uri(tls=False)
|
|
117
|
+
|
|
95
118
|
@property
|
|
96
119
|
def supported_roles(self) -> list[DBPrivilege]:
|
|
97
120
|
"""The supported roles for this configuration."""
|
|
@@ -112,5 +135,6 @@ EMPTY_CONFIGURATION = MongoConfiguration(
|
|
|
112
135
|
set(),
|
|
113
136
|
set(),
|
|
114
137
|
False,
|
|
115
|
-
|
|
138
|
+
Path(""),
|
|
139
|
+
Path(""),
|
|
116
140
|
)
|