Skip to content

Commit f02e3c3

Browse files
committed
Migrate cassandra client to database manager.
1 parent 3300905 commit f02e3c3

File tree

4 files changed

+23
-26
lines changed

4 files changed

+23
-26
lines changed

src/charm.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from events.cassandra import CassandraEvents
1717
from managers.cluster import ClusterManager
1818
from managers.config import ConfigManager
19+
from managers.database import DatabaseManager
1920
from workload import CassandraWorkload
2021

2122
logger = logging.getLogger(__name__)
@@ -40,6 +41,15 @@ def __init__(self, *args):
4041
seeds=self.state.cluster.seeds,
4142
authentication=bool(self.state.cluster.cassandra_password_secret),
4243
)
44+
database_manager = DatabaseManager(
45+
hosts=[
46+
"127.0.0.1"
47+
if self.state.unit.workload_state == UnitWorkloadState.CHANGING_PASSWORD
48+
else self.state.unit.ip
49+
],
50+
user="cassandra",
51+
password=self.state.cluster.cassandra_password_secret,
52+
)
4353
bootstrap_manager = RollingOpsManager(
4454
charm=self, relation="bootstrap", callback=self.bootstrap
4555
)
@@ -50,6 +60,7 @@ def __init__(self, *args):
5060
workload=self.workload,
5161
cluster_manager=self.cluster_manager,
5262
config_manager=config_manager,
63+
database_manager=database_manager,
5364
bootstrap_manager=bootstrap_manager,
5465
)
5566

src/events/cassandra.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@
1818
)
1919
from pydantic import ValidationError
2020

21-
from common.cassandra_client import CassandraClient
2221
from core.config import CharmConfig
2322
from core.state import ApplicationState, UnitWorkloadState
2423
from core.statuses import Status
2524
from core.workload import WorkloadBase
2625
from managers.cluster import ClusterManager
2726
from managers.config import ConfigManager
27+
from managers.database import DatabaseManager
2828

2929
logger = logging.getLogger(__name__)
3030

@@ -40,6 +40,7 @@ def __init__(
4040
cluster_manager: ClusterManager,
4141
config_manager: ConfigManager,
4242
bootstrap_manager: RollingOpsManager,
43+
database_manager: DatabaseManager,
4344
):
4445
super().__init__(charm, key="cassandra_events")
4546
self.charm = charm
@@ -48,6 +49,7 @@ def __init__(
4849
self.cluster_manager = cluster_manager
4950
self.config_manager = config_manager
5051
self.bootstrap_manager = bootstrap_manager
52+
self.database_manager = database_manager
5153

5254
self.framework.observe(self.charm.on.start, self._on_start)
5355
self.framework.observe(self.charm.on.install, self._on_install)
@@ -112,7 +114,7 @@ def _finalize_password_change(self, event: StartEvent) -> None:
112114
event.defer()
113115
return
114116
password = self.workload.generate_password()
115-
self._cassandra.change_superuser_password("cassandra", password)
117+
self.database_manager.update_system_user_password("cassandra", password)
116118
self.state.cluster.cassandra_password_secret = password
117119
self.cluster_manager.flush_tables("system_auth", ["roles"])
118120
self.config_manager.render_cassandra_config(
@@ -205,11 +207,3 @@ def _update_network_address(self) -> bool:
205207
and old_hostname is not None
206208
and (old_ip != self.state.unit.ip or old_hostname != self.state.unit.hostname)
207209
)
208-
209-
@property
210-
def _cassandra(self) -> CassandraClient:
211-
return CassandraClient(
212-
[self.state.unit.ip if self.state.cluster.cassandra_password_secret else "127.0.0.1"],
213-
"cassandra",
214-
self.state.cluster.cassandra_password_secret or None,
215-
)

src/managers/cluster.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ class ClusterManager:
2020

2121
def __init__(self, workload: WorkloadBase):
2222
self._workload = workload
23-
pass
2423

2524
@property
2625
def is_healthy(self) -> bool:
@@ -37,5 +36,5 @@ def network_address(self) -> tuple[str, str]:
3736
return socket.gethostbyname(hostname), hostname
3837

3938
def flush_tables(self, keyspace: str, tables: list[str]) -> None:
40-
"""TODO."""
39+
"""Flush tables in keyspace to disk."""
4140
self._workload.exec(["charmed-cassandra.nodetool", "flush", keyspace, *tables])

src/common/cassandra_client.py renamed to src/managers/database.py

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# Copyright 2025 Canonical Ltd.
33
# See LICENSE file for licensing details.
44

5-
"""Cassandra CQL client."""
5+
"""Database manager."""
66

77
import logging
88
from contextlib import contextmanager
@@ -16,24 +16,22 @@
1616
logger = logging.getLogger(__name__)
1717

1818

19-
class CassandraClient:
20-
"""Cassandra CQL client."""
19+
class DatabaseManager:
20+
"""Manager of Cassandra database."""
2121

22-
def __init__(self, hosts: list[str], user: str | None = None, password: str | None = None):
22+
def __init__(self, hosts: list[str], user: str, password: str):
2323
self.execution_profile = ExecutionProfile(
2424
load_balancing_policy=TokenAwarePolicy(DCAwareRoundRobinPolicy())
2525
)
2626
self.auth_provider = (
27-
PlainTextAuthProvider(username=user, password=password)
28-
if user is not None and password is not None
29-
else None
27+
PlainTextAuthProvider(username=user, password=password) if user and password else None
3028
)
3129
self.hosts = hosts
3230

3331
return
3432

35-
def change_superuser_password(self, user: str, password: str) -> None:
36-
"""TODO."""
33+
def update_system_user_password(self, user: str, password: str) -> None:
34+
"""Change password for the role in system_auth."""
3735
with self._session() as session:
3836
session.execute(
3937
"UPDATE system_auth.roles SET salted_hash = %s WHERE role = %s",
@@ -43,11 +41,6 @@ def change_superuser_password(self, user: str, password: str) -> None:
4341
],
4442
)
4543

46-
def change_user_password(self, user: str, password: str) -> None:
47-
"""TODO."""
48-
with self._session() as session:
49-
session.execute("ALTER USER %s WITH PASSWORD %s", [user, password])
50-
5144
@contextmanager
5245
def _session(self, keyspace: str | None = None) -> Generator[Session, None, None]:
5346
cluster = Cluster(

0 commit comments

Comments
 (0)