Skip to content

Commit 31b8890

Browse files
committed
fix: update charm dependent libs
1 parent e1f53c2 commit 31b8890

File tree

1 file changed

+69
-8
lines changed

1 file changed

+69
-8
lines changed

lib/charms/certificate_transfer_interface/v1/certificate_transfer.py

Lines changed: 69 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,15 @@
44
"""Library for the certificate_transfer relation.
55
66
This library contains the Requires and Provides classes for handling the
7-
certificate-transfer interface.
7+
certificate-transfer interface. It supports both v0 and v1 of the interface.
8+
9+
For requirers, they will set version 1 in their application databag as a hint to
10+
the provider. They will read the databag from the provider first as v1, and fallback
11+
to v0 if the format does not match.
12+
13+
For providers, they will check the version in the requirer's application databag,
14+
and send v1 if that version is set to 1, otherwise it will default to 0 for backwards
15+
compatibility.
816
917
## Getting Started
1018
From a charm directory, fetch the library using `charmcraft`:
@@ -116,7 +124,7 @@ def _on_certificates_removed(self, event: CertificatesRemovedEvent):
116124

117125
# Increment this PATCH version before using `charmcraft publish-lib` or reset
118126
# to 0 if you are raising the major API version
119-
LIBPATCH = 7
127+
LIBPATCH = 10
120128

121129
logger = logging.getLogger(__name__)
122130

@@ -283,6 +291,24 @@ class ProviderApplicationData(DatabagModel):
283291
)
284292

285293

294+
class _Certificate(pydantic.BaseModel):
295+
"""Certificate model."""
296+
297+
ca: str
298+
certificate: str
299+
chain: Optional[List[str]] = None
300+
version: int = pydantic.Field(
301+
description="Version of the interface used in this databag",
302+
default=0,
303+
)
304+
305+
306+
class ProviderUnitDataV0(DatabagModel):
307+
"""Provider Unit databag v0 model."""
308+
309+
certificates: List[_Certificate] = []
310+
311+
286312
class RequirerApplicationData(DatabagModel):
287313
"""Requirer App databag model."""
288314

@@ -399,14 +425,45 @@ def _get_relevant_relations(self, relation_id: Optional[int] = None) -> List[Rel
399425

400426
def _set_relation_data(self, relation: Relation, data: Set[str]) -> None:
401427
"""Set the given relation data."""
402-
databag = relation.data[self.model.app]
403-
ProviderApplicationData(certificates=data).dump(databag, False)
428+
if relation.data.get(relation.app, {}).get("version", "0") == "1":
429+
databag = relation.data[self.model.app]
430+
ProviderApplicationData(certificates=data).dump(databag, True)
431+
else:
432+
if "version" in relation.data.get(relation.app, {}):
433+
logger.warning(
434+
(
435+
"Requirer in relation %d is using version %s of the interface,",
436+
"defaulting to version 0.",
437+
"This is deprecated, please consider upgrading the requirer",
438+
"to version 1 of the library.",
439+
),
440+
relation.id,
441+
relation.data[relation.app]["version"],
442+
)
443+
else:
444+
logger.warning(
445+
(
446+
"Requirer in relation %d did not provide version field,",
447+
"defaulting to version 0.",
448+
"This is deprecated, please consider upgrading the requirer",
449+
"to version 1 of the library.",
450+
),
451+
relation.id,
452+
)
453+
454+
databag = relation.data[self.model.unit]
455+
certificates = [_Certificate(ca=cert, certificate=cert, chain=[cert]) for cert in data]
456+
ProviderUnitDataV0(certificates=certificates).dump(databag, True)
404457

405458
def _get_relation_data(self, relation: Relation) -> Set[str]:
406459
"""Get the given relation data."""
407-
databag = relation.data[self.model.app]
408460
try:
409-
return ProviderApplicationData().load(databag).certificates
461+
if relation.data.get(relation.app, {}).get("version", "0") == "1":
462+
databag = relation.data[self.model.app]
463+
return ProviderApplicationData().load(databag).certificates
464+
else:
465+
databag = relation.data[self.model.unit]
466+
return {cert.ca for cert in ProviderUnitDataV0().load(databag).certificates}
410467
except DataValidationError as e:
411468
logger.error(
412469
(
@@ -566,9 +623,13 @@ def is_ready(self, relation: Relation) -> bool:
566623

567624
def _get_relation_data(self, relation: Relation) -> Set[str]:
568625
"""Get the given relation data."""
569-
databag = relation.data[relation.app]
570626
try:
571-
return ProviderApplicationData().load(databag).certificates
627+
databag = relation.data[relation.app]
628+
certificates = ProviderApplicationData().load(databag).certificates
629+
if not certificates and relation.units:
630+
databag = relation.data.get(relation.units.pop(), {})
631+
return {cert.ca for cert in ProviderUnitDataV0().load(databag).certificates}
632+
return certificates
572633
except DataValidationError as e:
573634
logger.error(
574635
(

0 commit comments

Comments
 (0)