@@ -331,7 +331,7 @@ def _on_topic_requested(self, event: TopicRequestedEvent):
331
331
332
332
# Increment this PATCH version before using `charmcraft publish-lib` or reset
333
333
# to 0 if you are raising the major API version
334
- LIBPATCH = 46
334
+ LIBPATCH = 48
335
335
336
336
PYDEPS = ["ops>=2.0.0" ]
337
337
@@ -2569,7 +2569,7 @@ def __init__(
2569
2569
2570
2570
2571
2571
################################################################################
2572
- # Cross-charm Relatoins Data Handling and Evenets
2572
+ # Cross-charm Relations Data Handling and Events
2573
2573
################################################################################
2574
2574
2575
2575
# Generic events
@@ -3268,7 +3268,7 @@ def __init__(
3268
3268
# Kafka Events
3269
3269
3270
3270
3271
- class KafkaProvidesEvent (RelationEvent ):
3271
+ class KafkaProvidesEvent (RelationEventWithSecret ):
3272
3272
"""Base class for Kafka events."""
3273
3273
3274
3274
@property
@@ -3287,6 +3287,40 @@ def consumer_group_prefix(self) -> Optional[str]:
3287
3287
3288
3288
return self .relation .data [self .relation .app ].get ("consumer-group-prefix" )
3289
3289
3290
+ @property
3291
+ def mtls_cert (self ) -> Optional [str ]:
3292
+ """Returns TLS cert of the client."""
3293
+ if not self .relation .app :
3294
+ return None
3295
+
3296
+ if not self .secrets_enabled :
3297
+ raise SecretsUnavailableError ("Secrets unavailable on current Juju version" )
3298
+
3299
+ secret_field = f"{ PROV_SECRET_PREFIX } { SECRET_GROUPS .MTLS } "
3300
+ if secret_uri := self .relation .data [self .app ].get (secret_field ):
3301
+ secret = self .framework .model .get_secret (id = secret_uri )
3302
+ content = secret .get_content (refresh = True )
3303
+ if content :
3304
+ return content .get ("mtls-cert" )
3305
+
3306
+
3307
+ class KafkaClientMtlsCertUpdatedEvent (KafkaProvidesEvent ):
3308
+ """Event emitted when the mtls relation is updated."""
3309
+
3310
+ def __init__ (self , handle , relation , old_mtls_cert : Optional [str ] = None , app = None , unit = None ):
3311
+ super ().__init__ (handle , relation , app , unit )
3312
+
3313
+ self .old_mtls_cert = old_mtls_cert
3314
+
3315
+ def snapshot (self ):
3316
+ """Return a snapshot of the event."""
3317
+ return super ().snapshot () | {"old_mtls_cert" : self .old_mtls_cert }
3318
+
3319
+ def restore (self , snapshot ):
3320
+ """Restore the event from a snapshot."""
3321
+ super ().restore (snapshot )
3322
+ self .old_mtls_cert = snapshot ["old_mtls_cert" ]
3323
+
3290
3324
3291
3325
class TopicRequestedEvent (KafkaProvidesEvent , ExtraRoleEvent ):
3292
3326
"""Event emitted when a new topic is requested for use on this relation."""
@@ -3299,6 +3333,7 @@ class KafkaProvidesEvents(CharmEvents):
3299
3333
"""
3300
3334
3301
3335
topic_requested = EventSource (TopicRequestedEvent )
3336
+ mtls_cert_updated = EventSource (KafkaClientMtlsCertUpdatedEvent )
3302
3337
3303
3338
3304
3339
class KafkaRequiresEvent (RelationEvent ):
@@ -3416,6 +3451,13 @@ def __init__(self, charm: CharmBase, relation_data: KafkaProviderData) -> None:
3416
3451
def _on_relation_changed_event (self , event : RelationChangedEvent ) -> None :
3417
3452
"""Event emitted when the relation has changed."""
3418
3453
super ()._on_relation_changed_event (event )
3454
+
3455
+ new_data_keys = list (event .relation .data [event .app ].keys ())
3456
+ if any (newval for newval in new_data_keys if self .relation_data ._is_secret_field (newval )):
3457
+ self .relation_data ._register_secrets_to_relation (event .relation , new_data_keys )
3458
+
3459
+ getattr (self .on , "mtls_cert_updated" ).emit (event .relation , app = event .app , unit = event .unit )
3460
+
3419
3461
# Leader only
3420
3462
if not self .relation_data .local_unit .is_leader ():
3421
3463
return
@@ -3430,6 +3472,33 @@ def _on_relation_changed_event(self, event: RelationChangedEvent) -> None:
3430
3472
event .relation , app = event .app , unit = event .unit
3431
3473
)
3432
3474
3475
+ def _on_secret_changed_event (self , event : SecretChangedEvent ):
3476
+ """Event notifying about a new value of a secret."""
3477
+ if not event .secret .label :
3478
+ return
3479
+
3480
+ relation = self .relation_data ._relation_from_secret_label (event .secret .label )
3481
+ if not relation :
3482
+ logging .info (
3483
+ f"Received secret { event .secret .label } but couldn't parse, seems irrelevant"
3484
+ )
3485
+ return
3486
+
3487
+ if relation .app == self .charm .app :
3488
+ logging .info ("Secret changed event ignored for Secret Owner" )
3489
+
3490
+ remote_unit = None
3491
+ for unit in relation .units :
3492
+ if unit .app != self .charm .app :
3493
+ remote_unit = unit
3494
+
3495
+ old_mtls_cert = event .secret .get_content ().get ("mtls-cert" )
3496
+ # mtls-cert is the only secret that can be updated
3497
+ logger .info ("mtls-cert updated" )
3498
+ getattr (self .on , "mtls_cert_updated" ).emit (
3499
+ relation , app = relation .app , unit = remote_unit , old_mtls_cert = old_mtls_cert
3500
+ )
3501
+
3433
3502
3434
3503
class KafkaProvides (KafkaProviderData , KafkaProviderEventHandlers ):
3435
3504
"""Provider-side of the Kafka relation."""
@@ -3450,11 +3519,13 @@ def __init__(
3450
3519
extra_user_roles : Optional [str ] = None ,
3451
3520
consumer_group_prefix : Optional [str ] = None ,
3452
3521
additional_secret_fields : Optional [List [str ]] = [],
3522
+ mtls_cert : Optional [str ] = None ,
3453
3523
):
3454
3524
"""Manager of Kafka client relations."""
3455
3525
super ().__init__ (model , relation_name , extra_user_roles , additional_secret_fields )
3456
3526
self .topic = topic
3457
3527
self .consumer_group_prefix = consumer_group_prefix or ""
3528
+ self .mtls_cert = mtls_cert
3458
3529
3459
3530
@property
3460
3531
def topic (self ):
@@ -3468,6 +3539,15 @@ def topic(self, value):
3468
3539
raise ValueError (f"Error on topic '{ value } ', cannot be a wildcard." )
3469
3540
self ._topic = value
3470
3541
3542
+ def set_mtls_cert (self , relation_id : int , mtls_cert : str ) -> None :
3543
+ """Set the mtls cert in the application relation databag / secret.
3544
+
3545
+ Args:
3546
+ relation_id: the identifier for a particular relation.
3547
+ mtls_cert: mtls cert.
3548
+ """
3549
+ self .update_relation_data (relation_id , {"mtls-cert" : mtls_cert })
3550
+
3471
3551
3472
3552
class KafkaRequirerEventHandlers (RequirerEventHandlers ):
3473
3553
"""Requires-side of the Kafka relation."""
@@ -3489,6 +3569,9 @@ def _on_relation_created_event(self, event: RelationCreatedEvent) -> None:
3489
3569
# Sets topic, extra user roles, and "consumer-group-prefix" in the relation
3490
3570
relation_data = {"topic" : self .relation_data .topic }
3491
3571
3572
+ if self .relation_data .mtls_cert :
3573
+ relation_data ["mtls-cert" ] = self .relation_data .mtls_cert
3574
+
3492
3575
if self .relation_data .extra_user_roles :
3493
3576
relation_data ["extra-user-roles" ] = self .relation_data .extra_user_roles
3494
3577
@@ -3547,15 +3630,17 @@ def __init__(
3547
3630
extra_user_roles : Optional [str ] = None ,
3548
3631
consumer_group_prefix : Optional [str ] = None ,
3549
3632
additional_secret_fields : Optional [List [str ]] = [],
3633
+ mtls_cert : Optional [str ] = None ,
3550
3634
) -> None :
3551
3635
KafkaRequirerData .__init__ (
3552
3636
self ,
3553
3637
charm .model ,
3554
3638
relation_name ,
3555
3639
topic ,
3556
- extra_user_roles ,
3557
- consumer_group_prefix ,
3558
- additional_secret_fields ,
3640
+ extra_user_roles = extra_user_roles ,
3641
+ consumer_group_prefix = consumer_group_prefix ,
3642
+ additional_secret_fields = additional_secret_fields ,
3643
+ mtls_cert = mtls_cert ,
3559
3644
)
3560
3645
KafkaRequirerEventHandlers .__init__ (self , charm , self )
3561
3646
@@ -3675,6 +3760,10 @@ def _on_relation_changed_event(self, event: RelationChangedEvent) -> None:
3675
3760
event .relation , app = event .app , unit = event .unit
3676
3761
)
3677
3762
3763
+ def _on_secret_changed_event (self , event : SecretChangedEvent ) -> None :
3764
+ """Event emitted when the relation data has changed."""
3765
+ pass
3766
+
3678
3767
3679
3768
class OpenSearchProvides (OpenSearchProvidesData , OpenSearchProvidesEventHandlers ):
3680
3769
"""Provider-side of the OpenSearch relation."""
0 commit comments