Skip to content

Commit

Permalink
TLS now supported wit hsharding
Browse files Browse the repository at this point in the history
  • Loading branch information
MiaAltieri committed Mar 7, 2024
1 parent 623071c commit 444002e
Show file tree
Hide file tree
Showing 5 changed files with 391 additions and 70 deletions.
33 changes: 23 additions & 10 deletions lib/charms/mongodb/v0/mongodb_tls.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,26 +76,27 @@ def _on_set_tls_private_key(self, event: ActionEvent) -> None:
"""Set the TLS private key, which will be used for requesting the certificate."""
logger.debug("Request to set TLS private key received.")
try:
self._request_certificate(event.params.get("external-key", None), internal=False)
self._request_certificate(event.params.get("internal-key", None), internal=True)
self.request_certificate(event.params.get("external-key", None), internal=False)
self.request_certificate(event.params.get("internal-key", None), internal=True)
logger.debug("Successfully set TLS private key.")
except ValueError as e:
event.fail(str(e))

def _request_certificate(
def request_certificate(
self,
param: Optional[str],
internal: bool,
):
"""Request TLS certificate."""
if param is None:
key = generate_private_key()
else:
key = self._parse_tls_file(param)

csr = generate_csr(
private_key=key,
subject=self.get_host(self.charm.unit),
organization=self.charm.app.name,
subject=self._get_subject_name(),
organization=self._get_subject_name(),
sans=self._get_sans(),
sans_ip=[str(self.charm.model.get_binding(self.peer_relation).network.bind_address)],
)
Expand Down Expand Up @@ -124,8 +125,8 @@ def _parse_tls_file(raw_content: str) -> bytes:

def _on_tls_relation_joined(self, _: RelationJoinedEvent) -> None:
"""Request certificate when TLS relation joined."""
self._request_certificate(None, internal=True)
self._request_certificate(None, internal=False)
self.request_certificate(None, internal=True)
self.request_certificate(None, internal=False)

def _on_tls_relation_broken(self, event: RelationBrokenEvent) -> None:
"""Disable TLS when TLS relation broken."""
Expand All @@ -149,7 +150,7 @@ def _on_certificate_available(self, event: CertificateAvailableEvent) -> None:

if ext_csr and event.certificate_signing_request.rstrip() == ext_csr.rstrip():
logger.debug("The external TLS certificate available.")
internal = False # external crs
internal = False
elif int_csr and event.certificate_signing_request.rstrip() == int_csr.rstrip():
logger.debug("The internal TLS certificate available.")
internal = True
Expand Down Expand Up @@ -222,8 +223,8 @@ def _on_certificate_expiring(self, event: CertificateExpiringEvent) -> None:
old_csr = self.get_tls_secret(internal, Config.TLS.SECRET_CSR_LABEL).encode("utf-8")
new_csr = generate_csr(
private_key=key,
subject=self.get_host(self.charm.unit),
organization=self.charm.app.name,
subject=self._get_subject_name(),
organization=self._get_subject_name(),
sans=self._get_sans(),
sans_ip=[str(self.charm.model.get_binding(self.peer_relation).network.bind_address)],
)
Expand Down Expand Up @@ -293,3 +294,15 @@ def get_tls_secret(self, internal: bool, label_name: str) -> str:
scope = "int" if internal else "ext"
label_name = f"{scope}-{label_name}"
return self.charm.get_secret(UNIT_SCOPE, label_name)

def _get_subject_name(self) -> str:
"""Generate the subject name for CSR."""
# In sharded MongoDB deployments it is a requirement that all subject names match across
# all cluster components
if self.charm.is_role(Config.Role.SHARD):
# until integrated with config-server use current app name as
# subject name
subject_name = self.charm.shard.get_config_server_name() or self.charm.app.name
return subject_name

return self.charm.app.name
35 changes: 32 additions & 3 deletions lib/charms/mongodb/v1/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,40 @@ def get_mongos_args(
f"--configdb {config_server_db}",
# config server is already using 27017
f"--port {Config.MONGOS_PORT}",
f"--keyFile={full_conf_dir}/{KEY_FILE}",
"\n",
]

# TODO Future PR: support TLS on mongos
# TODO : generalise these into functions to be re-used
if not config.tls_internal:
# keyFile cannot be used without auth and cannot be used in tandem with internal TLS
cmd.extend(
[
"--clusterAuthMode=keyFile",
f"--keyFile={full_conf_dir}/{KEY_FILE}",
]
)

if config.tls_external:
cmd.extend(
[
f"--tlsCAFile={full_conf_dir}/{TLS_EXT_CA_FILE}",
f"--tlsCertificateKeyFile={full_conf_dir}/{TLS_EXT_PEM_FILE}",
# allow non-TLS connections
"--tlsMode=preferTLS",
"--tlsDisabledProtocols=TLS1_0,TLS1_1",
]
)

# internal TLS can be enabled only in external is enabled
if config.tls_internal and config.tls_external:
cmd.extend(
[
"--clusterAuthMode=x509",
"--tlsAllowInvalidCertificates",
f"--tlsClusterCAFile={full_conf_dir}/{TLS_INT_CA_FILE}",
f"--tlsClusterFile={full_conf_dir}/{TLS_INT_PEM_FILE}",
]
)
cmd.append("\n")
return " ".join(cmd)


Expand Down Expand Up @@ -161,6 +189,7 @@ def get_mongod_args(
if auth:
cmd.extend(["--auth"])

# todo this should get resolved once we set secrets properly in shared data
if auth and not config.tls_internal:
# keyFile cannot be used without auth and cannot be used in tandem with internal TLS
cmd.extend(
Expand Down
Loading

0 comments on commit 444002e

Please sign in to comment.