Skip to content

Commit

Permalink
chore(PR): Fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
merkata committed Oct 15, 2024
1 parent 65cee50 commit 06d44a8
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 41 deletions.
33 changes: 0 additions & 33 deletions src/charm_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,39 +44,6 @@ class DatasourcePostgreSQL(BaseModel):
db: str = Field(min_length=1, description="Database name")
uri: str = Field(min_length=1, description="Database connection URI")

@classmethod
def from_relation(cls, model: ops.Model, relation: ops.Relation) -> "DatasourcePostgreSQL":
"""Create a DatasourcePostgreSQL from a relation.
Args:
relation: The relation to get the data from.
model: The model to get the secret from.
Returns:
A DatasourcePostgreSQL instance.
"""
relation_data = relation.data[relation.app]
user = relation_data.get("username", "")
password = relation_data.get("password", "")
secret_user = relation_data.get("secret-user", "")
if user == "" and secret_user != "": # nosec
secret = model.get_secret(id=secret_user)
secret_fields = ops.Secret.get_content(secret)
user = secret_fields["username"]
password = secret_fields["password"]
host, port = relation_data.get("endpoints", ":").split(":")
db = relation_data.get("database", "")
uri = f"postgres://{user}:{password}@{host}:{port}/{db}"

return DatasourcePostgreSQL(
user=user,
password=password,
host=host,
port=port,
db=db,
uri=uri,
)


class CharmConfig(BaseModel):
"""A named tuple representing an IRC configuration.
Expand Down
40 changes: 35 additions & 5 deletions src/database_observer.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,40 @@ def get_db(self) -> typing.Optional[DatasourcePostgreSQL]:
Returns:
DatasourcePostgreSQL: The datasource model.
"""
# not using get_relation due this issue
# https://github.com/canonical/operator/issues/1153
if not self.model.relations.get(self.database.relation_name):
relation_data = list(
self.database.fetch_relation_data(
fields=["uris", "endpoints", "username", "password", "database"]
).values()
)

if not relation_data:
return None

# There can be only one database integrated at a time
# with the same interface name. See: metadata.yaml
data = relation_data[0]

# Check that the relation data is well formed according to the following json_schema:
# https://github.com/canonical/charm-relation-interfaces/blob/main/interfaces/mysql_client/v0/schemas/provider.json
if not all(data.get(key) for key in ("endpoints", "username", "password")):
return None

relation = self.model.get_relation(self.relation_name)
return DatasourcePostgreSQL.from_relation(self.model, relation)
database_name = data.get("database", self.database.database)
endpoint = data["endpoints"].split(",")[0]
user = data["username"]
password = data["password"]
host, port = endpoint.split(":")

if "uris" in data:
uri = data["uris"].split(",")[0]
else:
uri = f"postgres://{user}:{password}@{endpoint}/{database_name}"

return DatasourcePostgreSQL(
user=user,
password=password,
host=host,
port=port,
db=database_name,
uri=uri,
)
27 changes: 24 additions & 3 deletions tests/unit/test_database_observer.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,28 @@ def test_get_db_when_no_relation_data():
"""
harness = Harness(ObservedCharm, meta=REQUIRER_METADATA)
harness.begin()
harness.add_relation("database", "database-provider")
harness.add_relation("database", "database-provider", app_data={})

assert harness.charm.database.get_db() is None


def test_get_db_when_invalid_relation_data():
"""
arrange: set up a charm and a database relation with invalid databag.
act:.
assert: it raises a validation error.
"""
harness = Harness(ObservedCharm, meta=REQUIRER_METADATA)
harness.begin()
harness.add_relation(
"database",
"database-provider",
app_data={
"database": "ircbridge",
"endpoints": "postgresql-k8s-primary.local:5432",
"password": "",
"username": "",
},
)

with pytest.raises(ValidationError):
harness.charm.database.get_db() # pylint: disable=pointless-statement
assert harness.charm.database.get_db() is None

0 comments on commit 06d44a8

Please sign in to comment.