Update charm libraries
Change-Id: I95688e141fd071af654e364dc2f1a21161bd8520
This commit is contained in:
parent
36a77ba3fc
commit
577d6cc5f7
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2022 Canonical Ltd.
|
# Copyright 2023 Canonical Ltd.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -12,7 +12,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
"""[DEPRECATED] Relation 'requires' side abstraction for database relation.
|
r"""[DEPRECATED] Relation 'requires' side abstraction for database relation.
|
||||||
|
|
||||||
This library is a uniform interface to a selection of common database
|
This library is a uniform interface to a selection of common database
|
||||||
metadata, with added custom events that add convenience to database management,
|
metadata, with added custom events that add convenience to database management,
|
||||||
@ -160,7 +160,7 @@ LIBAPI = 0
|
|||||||
|
|
||||||
# Increment this PATCH version before using `charmcraft publish-lib` or reset
|
# Increment this PATCH version before using `charmcraft publish-lib` or reset
|
||||||
# to 0 if you are raising the major API version.
|
# to 0 if you are raising the major API version.
|
||||||
LIBPATCH = 5
|
LIBPATCH = 6
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -171,16 +171,25 @@ class DatabaseEvent(RelationEvent):
|
|||||||
@property
|
@property
|
||||||
def endpoints(self) -> Optional[str]:
|
def endpoints(self) -> Optional[str]:
|
||||||
"""Returns a comma separated list of read/write endpoints."""
|
"""Returns a comma separated list of read/write endpoints."""
|
||||||
|
if not self.relation.app:
|
||||||
|
return None
|
||||||
|
|
||||||
return self.relation.data[self.relation.app].get("endpoints")
|
return self.relation.data[self.relation.app].get("endpoints")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def password(self) -> Optional[str]:
|
def password(self) -> Optional[str]:
|
||||||
"""Returns the password for the created user."""
|
"""Returns the password for the created user."""
|
||||||
|
if not self.relation.app:
|
||||||
|
return None
|
||||||
|
|
||||||
return self.relation.data[self.relation.app].get("password")
|
return self.relation.data[self.relation.app].get("password")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def read_only_endpoints(self) -> Optional[str]:
|
def read_only_endpoints(self) -> Optional[str]:
|
||||||
"""Returns a comma separated list of read only endpoints."""
|
"""Returns a comma separated list of read only endpoints."""
|
||||||
|
if not self.relation.app:
|
||||||
|
return None
|
||||||
|
|
||||||
return self.relation.data[self.relation.app].get("read-only-endpoints")
|
return self.relation.data[self.relation.app].get("read-only-endpoints")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -189,16 +198,25 @@ class DatabaseEvent(RelationEvent):
|
|||||||
|
|
||||||
MongoDB only.
|
MongoDB only.
|
||||||
"""
|
"""
|
||||||
|
if not self.relation.app:
|
||||||
|
return None
|
||||||
|
|
||||||
return self.relation.data[self.relation.app].get("replset")
|
return self.relation.data[self.relation.app].get("replset")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tls(self) -> Optional[str]:
|
def tls(self) -> Optional[str]:
|
||||||
"""Returns whether TLS is configured."""
|
"""Returns whether TLS is configured."""
|
||||||
|
if not self.relation.app:
|
||||||
|
return None
|
||||||
|
|
||||||
return self.relation.data[self.relation.app].get("tls")
|
return self.relation.data[self.relation.app].get("tls")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tls_ca(self) -> Optional[str]:
|
def tls_ca(self) -> Optional[str]:
|
||||||
"""Returns TLS CA."""
|
"""Returns TLS CA."""
|
||||||
|
if not self.relation.app:
|
||||||
|
return None
|
||||||
|
|
||||||
return self.relation.data[self.relation.app].get("tls-ca")
|
return self.relation.data[self.relation.app].get("tls-ca")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -207,11 +225,17 @@ class DatabaseEvent(RelationEvent):
|
|||||||
|
|
||||||
MongoDB, Redis, OpenSearch and Kafka only.
|
MongoDB, Redis, OpenSearch and Kafka only.
|
||||||
"""
|
"""
|
||||||
|
if not self.relation.app:
|
||||||
|
return None
|
||||||
|
|
||||||
return self.relation.data[self.relation.app].get("uris")
|
return self.relation.data[self.relation.app].get("uris")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def username(self) -> Optional[str]:
|
def username(self) -> Optional[str]:
|
||||||
"""Returns the created username."""
|
"""Returns the created username."""
|
||||||
|
if not self.relation.app:
|
||||||
|
return None
|
||||||
|
|
||||||
return self.relation.data[self.relation.app].get("username")
|
return self.relation.data[self.relation.app].get("username")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -220,6 +244,9 @@ class DatabaseEvent(RelationEvent):
|
|||||||
|
|
||||||
Version as informed by the database daemon.
|
Version as informed by the database daemon.
|
||||||
"""
|
"""
|
||||||
|
if not self.relation.app:
|
||||||
|
return None
|
||||||
|
|
||||||
return self.relation.data[self.relation.app].get("version")
|
return self.relation.data[self.relation.app].get("version")
|
||||||
|
|
||||||
|
|
||||||
@ -259,15 +286,15 @@ A tuple for storing the diff between two data mappings.
|
|||||||
class DatabaseRequires(Object):
|
class DatabaseRequires(Object):
|
||||||
"""Requires-side of the database relation."""
|
"""Requires-side of the database relation."""
|
||||||
|
|
||||||
on = DatabaseEvents()
|
on = DatabaseEvents() # pyright: ignore [reportGeneralTypeIssues]
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
charm,
|
charm,
|
||||||
relation_name: str,
|
relation_name: str,
|
||||||
database_name: str,
|
database_name: str,
|
||||||
extra_user_roles: str = None,
|
extra_user_roles: Optional[str] = None,
|
||||||
relations_aliases: List[str] = None,
|
relations_aliases: Optional[List[str]] = None,
|
||||||
):
|
):
|
||||||
"""Manager of database client relations."""
|
"""Manager of database client relations."""
|
||||||
super().__init__(charm, relation_name)
|
super().__init__(charm, relation_name)
|
||||||
@ -352,9 +379,11 @@ class DatabaseRequires(Object):
|
|||||||
# Retrieve the old data from the data key in the local unit relation databag.
|
# Retrieve the old data from the data key in the local unit relation databag.
|
||||||
old_data = json.loads(event.relation.data[self.local_unit].get("data", "{}"))
|
old_data = json.loads(event.relation.data[self.local_unit].get("data", "{}"))
|
||||||
# Retrieve the new data from the event relation databag.
|
# Retrieve the new data from the event relation databag.
|
||||||
new_data = {
|
new_data = (
|
||||||
key: value for key, value in event.relation.data[event.app].items() if key != "data"
|
{key: value for key, value in event.relation.data[event.app].items() if key != "data"}
|
||||||
}
|
if event.app
|
||||||
|
else {}
|
||||||
|
)
|
||||||
|
|
||||||
# These are the keys that were added to the databag and triggered this event.
|
# These are the keys that were added to the databag and triggered this event.
|
||||||
added = new_data.keys() - old_data.keys()
|
added = new_data.keys() - old_data.keys()
|
||||||
@ -413,9 +442,11 @@ class DatabaseRequires(Object):
|
|||||||
"""
|
"""
|
||||||
data = {}
|
data = {}
|
||||||
for relation in self.relations:
|
for relation in self.relations:
|
||||||
data[relation.id] = {
|
data[relation.id] = (
|
||||||
key: value for key, value in relation.data[relation.app].items() if key != "data"
|
{key: value for key, value in relation.data[relation.app].items() if key != "data"}
|
||||||
}
|
if relation.app
|
||||||
|
else {}
|
||||||
|
)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def _update_relation_data(self, relation_id: int, data: dict) -> None:
|
def _update_relation_data(self, relation_id: int, data: dict) -> None:
|
||||||
@ -461,7 +492,9 @@ class DatabaseRequires(Object):
|
|||||||
if "username" in diff.added and "password" in diff.added:
|
if "username" in diff.added and "password" in diff.added:
|
||||||
# Emit the default event (the one without an alias).
|
# Emit the default event (the one without an alias).
|
||||||
logger.info("database created at %s", datetime.now())
|
logger.info("database created at %s", datetime.now())
|
||||||
self.on.database_created.emit(event.relation, app=event.app, unit=event.unit)
|
getattr(self.on, "database_created").emit(
|
||||||
|
event.relation, app=event.app, unit=event.unit
|
||||||
|
)
|
||||||
|
|
||||||
# Emit the aliased event (if any).
|
# Emit the aliased event (if any).
|
||||||
self._emit_aliased_event(event, "database_created")
|
self._emit_aliased_event(event, "database_created")
|
||||||
@ -475,7 +508,9 @@ class DatabaseRequires(Object):
|
|||||||
if "endpoints" in diff.added or "endpoints" in diff.changed:
|
if "endpoints" in diff.added or "endpoints" in diff.changed:
|
||||||
# Emit the default event (the one without an alias).
|
# Emit the default event (the one without an alias).
|
||||||
logger.info("endpoints changed on %s", datetime.now())
|
logger.info("endpoints changed on %s", datetime.now())
|
||||||
self.on.endpoints_changed.emit(event.relation, app=event.app, unit=event.unit)
|
getattr(self.on, "endpoints_changed").emit(
|
||||||
|
event.relation, app=event.app, unit=event.unit
|
||||||
|
)
|
||||||
|
|
||||||
# Emit the aliased event (if any).
|
# Emit the aliased event (if any).
|
||||||
self._emit_aliased_event(event, "endpoints_changed")
|
self._emit_aliased_event(event, "endpoints_changed")
|
||||||
@ -489,7 +524,7 @@ class DatabaseRequires(Object):
|
|||||||
if "read-only-endpoints" in diff.added or "read-only-endpoints" in diff.changed:
|
if "read-only-endpoints" in diff.added or "read-only-endpoints" in diff.changed:
|
||||||
# Emit the default event (the one without an alias).
|
# Emit the default event (the one without an alias).
|
||||||
logger.info("read-only-endpoints changed on %s", datetime.now())
|
logger.info("read-only-endpoints changed on %s", datetime.now())
|
||||||
self.on.read_only_endpoints_changed.emit(
|
getattr(self.on, "read_only_endpoints_changed").emit(
|
||||||
event.relation, app=event.app, unit=event.unit
|
event.relation, app=event.app, unit=event.unit
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
"""IdentityResourceProvides and Requires module.
|
"""IdentityResourceProvides and Requires module.
|
||||||
|
|
||||||
|
|
||||||
This library contains the Requires and Provides classes for handling
|
This library contains the Requires and Provides classes for handling
|
||||||
the identity_ops interface.
|
the identity_ops interface.
|
||||||
|
|
||||||
@ -85,9 +84,16 @@ The secret content should hold the sensitive data with same name as param name.
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
from typing import (
|
||||||
|
Optional,
|
||||||
|
)
|
||||||
|
|
||||||
from ops.charm import (
|
from ops.charm import (
|
||||||
|
CharmBase,
|
||||||
|
RelationBrokenEvent,
|
||||||
|
RelationChangedEvent,
|
||||||
RelationEvent,
|
RelationEvent,
|
||||||
|
RelationJoinedEvent,
|
||||||
)
|
)
|
||||||
from ops.framework import (
|
from ops.framework import (
|
||||||
EventBase,
|
EventBase,
|
||||||
@ -111,7 +117,7 @@ LIBAPI = 0
|
|||||||
|
|
||||||
# Increment this PATCH version before using `charmcraft publish-lib` or reset
|
# Increment this PATCH version before using `charmcraft publish-lib` or reset
|
||||||
# to 0 if you are raising the major API version
|
# to 0 if you are raising the major API version
|
||||||
LIBPATCH = 2
|
LIBPATCH = 3
|
||||||
|
|
||||||
|
|
||||||
REQUEST_NOT_SENT = 1
|
REQUEST_NOT_SENT = 1
|
||||||
@ -151,7 +157,7 @@ class IdentityResourceRequires(Object):
|
|||||||
on = IdentityResourceResponseEvents()
|
on = IdentityResourceResponseEvents()
|
||||||
_stored = StoredState()
|
_stored = StoredState()
|
||||||
|
|
||||||
def __init__(self, charm, relation_name):
|
def __init__(self, charm: CharmBase, relation_name: str):
|
||||||
super().__init__(charm, relation_name)
|
super().__init__(charm, relation_name)
|
||||||
self.charm = charm
|
self.charm = charm
|
||||||
self.relation_name = relation_name
|
self.relation_name = relation_name
|
||||||
@ -169,24 +175,30 @@ class IdentityResourceRequires(Object):
|
|||||||
self._on_identity_resource_relation_broken,
|
self._on_identity_resource_relation_broken,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _on_identity_resource_relation_joined(self, event):
|
def _on_identity_resource_relation_joined(
|
||||||
|
self, event: RelationJoinedEvent
|
||||||
|
):
|
||||||
"""Handle IdentityResource joined."""
|
"""Handle IdentityResource joined."""
|
||||||
self._stored.provider_ready = True
|
self._stored.provider_ready = True
|
||||||
self.on.provider_ready.emit(event.relation)
|
self.on.provider_ready.emit(event.relation)
|
||||||
|
|
||||||
def _on_identity_resource_relation_changed(self, event):
|
def _on_identity_resource_relation_changed(
|
||||||
|
self, event: RelationChangedEvent
|
||||||
|
):
|
||||||
"""Handle IdentityResource changed."""
|
"""Handle IdentityResource changed."""
|
||||||
id_ = self.response.get("id")
|
id_ = self.response.get("id")
|
||||||
self.save_request_in_store(id_, None, None, REQUEST_PROCESSED)
|
self.save_request_in_store(id_, None, None, REQUEST_PROCESSED)
|
||||||
self.on.response_available.emit(event.relation)
|
self.on.response_available.emit(event.relation)
|
||||||
|
|
||||||
def _on_identity_resource_relation_broken(self, event):
|
def _on_identity_resource_relation_broken(
|
||||||
|
self, event: RelationBrokenEvent
|
||||||
|
):
|
||||||
"""Handle IdentityResource broken."""
|
"""Handle IdentityResource broken."""
|
||||||
self._stored.provider_ready = False
|
self._stored.provider_ready = False
|
||||||
self.on.provider_goneaway.emit(event.relation)
|
self.on.provider_goneaway.emit(event.relation)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _identity_resource_rel(self) -> Relation:
|
def _identity_resource_rel(self) -> Optional[Relation]:
|
||||||
"""The IdentityResource relation."""
|
"""The IdentityResource relation."""
|
||||||
return self.framework.model.get_relation(self.relation_name)
|
return self.framework.model.get_relation(self.relation_name)
|
||||||
|
|
||||||
@ -204,7 +216,9 @@ class IdentityResourceRequires(Object):
|
|||||||
|
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
def save_request_in_store(self, id: str, tag: str, ops: list, state: int):
|
def save_request_in_store(
|
||||||
|
self, id: str, tag: str, ops: list, state: int
|
||||||
|
) -> None:
|
||||||
"""Save request in the store."""
|
"""Save request in the store."""
|
||||||
if id is None:
|
if id is None:
|
||||||
return
|
return
|
||||||
@ -242,12 +256,15 @@ class IdentityResourceRequires(Object):
|
|||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_remote_app_data(self, key: str) -> str:
|
def get_remote_app_data(self, key: str) -> Optional[str]:
|
||||||
"""Return the value for the given key from remote app data."""
|
"""Return the value for the given key from remote app data."""
|
||||||
data = self._identity_resource_rel.data[
|
if self._identity_resource_rel:
|
||||||
self._identity_resource_rel.app
|
data = self._identity_resource_rel.data[
|
||||||
]
|
self._identity_resource_rel.app
|
||||||
return data.get(key)
|
]
|
||||||
|
return data.get(key)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
def ready(self) -> bool:
|
def ready(self) -> bool:
|
||||||
"""Interface is ready or not.
|
"""Interface is ready or not.
|
||||||
@ -337,7 +354,7 @@ class IdentityResourceProvides(Object):
|
|||||||
|
|
||||||
on = IdentityResourceProviderEvents()
|
on = IdentityResourceProviderEvents()
|
||||||
|
|
||||||
def __init__(self, charm, relation_name):
|
def __init__(self, charm: CharmBase, relation_name: str):
|
||||||
super().__init__(charm, relation_name)
|
super().__init__(charm, relation_name)
|
||||||
self.charm = charm
|
self.charm = charm
|
||||||
self.relation_name = relation_name
|
self.relation_name = relation_name
|
||||||
@ -346,7 +363,9 @@ class IdentityResourceProvides(Object):
|
|||||||
self._on_identity_resource_relation_changed,
|
self._on_identity_resource_relation_changed,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _on_identity_resource_relation_changed(self, event):
|
def _on_identity_resource_relation_changed(
|
||||||
|
self, event: RelationChangedEvent
|
||||||
|
):
|
||||||
"""Handle IdentityResource changed."""
|
"""Handle IdentityResource changed."""
|
||||||
request = event.relation.data[event.relation.app].get("request", {})
|
request = event.relation.data[event.relation.app].get("request", {})
|
||||||
self.on.process_op.emit(
|
self.on.process_op.emit(
|
||||||
@ -355,7 +374,7 @@ class IdentityResourceProvides(Object):
|
|||||||
|
|
||||||
def set_ops_response(
|
def set_ops_response(
|
||||||
self, relation_id: str, relation_name: str, ops_response: dict
|
self, relation_id: str, relation_name: str, ops_response: dict
|
||||||
):
|
) -> None:
|
||||||
"""Set response to ops request."""
|
"""Set response to ops request."""
|
||||||
if not self.model.unit.is_leader():
|
if not self.model.unit.is_leader():
|
||||||
logger.debug("Not a leader unit, not sending response")
|
logger.debug("Not a leader unit, not sending response")
|
||||||
|
Loading…
Reference in New Issue
Block a user