mongo-charms-single-kernel 1.8.8__py3-none-any.whl → 1.8.10__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.8.dist-info → mongo_charms_single_kernel-1.8.10.dist-info}/METADATA +1 -1
- {mongo_charms_single_kernel-1.8.8.dist-info → mongo_charms_single_kernel-1.8.10.dist-info}/RECORD +30 -30
- single_kernel_mongo/config/literals.py +12 -5
- single_kernel_mongo/config/relations.py +2 -1
- single_kernel_mongo/config/statuses.py +127 -20
- single_kernel_mongo/core/operator.py +7 -0
- single_kernel_mongo/core/structured_config.py +2 -0
- single_kernel_mongo/core/workload.py +10 -4
- single_kernel_mongo/events/cluster.py +5 -0
- single_kernel_mongo/events/sharding.py +3 -1
- single_kernel_mongo/events/tls.py +183 -157
- single_kernel_mongo/exceptions.py +0 -8
- single_kernel_mongo/lib/charms/tls_certificates_interface/v4/tls_certificates.py +1995 -0
- single_kernel_mongo/managers/cluster.py +70 -28
- single_kernel_mongo/managers/config.py +24 -14
- single_kernel_mongo/managers/mongo.py +12 -12
- single_kernel_mongo/managers/mongodb_operator.py +58 -34
- single_kernel_mongo/managers/mongos_operator.py +16 -20
- single_kernel_mongo/managers/sharding.py +172 -136
- single_kernel_mongo/managers/tls.py +223 -206
- single_kernel_mongo/managers/upgrade_v3.py +6 -6
- single_kernel_mongo/state/charm_state.py +54 -31
- single_kernel_mongo/state/cluster_state.py +8 -0
- single_kernel_mongo/state/config_server_state.py +15 -6
- single_kernel_mongo/state/models.py +2 -2
- single_kernel_mongo/state/tls_state.py +39 -12
- single_kernel_mongo/utils/helpers.py +4 -19
- single_kernel_mongo/utils/mongodb_users.py +20 -20
- single_kernel_mongo/lib/charms/tls_certificates_interface/v3/tls_certificates.py +0 -2123
- {mongo_charms_single_kernel-1.8.8.dist-info → mongo_charms_single_kernel-1.8.10.dist-info}/WHEEL +0 -0
- {mongo_charms_single_kernel-1.8.8.dist-info → mongo_charms_single_kernel-1.8.10.dist-info}/licenses/LICENSE +0 -0
|
@@ -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
|
|
|
@@ -212,9 +212,14 @@ class CharmState(Object, StatusesStateProtocol):
|
|
|
212
212
|
return set(self.model.relations[RelationNames.CONFIG_SERVER.value])
|
|
213
213
|
|
|
214
214
|
@property
|
|
215
|
-
def
|
|
216
|
-
"""The TLS relation."""
|
|
217
|
-
return self.model.get_relation(ExternalRequirerRelations.
|
|
215
|
+
def client_tls_relation(self) -> Relation | None:
|
|
216
|
+
"""The client TLS relation if it exists."""
|
|
217
|
+
return self.model.get_relation(ExternalRequirerRelations.CLIENT_TLS.value)
|
|
218
|
+
|
|
219
|
+
@property
|
|
220
|
+
def peer_tls_relation(self) -> Relation | None:
|
|
221
|
+
"""The peer TLS relation if it exists."""
|
|
222
|
+
return self.model.get_relation(ExternalRequirerRelations.PEER_TLS.value)
|
|
218
223
|
|
|
219
224
|
@property
|
|
220
225
|
def s3_relation(self) -> Relation | None:
|
|
@@ -342,7 +347,11 @@ class CharmState(Object, StatusesStateProtocol):
|
|
|
342
347
|
@property
|
|
343
348
|
def tls(self) -> TLSState:
|
|
344
349
|
"""A view of the TLS status from the local unit databag."""
|
|
345
|
-
return TLSState(
|
|
350
|
+
return TLSState(
|
|
351
|
+
peer_relation=self.peer_tls_relation,
|
|
352
|
+
client_relation=self.client_tls_relation,
|
|
353
|
+
secrets=self.secrets,
|
|
354
|
+
)
|
|
346
355
|
|
|
347
356
|
@property
|
|
348
357
|
def ldap(self) -> LdapState:
|
|
@@ -554,8 +563,8 @@ class CharmState(Object, StatusesStateProtocol):
|
|
|
554
563
|
return f"{replica_set_name}/{','.join(hosts)}"
|
|
555
564
|
|
|
556
565
|
# END: Helpers
|
|
557
|
-
def
|
|
558
|
-
"""Updates the CA secret
|
|
566
|
+
def _update_ca_secrets(self, new_ca: str | None, cluster_key: str, sharding_key: str) -> None:
|
|
567
|
+
"""Updates the CA secret for the right values on the right fields."""
|
|
559
568
|
# Only the leader can update the databag
|
|
560
569
|
if not self.charm.unit.is_leader():
|
|
561
570
|
return
|
|
@@ -564,22 +573,36 @@ class CharmState(Object, StatusesStateProtocol):
|
|
|
564
573
|
for relation in self.cluster_relations:
|
|
565
574
|
if new_ca is None:
|
|
566
575
|
self.cluster_provider_data_interface.delete_relation_data(
|
|
567
|
-
relation.id, [
|
|
576
|
+
relation.id, [cluster_key]
|
|
568
577
|
)
|
|
569
578
|
else:
|
|
570
579
|
self.cluster_provider_data_interface.update_relation_data(
|
|
571
|
-
relation.id, {
|
|
580
|
+
relation.id, {cluster_key: new_ca}
|
|
572
581
|
)
|
|
573
582
|
for relation in self.config_server_relation:
|
|
574
583
|
if new_ca is None:
|
|
575
|
-
self.config_server_data_interface.delete_relation_data(
|
|
576
|
-
relation.id, [AppShardingComponentKeys.INT_CA_SECRET.value]
|
|
577
|
-
)
|
|
584
|
+
self.config_server_data_interface.delete_relation_data(relation.id, [sharding_key])
|
|
578
585
|
else:
|
|
579
586
|
self.config_server_data_interface.update_relation_data(
|
|
580
|
-
relation.id, {
|
|
587
|
+
relation.id, {sharding_key: new_ca}
|
|
581
588
|
)
|
|
582
589
|
|
|
590
|
+
def update_peer_ca_secrets(self, new_ca: str | None) -> None:
|
|
591
|
+
"""Updates the peer CA secret in the cluster and config-server relations."""
|
|
592
|
+
self._update_ca_secrets(
|
|
593
|
+
new_ca=new_ca,
|
|
594
|
+
cluster_key=ClusterStateKeys.INT_CA_SECRET.value,
|
|
595
|
+
sharding_key=AppShardingComponentKeys.INT_CA_SECRET.value,
|
|
596
|
+
)
|
|
597
|
+
|
|
598
|
+
def update_client_ca_secrets(self, new_ca: str | None) -> None:
|
|
599
|
+
"""Updates the client CA secret in the cluster and config-server relations."""
|
|
600
|
+
self._update_ca_secrets(
|
|
601
|
+
new_ca=new_ca,
|
|
602
|
+
cluster_key=ClusterStateKeys.EXT_CA_SECRET.value,
|
|
603
|
+
sharding_key=AppShardingComponentKeys.EXT_CA_SECRET.value,
|
|
604
|
+
)
|
|
605
|
+
|
|
583
606
|
def is_scaling_down(self, rel_id: int) -> bool:
|
|
584
607
|
"""Returns True if the application is scaling down."""
|
|
585
608
|
rel_departed_key = generate_relation_departed_key(rel_id)
|
|
@@ -606,7 +629,7 @@ class CharmState(Object, StatusesStateProtocol):
|
|
|
606
629
|
return False
|
|
607
630
|
|
|
608
631
|
# We can't check if we don't have a valid certificate
|
|
609
|
-
if self.shard_state.
|
|
632
|
+
if self.shard_state.external_ca_secret is not None and not self.tls.client_enabled:
|
|
610
633
|
return False
|
|
611
634
|
|
|
612
635
|
try:
|
|
@@ -665,7 +688,7 @@ class CharmState(Object, StatusesStateProtocol):
|
|
|
665
688
|
hosts=hosts or user.hosts,
|
|
666
689
|
port=MongoPorts.MONGODB_PORT.value,
|
|
667
690
|
roles=user.roles,
|
|
668
|
-
tls_enabled=self.tls.
|
|
691
|
+
tls_enabled=self.tls.client_enabled,
|
|
669
692
|
tls_external_keyfile=self.paths.ext_pem_file,
|
|
670
693
|
tls_external_ca=self.paths.ext_ca_file,
|
|
671
694
|
standalone=standalone,
|
|
@@ -695,42 +718,42 @@ class CharmState(Object, StatusesStateProtocol):
|
|
|
695
718
|
hosts=hosts or user.hosts,
|
|
696
719
|
port=MongoPorts.MONGOS_PORT.value,
|
|
697
720
|
roles=user.roles,
|
|
698
|
-
tls_enabled=self.tls.
|
|
721
|
+
tls_enabled=self.tls.client_enabled,
|
|
699
722
|
tls_external_keyfile=self.paths.ext_pem_file,
|
|
700
723
|
tls_external_ca=self.paths.ext_ca_file,
|
|
701
724
|
)
|
|
702
725
|
|
|
703
726
|
@property
|
|
704
727
|
def backup_config(self) -> MongoConfiguration:
|
|
705
|
-
"""Mongo Configuration for the backup user."""
|
|
706
|
-
return self.mongodb_config_for_user(
|
|
728
|
+
"""Mongo Configuration for the charmed-backup user."""
|
|
729
|
+
return self.mongodb_config_for_user(CharmedBackupUser, standalone=True)
|
|
707
730
|
|
|
708
731
|
@property
|
|
709
|
-
def
|
|
710
|
-
"""Mongo Configuration for the
|
|
711
|
-
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)
|
|
712
735
|
|
|
713
736
|
@property
|
|
714
737
|
def logrotate_config(self) -> MongoConfiguration:
|
|
715
|
-
"""Mongo Configuration for the logrotate user."""
|
|
716
|
-
return self.mongodb_config_for_user(
|
|
738
|
+
"""Mongo Configuration for the charmed-logrotate user."""
|
|
739
|
+
return self.mongodb_config_for_user(CharmedLogRotateUser, standalone=True)
|
|
717
740
|
|
|
718
741
|
@property
|
|
719
742
|
def operator_config(self) -> MongoConfiguration:
|
|
720
|
-
"""Mongo Configuration for the operator user."""
|
|
721
|
-
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)
|
|
722
745
|
|
|
723
746
|
@property
|
|
724
747
|
def remote_mongos_config(self) -> MongoConfiguration:
|
|
725
748
|
"""Mongos Configuration for the remote mongos server."""
|
|
726
749
|
mongos_hosts = self.app_peer_data.mongos_hosts
|
|
727
|
-
return self.mongos_config_for_user(
|
|
750
|
+
return self.mongos_config_for_user(CharmedOperatorUser, set(mongos_hosts))
|
|
728
751
|
|
|
729
752
|
@property
|
|
730
753
|
def mongos_config(self) -> MongoConfiguration:
|
|
731
754
|
"""Mongos Configuration for the admin mongos user."""
|
|
732
755
|
if self.charm_role.name == CharmKind.MONGOD:
|
|
733
|
-
return self.mongos_config_for_user(
|
|
756
|
+
return self.mongos_config_for_user(CharmedOperatorUser, self.internal_hosts)
|
|
734
757
|
username, password = self.get_user_credentials()
|
|
735
758
|
database = self.app_peer_data.database
|
|
736
759
|
port: int | None = MongoPorts.MONGOS_PORT.value
|
|
@@ -751,7 +774,7 @@ class CharmState(Object, StatusesStateProtocol):
|
|
|
751
774
|
# unlike the vm mongos charm, the K8s charm does not communicate with the unix socket
|
|
752
775
|
port=port,
|
|
753
776
|
roles={RoleNames.ADMIN},
|
|
754
|
-
tls_enabled=self.tls.
|
|
777
|
+
tls_enabled=self.tls.client_enabled,
|
|
755
778
|
tls_external_keyfile=self.paths.ext_pem_file,
|
|
756
779
|
tls_external_ca=self.paths.ext_ca_file,
|
|
757
780
|
)
|
|
@@ -23,6 +23,7 @@ class ClusterStateKeys(str, Enum):
|
|
|
23
23
|
CONFIG_SERVER_DB = "config-server-db"
|
|
24
24
|
KEYFILE = "key-file"
|
|
25
25
|
INT_CA_SECRET = "int-ca-secret"
|
|
26
|
+
EXT_CA_SECRET = "ext-ca-secret"
|
|
26
27
|
LDAP_USER_TO_DN_MAPPING = "ldap-user-to-dn-mapping"
|
|
27
28
|
LDAP_HASH = "ldap-hash"
|
|
28
29
|
|
|
@@ -74,6 +75,13 @@ class ClusterState(AbstractRelationState[Data]):
|
|
|
74
75
|
return None
|
|
75
76
|
return self.relation_data.get(ClusterStateKeys.INT_CA_SECRET.value, None)
|
|
76
77
|
|
|
78
|
+
@property
|
|
79
|
+
def external_ca_secret(self) -> str | None:
|
|
80
|
+
"""Returns the external CA secret."""
|
|
81
|
+
if not self.relation:
|
|
82
|
+
return None
|
|
83
|
+
return self.relation_data.get(ClusterStateKeys.EXT_CA_SECRET.value, None)
|
|
84
|
+
|
|
77
85
|
@property
|
|
78
86
|
def ldap_user_to_dn_mapping(self) -> str | None:
|
|
79
87
|
"""Returns the userToDNMapping config option shared by the config-server."""
|
|
@@ -18,11 +18,12 @@ 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"
|
|
26
|
+
EXT_CA_SECRET = "ext-ca-secret"
|
|
26
27
|
BACKUP_CA_SECRET = "backup-ca-secret"
|
|
27
28
|
|
|
28
29
|
# We don't use those except to check if we've received credentials
|
|
@@ -31,10 +32,11 @@ class AppShardingComponentKeys(str, Enum):
|
|
|
31
32
|
|
|
32
33
|
|
|
33
34
|
SECRETS_FIELDS = [
|
|
34
|
-
"operator-password",
|
|
35
|
-
"backup-password",
|
|
35
|
+
"charmed-operator-password",
|
|
36
|
+
"charmed-backup-password",
|
|
36
37
|
"key-file",
|
|
37
38
|
"int-ca-secret",
|
|
39
|
+
"ext-ca-secret",
|
|
38
40
|
"backup-ca-secret",
|
|
39
41
|
]
|
|
40
42
|
|
|
@@ -75,6 +77,13 @@ class AppShardingComponentState(AbstractRelationState[Data]):
|
|
|
75
77
|
return None
|
|
76
78
|
return self.relation_data.get(AppShardingComponentKeys.INT_CA_SECRET.value, None)
|
|
77
79
|
|
|
80
|
+
@property
|
|
81
|
+
def external_ca_secret(self) -> str | None:
|
|
82
|
+
"""Returns the external CA secret."""
|
|
83
|
+
if not self.relation:
|
|
84
|
+
return None
|
|
85
|
+
return self.relation_data.get(AppShardingComponentKeys.EXT_CA_SECRET.value, None)
|
|
86
|
+
|
|
78
87
|
@property
|
|
79
88
|
def keyfile(self) -> str | None:
|
|
80
89
|
"""Returns the keyfile."""
|
|
@@ -84,14 +93,14 @@ class AppShardingComponentState(AbstractRelationState[Data]):
|
|
|
84
93
|
|
|
85
94
|
@property
|
|
86
95
|
def operator_password(self) -> str | None:
|
|
87
|
-
"""Returns the operator password."""
|
|
96
|
+
"""Returns the charmed-operator password."""
|
|
88
97
|
if not self.relation:
|
|
89
98
|
return None
|
|
90
99
|
return self.relation_data.get(AppShardingComponentKeys.OPERATOR_PASSWORD.value, None)
|
|
91
100
|
|
|
92
101
|
@property
|
|
93
102
|
def backup_password(self) -> str | None:
|
|
94
|
-
"""Returns the
|
|
103
|
+
"""Returns the charmed-backup password."""
|
|
95
104
|
if not self.relation:
|
|
96
105
|
return None
|
|
97
106
|
return self.relation_data.get(AppShardingComponentKeys.BACKUP_PASSWORD.value, None)
|
|
@@ -4,44 +4,59 @@
|
|
|
4
4
|
|
|
5
5
|
"""The TLS state."""
|
|
6
6
|
|
|
7
|
+
from enum import Enum
|
|
8
|
+
|
|
7
9
|
from ops import Relation
|
|
8
10
|
from ops.model import Unit
|
|
9
11
|
|
|
10
12
|
from single_kernel_mongo.config.literals import Scope
|
|
11
13
|
from single_kernel_mongo.core.secrets import SecretCache
|
|
14
|
+
from single_kernel_mongo.lib.charms.tls_certificates_interface.v4.tls_certificates import PrivateKey
|
|
12
15
|
|
|
13
16
|
SECRET_KEY_LABEL = "key-secret"
|
|
14
17
|
SECRET_CA_LABEL = "ca-secret"
|
|
15
|
-
SECRET_CERT_LABEL = "cert-secret"
|
|
16
18
|
SECRET_CSR_LABEL = "csr-secret"
|
|
19
|
+
SECRET_CERT_LABEL = "cert-secret"
|
|
17
20
|
SECRET_CHAIN_LABEL = "chain-secret"
|
|
18
|
-
WAIT_CERT_UPDATE = "wait-cert-updated"
|
|
19
21
|
INT_CERT_SECRET_KEY = "int-cert-secret"
|
|
20
22
|
EXT_CERT_SECRET_KEY = "ext-cert-secret"
|
|
21
23
|
|
|
22
24
|
|
|
25
|
+
class TlsManagementState(Enum):
|
|
26
|
+
"""TLS management state that can be mapped to a status."""
|
|
27
|
+
|
|
28
|
+
EMPTY = ""
|
|
29
|
+
UPGRADE_IN_PROGRESS = "Upgrade in progress."
|
|
30
|
+
DB_NOT_INTIALIZED = "DB is not initialized."
|
|
31
|
+
MONGOS_MISSING_CONFIG_SERVER = "mongos is not running (not integrated to config-server)."
|
|
32
|
+
MONGOS_DB_NOT_INITIALIZED = "mongos DB is not initialized."
|
|
33
|
+
|
|
34
|
+
|
|
23
35
|
class TLSState:
|
|
24
36
|
"""The stored state for the TLS relation."""
|
|
25
37
|
|
|
26
38
|
component: Unit
|
|
27
39
|
|
|
28
|
-
def __init__(
|
|
29
|
-
self
|
|
40
|
+
def __init__(
|
|
41
|
+
self, peer_relation: Relation | None, client_relation: Relation | None, secrets: SecretCache
|
|
42
|
+
):
|
|
43
|
+
self.peer_relation = peer_relation
|
|
44
|
+
self.client_relation = client_relation
|
|
30
45
|
self.secrets = secrets
|
|
31
46
|
|
|
32
47
|
@property
|
|
33
|
-
def
|
|
34
|
-
"""Is
|
|
48
|
+
def peer_enabled(self) -> bool:
|
|
49
|
+
"""Is peer TLS enabled."""
|
|
35
50
|
return (
|
|
36
|
-
self.
|
|
51
|
+
self.peer_relation is not None
|
|
37
52
|
and self.secrets.get_for_key(Scope.UNIT, INT_CERT_SECRET_KEY) is not None
|
|
38
53
|
)
|
|
39
54
|
|
|
40
55
|
@property
|
|
41
|
-
def
|
|
42
|
-
"""Is
|
|
56
|
+
def client_enabled(self) -> bool:
|
|
57
|
+
"""Is client TLS enabled."""
|
|
43
58
|
return (
|
|
44
|
-
self.
|
|
59
|
+
self.client_relation is not None
|
|
45
60
|
and self.secrets.get_for_key(Scope.UNIT, EXT_CERT_SECRET_KEY) is not None
|
|
46
61
|
)
|
|
47
62
|
|
|
@@ -49,9 +64,9 @@ class TLSState:
|
|
|
49
64
|
"""Is TLS enabled for ::internal."""
|
|
50
65
|
match internal:
|
|
51
66
|
case True:
|
|
52
|
-
return self.
|
|
67
|
+
return self.peer_enabled
|
|
53
68
|
case False:
|
|
54
|
-
return self.
|
|
69
|
+
return self.client_enabled
|
|
55
70
|
|
|
56
71
|
def set_secret(self, internal: bool, label_name: str, contents: str | None) -> None:
|
|
57
72
|
"""Sets TLS secret, based on whether or not it is related to internal connections."""
|
|
@@ -67,3 +82,15 @@ class TLSState:
|
|
|
67
82
|
scope = "int" if internal else "ext"
|
|
68
83
|
label_name = f"{scope}-{label_name}"
|
|
69
84
|
return self.secrets.get_for_key(Scope.UNIT, label_name)
|
|
85
|
+
|
|
86
|
+
@property
|
|
87
|
+
def client_private_key(self) -> PrivateKey | None:
|
|
88
|
+
"""Private key for the client relation."""
|
|
89
|
+
private_key_str = self.get_secret(internal=False, label_name=SECRET_KEY_LABEL)
|
|
90
|
+
return PrivateKey(private_key_str) if private_key_str else None
|
|
91
|
+
|
|
92
|
+
@property
|
|
93
|
+
def peer_private_key(self) -> PrivateKey | None:
|
|
94
|
+
"""Private key for the peer relation."""
|
|
95
|
+
private_key_str = self.get_secret(internal=True, label_name=SECRET_KEY_LABEL)
|
|
96
|
+
return PrivateKey(private_key_str) if private_key_str else None
|
|
@@ -4,8 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
"""Some helpers functions that doesn't belong anywhere else."""
|
|
6
6
|
|
|
7
|
-
import base64
|
|
8
|
-
import re
|
|
9
7
|
from functools import partial
|
|
10
8
|
from logging import getLogger
|
|
11
9
|
|
|
@@ -18,21 +16,6 @@ from single_kernel_mongo.exceptions import InvalidCharmKindError
|
|
|
18
16
|
logger = getLogger(__name__)
|
|
19
17
|
|
|
20
18
|
|
|
21
|
-
def parse_tls_file(raw_content: str) -> bytes:
|
|
22
|
-
"""Parse TLS files from both plain text or base64 format."""
|
|
23
|
-
if re.match(r"(-+(BEGIN|END) [A-Z ]+-+)", raw_content):
|
|
24
|
-
return (
|
|
25
|
-
re.sub(
|
|
26
|
-
r"(-+(BEGIN|END) [A-Z ]+-+)",
|
|
27
|
-
"\\1",
|
|
28
|
-
raw_content,
|
|
29
|
-
)
|
|
30
|
-
.rstrip()
|
|
31
|
-
.encode("utf-8")
|
|
32
|
-
)
|
|
33
|
-
return base64.b64decode(raw_content)
|
|
34
|
-
|
|
35
|
-
|
|
36
19
|
def generate_relation_departed_key(rel_id: int) -> str: # noqa
|
|
37
20
|
return f"relation_{rel_id}_departed"
|
|
38
21
|
|
|
@@ -61,7 +44,7 @@ def hostname_from_shardname(host: str) -> str:
|
|
|
61
44
|
return host.split("/")[0]
|
|
62
45
|
|
|
63
46
|
|
|
64
|
-
def is_valid_ldapusertodnmapping(ldap_user_to_dn_mapping: str) -> bool:
|
|
47
|
+
def is_valid_ldapusertodnmapping(ldap_user_to_dn_mapping: str | None) -> bool:
|
|
65
48
|
"""Validates the mapping, returning a boolean."""
|
|
66
49
|
if not ldap_user_to_dn_mapping:
|
|
67
50
|
return True
|
|
@@ -73,7 +56,9 @@ def is_valid_ldapusertodnmapping(ldap_user_to_dn_mapping: str) -> bool:
|
|
|
73
56
|
return False
|
|
74
57
|
|
|
75
58
|
|
|
76
|
-
def is_valid_ldap_options(
|
|
59
|
+
def is_valid_ldap_options(
|
|
60
|
+
ldap_user_to_dn_mapping: str | None, ldap_query_template: str | None
|
|
61
|
+
) -> bool:
|
|
77
62
|
"""Validates the combination of the two LDAP options.
|
|
78
63
|
|
|
79
64
|
Rules are the following:
|
|
@@ -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
|
|