Skip to content
This repository was archived by the owner on Jun 7, 2024. It is now read-only.

Commit b03dace

Browse files
chore: update charm libraries (#67)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent baa74cc commit b03dace

File tree

1 file changed

+46
-16
lines changed

1 file changed

+46
-16
lines changed

lib/charms/data_platform_libs/v0/data_interfaces.py

+46-16
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ def _on_topic_requested(self, event: TopicRequestedEvent):
320320

321321
# Increment this PATCH version before using `charmcraft publish-lib` or reset
322322
# to 0 if you are raising the major API version
323-
LIBPATCH = 21
323+
LIBPATCH = 22
324324

325325
PYDEPS = ["ops>=2.0.0"]
326326

@@ -763,14 +763,23 @@ def _process_secret_fields(
763763
req_secret_fields: Optional[List[str]],
764764
impacted_rel_fields: List[str],
765765
operation: Callable,
766-
second_chance_as_normal_field: bool = True,
767766
*args,
768767
**kwargs,
769768
) -> Tuple[Dict[str, str], Set[str]]:
770769
"""Isolate target secret fields of manipulation, and execute requested operation by Secret Group."""
771770
result = {}
771+
772+
# If the relation started on a databag, we just stay on the databag
773+
# (Rolling upgrades may result in a relation starting on databag, getting secrets enabled on-the-fly)
774+
# self.local_app is sufficient to check (ignored if Requires, never has secrets -- works if Provides)
775+
fallback_to_databag = (
776+
req_secret_fields
777+
and self.local_unit.is_leader()
778+
and set(req_secret_fields) & set(relation.data[self.local_app])
779+
)
780+
772781
normal_fields = set(impacted_rel_fields)
773-
if req_secret_fields and self.secrets_enabled:
782+
if req_secret_fields and self.secrets_enabled and not fallback_to_databag:
774783
normal_fields = normal_fields - set(req_secret_fields)
775784
secret_fields = set(impacted_rel_fields) - set(normal_fields)
776785

@@ -779,8 +788,10 @@ def _process_secret_fields(
779788
for group in secret_fieldnames_grouped:
780789
# operation() should return nothing when all goes well
781790
if group_result := operation(relation, group, secret_fields, *args, **kwargs):
782-
result.update(group_result)
783-
elif second_chance_as_normal_field:
791+
# If "meaningful" data was returned, we take it. (Some 'operation'-s only return success/failure.)
792+
if isinstance(group_result, dict):
793+
result.update(group_result)
794+
else:
784795
# If it wasn't found as a secret, let's give it a 2nd chance as "normal" field
785796
# Needed when Juju3 Requires meets Juju2 Provider
786797
normal_fields |= set(secret_fieldnames_grouped[group])
@@ -999,12 +1010,12 @@ def _diff(self, event: RelationChangedEvent) -> Diff:
9991010
@juju_secrets_only
10001011
def _add_relation_secret(
10011012
self, relation: Relation, content: Dict[str, str], group_mapping: SecretGroup
1002-
) -> Optional[Secret]:
1013+
) -> bool:
10031014
"""Add a new Juju Secret that will be registered in the relation databag."""
10041015
secret_field = self._generate_secret_field_name(group_mapping)
10051016
if relation.data[self.local_app].get(secret_field):
10061017
logging.error("Secret for relation %s already exists, not adding again", relation.id)
1007-
return
1018+
return False
10081019

10091020
label = self._generate_secret_label(self.relation_name, relation.id, group_mapping)
10101021
secret = self.secrets.add(label, content, relation)
@@ -1013,57 +1024,76 @@ def _add_relation_secret(
10131024
if secret.meta and secret.meta.id:
10141025
relation.data[self.local_app][secret_field] = secret.meta.id
10151026

1027+
# Return the content that was added
1028+
return True
1029+
10161030
@juju_secrets_only
10171031
def _update_relation_secret(
10181032
self, relation: Relation, content: Dict[str, str], group_mapping: SecretGroup
1019-
):
1033+
) -> bool:
10201034
"""Update the contents of an existing Juju Secret, referred in the relation databag."""
10211035
secret = self._get_relation_secret(relation.id, group_mapping)
10221036

10231037
if not secret:
10241038
logging.error("Can't update secret for relation %s", relation.id)
1025-
return
1039+
return False
10261040

10271041
old_content = secret.get_content()
10281042
full_content = copy.deepcopy(old_content)
10291043
full_content.update(content)
10301044
secret.set_content(full_content)
10311045

1046+
# Return True on success
1047+
return True
1048+
10321049
def _add_or_update_relation_secrets(
10331050
self,
10341051
relation: Relation,
10351052
group: SecretGroup,
10361053
secret_fields: Set[str],
10371054
data: Dict[str, str],
1038-
) -> None:
1055+
) -> bool:
10391056
"""Update contents for Secret group. If the Secret doesn't exist, create it."""
10401057
secret_content = self._content_for_secret_group(data, secret_fields, group)
10411058
if self._get_relation_secret(relation.id, group):
1042-
self._update_relation_secret(relation, secret_content, group)
1059+
return self._update_relation_secret(relation, secret_content, group)
10431060
else:
1044-
self._add_relation_secret(relation, secret_content, group)
1061+
return self._add_relation_secret(relation, secret_content, group)
10451062

10461063
@juju_secrets_only
10471064
def _delete_relation_secret(
10481065
self, relation: Relation, group: SecretGroup, secret_fields: List[str], fields: List[str]
1049-
):
1066+
) -> bool:
10501067
"""Update the contents of an existing Juju Secret, referred in the relation databag."""
10511068
secret = self._get_relation_secret(relation.id, group)
10521069

10531070
if not secret:
1054-
logging.error("Can't update secret for relation %s", relation.id)
1055-
return
1071+
logging.error("Can't update secret for relation %s", str(relation.id))
1072+
return False
10561073

10571074
old_content = secret.get_content()
10581075
new_content = copy.deepcopy(old_content)
10591076
for field in fields:
1060-
new_content.pop(field)
1077+
try:
1078+
new_content.pop(field)
1079+
except KeyError:
1080+
logging.error(
1081+
"Non-existing secret was attempted to be removed %s, %s",
1082+
str(relation.id),
1083+
str(field),
1084+
)
1085+
return False
1086+
10611087
secret.set_content(new_content)
10621088

1089+
# Remove secret from the relation if it's fully gone
10631090
if not new_content:
10641091
field = self._generate_secret_field_name(group)
10651092
relation.data[self.local_app].pop(field)
10661093

1094+
# Return the content that was removed
1095+
return True
1096+
10671097
# Mandatory internal overrides
10681098

10691099
@juju_secrets_only

0 commit comments

Comments
 (0)