Skip to content

Commit 5354c94

Browse files
authored
feat(DPE-6723): LDAP Support (#401)
* feat: first integration testing of ldap on charm side * fix: integration testing fails to download self-signed-certificates * fix: bump lib + tiny test * fix: rel name + relock * fix: upgrade errors * fix: resources path * fix: also for sharded upgrades * fix: upgrade tests? * feat: Use released library
1 parent 732c94a commit 5354c94

File tree

11 files changed

+833
-569
lines changed

11 files changed

+833
-569
lines changed

metadata.yaml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ peers:
2323
interface: mongodb-peers
2424
upgrade-version-a:
2525
interface: upgrade
26+
ldap-peers:
27+
# Stores the data for the ldap relation.
28+
interface: ldap-peers
2629

2730
provides:
2831
database:
@@ -52,6 +55,14 @@ requires:
5255
interface: shards
5356
# shards can only relate to one config-server
5457
limit: 1
58+
ldap:
59+
interface: ldap
60+
limit: 1
61+
optional: true
62+
ldap-certificate-transfer:
63+
interface: certificate_transfer
64+
limit: 1
65+
optional: true
5566

5667
containers:
5768
mongod:
@@ -64,7 +75,7 @@ resources:
6475
type: oci-image
6576
description: OCI image for mongodb
6677
# TODO: Update sha whenever upstream rock changes
67-
upstream-source: ghcr.io/canonical/charmed-mongodb@sha256:c24916ddf111da240dd3d5508ba8d42f611e9167bb9be67a3acc392a25883047
78+
upstream-source: ghcr.io/canonical/charmed-mongodb@sha256:7ddb80a3b5ddffa95704a8980fc11037ba1a23273a9805214bc42be9f507107f
6879
storage:
6980
mongodb:
7081
type: filesystem

poetry.lock

Lines changed: 679 additions & 485 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ requires-poetry = ">=2.0.0"
88

99
[tool.poetry.dependencies]
1010
python = "^3.10.12"
11-
mongo-charms-single-kernel = "~0.0.4"
12-
dacite = "==1.8.0"
11+
mongo-charms-single-kernel = "==0.0.6"
1312
ops = "~2.15.0"
1413
pymongo = "^4.7.3"
1514
tenacity = "^8.2.3"
@@ -57,14 +56,12 @@ coverage = {extras = ["toml"], version = "^7.5.0"}
5756
pytest = "^8.1.1"
5857
pytest-mock = "*"
5958
parameterized = "^0.9.0"
60-
mongo-charms-single-kernel = "~0.0.4"
61-
dacite = "==1.8.0"
59+
mongo-charms-single-kernel = "==0.0.6"
6260

6361
[tool.poetry.group.integration.dependencies]
6462
allure-pytest = "^2.13.5"
6563
ops = "~2.15.0"
66-
mongo-charms-single-kernel = "~0.0.4"
67-
dacite = "==1.8.0"
64+
mongo-charms-single-kernel = "==0.0.6"
6865
tenacity = "^8.2.3"
6966
pymongo = "^4.7.3"
7067
parameterized = "^0.9.0"

tests/integration/sharding_tests/helpers.py

Lines changed: 102 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ async def get_related_username_password(
4343

4444

4545
async def deploy_cluster_components(
46-
ops_test: OpsTest, num_units_cluster_config: dict | None = None, channel: str | None = None
46+
ops_test: OpsTest,
47+
num_units_cluster_config: dict | None = None,
48+
channel: str | None = None,
4749
) -> None:
4850
if not num_units_cluster_config:
4951
num_units_cluster_config = {
@@ -62,44 +64,105 @@ async def deploy_cluster_components(
6264
if channel
6365
else {"mongodb-image": METADATA["resources"]["mongodb-image"]["upstream-source"]}
6466
)
65-
await ops_test.model.deploy(
66-
my_charm,
67-
resources=resources,
68-
num_units=num_units_cluster_config[CONFIG_SERVER_APP_NAME],
69-
config={"role": "config-server"},
70-
application_name=CONFIG_SERVER_APP_NAME,
71-
channel=channel,
72-
series="jammy",
73-
trust=True,
74-
)
75-
await ops_test.model.deploy(
76-
my_charm,
77-
resources=resources,
78-
num_units=num_units_cluster_config[SHARD_ONE_APP_NAME],
79-
config={"role": "shard"},
80-
application_name=SHARD_ONE_APP_NAME,
81-
channel=channel,
82-
series="jammy",
83-
trust=True,
84-
)
85-
await ops_test.model.deploy(
86-
my_charm,
87-
resources=resources,
88-
num_units=num_units_cluster_config[SHARD_TWO_APP_NAME],
89-
config={"role": "shard"},
90-
application_name=SHARD_TWO_APP_NAME,
91-
channel=channel,
92-
series="jammy",
93-
trust=True,
94-
)
95-
96-
await ops_test.model.wait_for_idle(
97-
apps=CLUSTER_COMPONENTS,
98-
idle_period=20,
99-
timeout=TIMEOUT,
100-
raise_on_blocked=False,
101-
raise_on_error=False,
102-
)
67+
if channel is None:
68+
await ops_test.model.deploy(
69+
my_charm,
70+
resources=resources,
71+
num_units=num_units_cluster_config[CONFIG_SERVER_APP_NAME],
72+
config={"role": "config-server"},
73+
application_name=CONFIG_SERVER_APP_NAME,
74+
channel=channel,
75+
series="jammy",
76+
trust=True,
77+
)
78+
await ops_test.model.deploy(
79+
my_charm,
80+
resources=resources,
81+
num_units=num_units_cluster_config[SHARD_ONE_APP_NAME],
82+
config={"role": "shard"},
83+
application_name=SHARD_ONE_APP_NAME,
84+
channel=channel,
85+
series="jammy",
86+
trust=True,
87+
)
88+
await ops_test.model.deploy(
89+
my_charm,
90+
resources=resources,
91+
num_units=num_units_cluster_config[SHARD_TWO_APP_NAME],
92+
config={"role": "shard"},
93+
application_name=SHARD_TWO_APP_NAME,
94+
channel=channel,
95+
series="jammy",
96+
trust=True,
97+
)
98+
99+
await ops_test.model.wait_for_idle(
100+
apps=CLUSTER_COMPONENTS,
101+
idle_period=20,
102+
timeout=TIMEOUT,
103+
raise_on_blocked=False,
104+
raise_on_error=False,
105+
)
106+
# FIXME: (revert this) Deploy 1 and scale up due to silly bug fixed but unreleased
107+
else:
108+
await ops_test.model.deploy(
109+
my_charm,
110+
resources=resources,
111+
num_units=1,
112+
config={"role": "config-server"},
113+
application_name=CONFIG_SERVER_APP_NAME,
114+
channel=channel,
115+
series="jammy",
116+
trust=True,
117+
)
118+
await ops_test.model.deploy(
119+
my_charm,
120+
resources=resources,
121+
num_units=1,
122+
config={"role": "shard"},
123+
application_name=SHARD_ONE_APP_NAME,
124+
channel=channel,
125+
series="jammy",
126+
trust=True,
127+
)
128+
await ops_test.model.deploy(
129+
my_charm,
130+
resources=resources,
131+
num_units=1,
132+
config={"role": "shard"},
133+
application_name=SHARD_TWO_APP_NAME,
134+
channel=channel,
135+
series="jammy",
136+
trust=True,
137+
)
138+
# Wait a bit before scaling up
139+
await ops_test.model.wait_for_idle(
140+
apps=CLUSTER_COMPONENTS,
141+
idle_period=20,
142+
timeout=TIMEOUT,
143+
raise_on_blocked=False,
144+
raise_on_error=False,
145+
)
146+
if num_units_cluster_config[CONFIG_SERVER_APP_NAME] != 1:
147+
await ops_test.model.applications[CONFIG_SERVER_APP_NAME].scale(
148+
num_units_cluster_config[CONFIG_SERVER_APP_NAME]
149+
)
150+
151+
if num_units_cluster_config[SHARD_ONE_APP_NAME] != 1:
152+
await ops_test.model.applications[SHARD_ONE_APP_NAME].scale(
153+
num_units_cluster_config[SHARD_ONE_APP_NAME]
154+
)
155+
if num_units_cluster_config[SHARD_TWO_APP_NAME] != 1:
156+
await ops_test.model.applications[SHARD_TWO_APP_NAME].scale(
157+
num_units_cluster_config[SHARD_TWO_APP_NAME]
158+
)
159+
await ops_test.model.wait_for_idle(
160+
apps=CLUSTER_COMPONENTS,
161+
idle_period=20,
162+
timeout=TIMEOUT,
163+
raise_on_blocked=False,
164+
raise_on_error=False,
165+
)
103166

104167

105168
async def integrate_cluster(ops_test: OpsTest) -> None:

tests/integration/tls_tests/test_sharding_tls.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ async def test_build_and_deploy(ops_test: OpsTest) -> None:
4343
await deploy_cluster_components(ops_test)
4444

4545
# deploy the self-signed-certificates charm
46-
await ops_test.model.deploy(CERTS_APP_NAME, channel="stable")
46+
await ops_test.model.deploy(CERTS_APP_NAME, channel="latest/stable", base="[email protected]")
4747

4848
await ops_test.model.wait_for_idle(
4949
apps=[
@@ -129,7 +129,10 @@ async def test_tls_then_build_cluster(ops_test: OpsTest) -> None:
129129
@pytest.mark.abort_on_fail
130130
async def test_tls_inconsistent_rels(ops_test: OpsTest) -> None:
131131
await ops_test.model.deploy(
132-
CERTS_APP_NAME, application_name=DIFFERENT_CERTS_APP_NAME, channel="stable"
132+
CERTS_APP_NAME,
133+
application_name=DIFFERENT_CERTS_APP_NAME,
134+
channel="latest/stable",
135+
133136
)
134137

135138
# CASE 1: Config-server has TLS enabled - but shard does not

tests/integration/tls_tests/test_tls.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ async def test_build_and_deploy(ops_test: OpsTest) -> None:
6363
config = {"ca-common-name": "Test CA"}
6464
await ops_test.model.deploy(
6565
TLS_CERTIFICATES_APP_NAME,
66-
channel="stable",
66+
channel="latest/stable",
6767
config=config,
68-
series="jammy",
68+
6969
)
7070
await ops_test.model.wait_for_idle(
7171
apps=[TLS_CERTIFICATES_APP_NAME],
@@ -80,7 +80,9 @@ async def test_enable_tls(ops_test: OpsTest) -> None:
8080
# Relate it to the MongoDB to enable TLS.
8181
app_name = await get_app_name(ops_test)
8282
# check if relation exists
83-
await ops_test.model.integrate(app_name, TLS_CERTIFICATES_APP_NAME)
83+
await ops_test.model.integrate(
84+
f"{app_name}:certificates", f"{TLS_CERTIFICATES_APP_NAME}:certificates"
85+
)
8486

8587
async with ops_test.fast_forward():
8688
await ops_test.model.wait_for_idle(status="active", timeout=1000)

tests/integration/upgrades/helpers.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from pytest_operator.plugin import OpsTest
99

1010
from ..backup_tests import helpers as backup_helpers
11+
from ..helpers import METADATA
1112

1213
logger = logging.getLogger(__name__)
1314

@@ -23,7 +24,11 @@ async def assert_successful_run_upgrade_sequence(
2324

2425
logger.info(f"Upgrading {app_name}")
2526

26-
await ops_test.model.applications[app_name].refresh(path=new_charm)
27+
resources = {"mongodb-image": METADATA["resources"]["mongodb-image"]["upstream-source"]}
28+
await ops_test.model.applications[app_name].refresh(
29+
path=new_charm,
30+
resources=resources, # We add resources in case the rock changed.
31+
)
2732
# TODO future work, resolve flickering status of app
2833
await ops_test.model.wait_for_idle(apps=[app_name], timeout=1000, idle_period=90)
2934

tests/integration/upgrades/test_sharding_upgrades.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,9 @@ async def test_build_and_deploy(ops_test: OpsTest) -> None:
7878
}
7979
await deploy_and_scale_application(ops_test)
8080

81-
await deploy_cluster_components(ops_test, num_units_cluster_config, channel="6/edge")
81+
await deploy_cluster_components(
82+
ops_test, num_units_cluster_config=num_units_cluster_config, channel="6/edge"
83+
)
8284

8385
await ops_test.model.wait_for_idle(
8486
apps=CLUSTER_COMPONENTS,
@@ -193,6 +195,8 @@ async def test_pre_upgrade_check_failure(ops_test: OpsTest, chaos_mesh) -> None:
193195
non_leader_unit = unit
194196
break
195197

198+
assert non_leader_unit, "No non leader unit found"
199+
196200
isolate_instance_from_cluster(ops_test, non_leader_unit.name)
197201
await wait_until_unit_in_status(
198202
ops_test,

tests/integration/upgrades/test_upgrades.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,22 @@ async def test_build_and_deploy(ops_test: OpsTest):
4848
await check_or_scale_app(ops_test, db_app_name, required_units=3)
4949
return
5050
else:
51-
await ops_test.model.deploy(MONGODB_CHARM_NAME, channel="6/edge", num_units=3, trust=True)
51+
# FIXME: (revert this) Deploy 1 and scale up due to silly bug fixed but unreleased.
52+
await ops_test.model.deploy(MONGODB_CHARM_NAME, channel="6/edge", num_units=1, trust=True)
53+
54+
await ops_test.model.wait_for_idle(
55+
apps=[MONGODB_CHARM_NAME], status="active", timeout=DEPLOYMENT_TIMEOUT
56+
)
57+
58+
await ops_test.model.applications[MONGODB_CHARM_NAME].scale(3)
5259

5360
db_app_name = await get_app_name(ops_test)
5461
await ops_test.model.wait_for_idle(
55-
apps=[db_app_name], status="active", timeout=DEPLOYMENT_TIMEOUT, idle_period=120
62+
apps=[db_app_name],
63+
status="active",
64+
timeout=DEPLOYMENT_TIMEOUT,
65+
idle_period=120,
66+
raise_on_blocked=False,
5667
)
5768

5869
await relate_mongodb_and_application(ops_test, db_app_name, WRITE_APP)

tests/unit/test_charm.py

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -116,34 +116,8 @@ def test_mongod_pebble_ready(
116116
"group": "mongodb",
117117
"override": "replace",
118118
"summary": "mongod",
119-
"command": (
120-
"/usr/bin/mongod --bind_ip_all "
121-
"--port=27017 "
122-
"--auth --clusterAuthMode=keyFile "
123-
f"--keyFile={self.harness.charm.workload.paths.keyfile} "
124-
"--setParameter processUmask=037 "
125-
"--logRotate reopen --logappend --logpath=/var/log/mongodb/mongodb.log "
126-
"--auditDestination=file "
127-
"--auditFormat=JSON "
128-
"--auditPath=/var/log/mongodb/audit.log "
129-
"--replSet=mongodb-k8s "
130-
f"--dbpath={self.harness.charm.workload.paths.data_path}"
131-
),
132-
"environment": {
133-
"MONGOD_ARGS": (
134-
"--bind_ip_all "
135-
"--port=27017 "
136-
"--auth --clusterAuthMode=keyFile "
137-
f"--keyFile={self.harness.charm.workload.paths.keyfile} "
138-
"--setParameter processUmask=037 "
139-
"--logRotate reopen --logappend --logpath=/var/log/mongodb/mongodb.log "
140-
"--auditDestination=file "
141-
"--auditFormat=JSON "
142-
"--auditPath=/var/log/mongodb/audit.log "
143-
"--replSet=mongodb-k8s "
144-
f"--dbpath={self.harness.charm.workload.paths.data_path}"
145-
)
146-
},
119+
"command": "/bin/bash /bin/start-mongod.sh",
120+
"environment": {"MONGOD_ARGS": ""},
147121
"startup": "enabled",
148122
},
149123
},

0 commit comments

Comments
 (0)