@@ -334,6 +334,10 @@ def __init__(self, *args):
334334 self.framework.observe(
335335 self.karapace.on.subject_allowed, self._on_karapace_subject_allowed
336336 )
337+ self.framework.observe(
338+ self.karapace.on.subject_entity_created, self._on_subject_entity_created
339+ )
340+
337341
338342 def _on_karapace_server_changed(self, event: EndpointsChangedEvent):
339343 # Event triggered when a server endpoint was changed for this application
@@ -347,6 +351,12 @@ def _on_karapace_subject_allowed(self, event: SubjectAllowedEvent):
347351 tls = event.tls
348352 endpoints = event.endpoints
349353 ...
354+
355+ def _on_subject_entity_created(self, event: SubjectEntityCreatedEvent):
356+ # Event triggered when a subject entity was created this application
357+ entity_name = event.entity_name
358+ entity_password = event.entity_password
359+ ...
350360```
351361
352362As shown above, the library provides some custom events to handle specific situations,
@@ -437,7 +447,7 @@ def _on_subject_requested(self, event: SubjectRequestedEvent):
437447
438448# Increment this PATCH version before using `charmcraft publish-lib` or reset
439449# to 0 if you are raising the major API version
440- LIBPATCH = 51
450+ LIBPATCH = 52
441451
442452PYDEPS = ["ops>=2.0.0" ]
443453
@@ -4126,13 +4136,23 @@ def extra_user_roles(self) -> Optional[str]:
41264136 return self .relation .data [self .relation .app ].get ("extra-user-roles" )
41274137
41284138
4139+ class SubjectEntityRequestedEvent (KarapaceProvidesEvent , EntityProvidesEvent ):
4140+ """Event emitted when a new entity is requested for use on this relation."""
4141+
4142+
4143+ class SubjectEntityPermissionsChangedEvent (KarapaceProvidesEvent , EntityProvidesEvent ):
4144+ """Event emitted when existing entity permissions are changed on this relation."""
4145+
4146+
41294147class KarapaceProvidesEvents (CharmEvents ):
41304148 """Karapace events.
41314149
41324150 This class defines the events that the Karapace can emit.
41334151 """
41344152
41354153 subject_requested = EventSource (SubjectRequestedEvent )
4154+ subject_entity_requested = EventSource (SubjectEntityRequestedEvent )
4155+ subject_entity_permissions_changed = EventSource (SubjectEntityPermissionsChangedEvent )
41364156
41374157
41384158class KarapaceRequiresEvent (RelationEvent ):
@@ -4159,6 +4179,10 @@ class SubjectAllowedEvent(AuthenticationEvent, KarapaceRequiresEvent):
41594179 """Event emitted when a new subject ACL is created for use on this relation."""
41604180
41614181
4182+ class SubjectEntityCreatedEvent (EntityRequiresEvent , KarapaceRequiresEvent ):
4183+ """Event emitted when a new entity is created for use on this relation."""
4184+
4185+
41624186class EndpointsChangedEvent (AuthenticationEvent , KarapaceRequiresEvent ):
41634187 """Event emitted when the endpoints are changed."""
41644188
@@ -4170,6 +4194,7 @@ class KarapaceRequiresEvents(CharmEvents):
41704194 """
41714195
41724196 subject_allowed = EventSource (SubjectAllowedEvent )
4197+ subject_entity_created = EventSource (SubjectEntityCreatedEvent )
41734198 server_changed = EventSource (EndpointsChangedEvent )
41744199
41754200
@@ -4227,13 +4252,40 @@ def _on_relation_changed_event(self, event: RelationChangedEvent) -> None:
42274252 # Validate entity information is not dynamically changed
42284253 self ._validate_entity_consistency (event , diff )
42294254
4230- # Emit a subject requested event if the setup key (subject name and optional
4231- # extra user roles) was added to the relation databag by the application .
4232- if "subject" in diff .added :
4255+ # Emit a subject requested event if the setup key (subject name)
4256+ # was added to the relation databag, but the entity-type key was not .
4257+ if "subject" in diff .added and "entity-type" not in diff . added :
42334258 getattr (self .on , "subject_requested" ).emit (
42344259 event .relation , app = event .app , unit = event .unit
42354260 )
42364261
4262+ # To avoid unnecessary application restarts do not trigger other events.
4263+ return
4264+
4265+ # Emit an entity requested event if the setup key (subject name)
4266+ # was added to the relation databag, in addition to the entity-type key.
4267+ if "subject" in diff .added and "entity-type" in diff .added :
4268+ getattr (self .on , "subject_entity_requested" ).emit (
4269+ event .relation , app = event .app , unit = event .unit
4270+ )
4271+
4272+ # To avoid unnecessary application restarts do not trigger other events.
4273+ return
4274+
4275+ # Emit a permissions changed event if the setup key (subject name)
4276+ # was added to the relation databag, and the entity-permissions key changed.
4277+ if (
4278+ "subject" not in diff .added
4279+ and "entity-type" not in diff .added
4280+ and ("entity-permissions" in diff .added or "entity-permissions" in diff .changed )
4281+ ):
4282+ getattr (self .on , "subject_entity_permissions_changed" ).emit (
4283+ event .relation , app = event .app , unit = event .unit
4284+ )
4285+
4286+ # To avoid unnecessary application restarts do not trigger other events.
4287+ return
4288+
42374289 def _on_secret_changed_event (self , event : SecretChangedEvent ):
42384290 """Event notifying about a new value of a secret."""
42394291 pass
@@ -4257,9 +4309,20 @@ def __init__(
42574309 subject : str ,
42584310 extra_user_roles : Optional [str ] = None ,
42594311 additional_secret_fields : Optional [List [str ]] = [],
4312+ extra_group_roles : Optional [str ] = None ,
4313+ entity_type : Optional [str ] = None ,
4314+ entity_permissions : Optional [str ] = None ,
42604315 ):
42614316 """Manager of Karapace client relations."""
4262- super ().__init__ (model , relation_name , extra_user_roles , additional_secret_fields )
4317+ super ().__init__ (
4318+ model ,
4319+ relation_name ,
4320+ extra_user_roles ,
4321+ additional_secret_fields ,
4322+ extra_group_roles ,
4323+ entity_type ,
4324+ entity_permissions ,
4325+ )
42634326 self .subject = subject
42644327
42654328 @property
@@ -4297,6 +4360,12 @@ def _on_relation_created_event(self, event: RelationCreatedEvent) -> None:
42974360
42984361 if self .relation_data .extra_user_roles :
42994362 relation_data ["extra-user-roles" ] = self .relation_data .extra_user_roles
4363+ if self .relation_data .extra_group_roles :
4364+ relation_data ["extra-group-roles" ] = self .relation_data .extra_group_roles
4365+ if self .relation_data .entity_type :
4366+ relation_data ["entity-type" ] = self .relation_data .entity_type
4367+ if self .relation_data .entity_permissions :
4368+ relation_data ["entity-permissions" ] = self .relation_data .entity_permissions
43004369
43014370 self .relation_data .update_relation_data (event .relation .id , relation_data )
43024371
@@ -4316,18 +4385,28 @@ def _on_relation_changed_event(self, event: RelationChangedEvent) -> None:
43164385 if any (newval for newval in diff .added if self .relation_data ._is_secret_field (newval )):
43174386 self .relation_data ._register_secrets_to_relation (event .relation , diff .added )
43184387
4319- secret_field_user = self .relation_data ._generate_secret_field_name (SECRET_GROUPS .USER )
4320- if (
4321- "username" in diff .added and "password" in diff .added
4322- ) or secret_field_user in diff .added :
4388+ app_databag = get_encoded_dict (event .relation , event .app , "data" )
4389+ if app_databag is None :
4390+ app_databag = {}
4391+
4392+ if self ._main_credentials_shared (diff ) and "entity-type" not in app_databag :
43234393 # Emit the default event (the one without an alias).
43244394 logger .info ("subject ACL created at %s" , datetime .now ())
43254395 getattr (self .on , "subject_allowed" ).emit (
43264396 event .relation , app = event .app , unit = event .unit
43274397 )
43284398
4329- # To avoid unnecessary application restarts do not trigger
4330- # “endpoints_changed“ event if “subject_allowed“ is triggered.
4399+ # To avoid unnecessary application restarts do not trigger other events.
4400+ return
4401+
4402+ if self ._entity_credentials_shared (diff ) and "entity-type" in app_databag :
4403+ # Emit the default event (the one without an alias).
4404+ logger .info ("entity created at %s" , datetime .now ())
4405+ getattr (self .on , "subject_entity_created" ).emit (
4406+ event .relation , app = event .app , unit = event .unit
4407+ )
4408+
4409+ # To avoid unnecessary application restarts do not trigger other events.
43314410 return
43324411
43334412 # Emit an endpoints changed event if the Karapace endpoints added or changed
@@ -4338,6 +4417,8 @@ def _on_relation_changed_event(self, event: RelationChangedEvent) -> None:
43384417 getattr (self .on , "server_changed" ).emit (
43394418 event .relation , app = event .app , unit = event .unit
43404419 ) # here check if this is the right design
4420+
4421+ # To avoid unnecessary application restarts do not trigger other events.
43414422 return
43424423
43434424
@@ -4351,6 +4432,9 @@ def __init__(
43514432 subject : str ,
43524433 extra_user_roles : Optional [str ] = None ,
43534434 additional_secret_fields : Optional [List [str ]] = [],
4435+ extra_group_roles : Optional [str ] = None ,
4436+ entity_type : Optional [str ] = None ,
4437+ entity_permissions : Optional [str ] = None ,
43544438 ) -> None :
43554439 KarapaceRequirerData .__init__ (
43564440 self ,
@@ -4359,6 +4443,9 @@ def __init__(
43594443 subject ,
43604444 extra_user_roles ,
43614445 additional_secret_fields ,
4446+ extra_group_roles ,
4447+ entity_type ,
4448+ entity_permissions ,
43624449 )
43634450 KarapaceRequirerEventHandlers .__init__ (self , charm , self )
43644451
0 commit comments