@@ -301,6 +301,12 @@ def entity_type(self):
301301 'application' or 'unit', etc.
302302
303303 """
304+ # Allow the overriding of entity names from the type instead of from
305+ # the class name. Useful because Model and ModelInfo clash and we really
306+ # want ModelInfo to be called Model.
307+ if hasattr (self .__class__ , "type_name_override" ) and callable (self .__class__ .type_name_override ):
308+ return self .__class__ .type_name_override ()
309+
304310 def first_lower (s ):
305311 if len (s ) == 0 :
306312 return s
@@ -449,6 +455,7 @@ def __init__(
449455 self ._observers = weakref .WeakValueDictionary ()
450456 self .state = ModelState (self )
451457 self ._info = None
458+ self ._mode = None
452459 self ._watch_stopping = asyncio .Event (loop = self ._connector .loop )
453460 self ._watch_stopped = asyncio .Event (loop = self ._connector .loop )
454461 self ._watch_received = asyncio .Event (loop = self ._connector .loop )
@@ -797,6 +804,10 @@ def info(self):
797804 """
798805 return self ._info
799806
807+ @property
808+ def strict_mode (self ):
809+ return self ._mode is not None and "strict" in self ._mode
810+
800811 def add_observer (
801812 self , callable_ , entity_type = None , action = None , entity_id = None ,
802813 predicate = None ):
@@ -843,7 +854,21 @@ def _watch(self):
843854 See :meth:`add_observer` to register an onchange callback.
844855
845856 """
857+ def _post_step (obj ):
858+ # Once we get the model, ensure we're running in the correct state
859+ # as a post step.
860+ if isinstance (obj , ModelInfo ) and obj .safe_data is not None :
861+ model_config = obj .safe_data ["config" ]
862+ if "mode" in model_config :
863+ self ._mode = model_config ["mode" ]
864+
846865 async def _all_watcher ():
866+ # First attempt to get the model config so we know what mode the
867+ # library should be running in.
868+ model_config = await self .get_config ()
869+ if "mode" in model_config :
870+ self ._mode = model_config ["mode" ]["value" ]
871+
847872 try :
848873 allwatcher = client .AllWatcherFacade .from_connection (
849874 self .connection ())
@@ -892,17 +917,20 @@ async def _all_watcher():
892917 pass # can't stop on a closed conn
893918 break
894919 for delta in results .deltas :
920+ entity = None
895921 try :
896- delta = get_entity_delta (delta )
897- old_obj , new_obj = self .state .apply_delta (delta )
898- await self ._notify_observers (delta , old_obj , new_obj )
899- except KeyError as e :
900- # TODO (stickupkid): we should raise the unknown delta
901- # type, so we handle correctly all the types comming from
902- # the all watcher. Currently they're ignored, causing
903- # issue.
904- # raise JujuError("unknown delta type {}".format(e.args))
905- log .warning ("unknown delta type: %s" , e .args [0 ])
922+ entity = get_entity_delta (delta )
923+ except KeyError :
924+ if self .strict_mode :
925+ raise JujuError ("unknown delta type '{}'" .format (delta .entity ))
926+
927+ if not self .strict_mode and entity is None :
928+ continue
929+ old_obj , new_obj = self .state .apply_delta (entity )
930+ await self ._notify_observers (entity , old_obj , new_obj )
931+ # Post step ensure that we can handle any settings
932+ # that need to be correctly set as a post step.
933+ _post_step (new_obj )
906934 self ._watch_received .set ()
907935 except CancelledError :
908936 pass
@@ -2270,6 +2298,11 @@ def _ignore(self, path):
22702298
22712299
22722300class ModelInfo (ModelEntity ):
2301+
22732302 @property
22742303 def tag (self ):
22752304 return tag .model (self .uuid )
2305+
2306+ @staticmethod
2307+ def type_name_override ():
2308+ return "model"
0 commit comments