+
     g=              
          ^ RI t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIH	t	 ^ RI
HtHtHtHtHt ^ RIHtHt ^ RIHt ^ RIHt ]! 4       tR R lt]P4                  ! ]! ]4      4      t ! R	 R
]P:                  4      t ! R R]P>                  4      t R t!R5R R llt"R. 3R R llt#R6R R llt$R R lt%. R7Ot&]&3R R llt'R R lt(R R lt)R R lt*R t+R  t,R!R"R#R$R%R&R'R(R)R*/t-R+ R, lt.R- R. lt/R/ R0 lt0R1 R2 lt1R3 R4 lt2R# )8    Nwraps)AnyDictListOptionalUnion)
exceptionsmessages)CONFIG_FIELD_ENVVAR_ALLOWLIST)MessagingOperationsc                0    V ^8  d   QhR\         R\         /# )   namereturnstr)formats   "//usr/lib/python3/dist-packages/uaclient/util.py__annotate__r      s            c                b    V R8X  d   R# V P                  R4      pRV^ &   RP                  V4      # )z1Replace the name of the root logger from __name__ .	ubuntupro)splitjoin)r   namess   & r   replace_top_level_logger_namer      s0    rzJJsOEE!H88E?r   c                   6   a a ] tR t^t oRtV 3R ltRtVtV ;t# )DatetimeAwareJSONEncoderzBA json.JSONEncoder subclass that writes out isoformat'd datetimes.c                   < \        V\        P                  4      '       d   VP                  4       # \        SV `  V4      # N)
isinstancedatetime	isoformatsuperdefault)selfo	__class__s   &&r   r(    DatetimeAwareJSONEncoder.default"   s1    a**++;;= wq!!r    )	__name__
__module____qualname____firstlineno____doc__r(   __static_attributes____classdictcell____classcell__r+   __classdict__s   @@r   r!   r!      s     L" "r   r!   c                   F   a a ] tR t^(t oRtV 3R lt]R 4       tRtVt	V ;t
# )DatetimeAwareJSONDecodera  
A JSONDecoder that parses some ISO datetime strings to datetime objects.

Important note: the "some" is because we seem to only be able extend
Python's json library in a way that lets us convert string values within
JSON objects (e.g. '{"lastModified": "2019-07-25T14:35:51"}'). Strings
outside of JSON objects (e.g. '"2019-07-25T14:35:51"') will not be passed
through our decoder.

(N.B. This will override any object_hook specified using arguments to it,
or used in load or loads calls that specify this as the cls.)
c                p   < R V9   d   VP                  R 4       \        SV `  ! VR V P                  /VB  R# )object_hookN)popr'   __init__r;   )r)   argskwargsr+   s   &*,r   r=   !DatetimeAwareJSONDecoder.__init__6   s4    F"JJ}%$GD,<,<GGr   c                    V P                  4        F-  w  r\        V\        4      '       g   K   \        V4      pW0V&   K/  	  V #   \         d    Tp Li ; ir#   )itemsr$   r   parse_rfc3339_date
ValueError)r*   keyvalue	new_values   &   r   r;   $DatetimeAwareJSONDecoder.object_hook;   sY    '')JC%%%& 2!I ## $ 	 " & %I&s   AAAr-   )r.   r/   r0   r1   r2   r=   staticmethodr;   r3   r4   r5   r6   s   @@r   r9   r9   (   s)     H
   r   r9   c                   a a V V3R lpV# )a  Decorator to retry on exception for retry_sleeps.

@param retry_sleeps: List of sleep lengths to apply between
   retries. Specifying a list of [0.5, 1] tells subp to retry twice
   on failure; sleeping half a second before the first retry and 1 second
   before the second retry.
@param exception: The exception class to catch and retry for the provided
   retry_sleeps. Any other exception types will not be caught by the
   decorator.
c                 6   <a  \        S 4      VV V3R  l4       pV# )c                    < SP                  4       p  S! V / VB #   S dd   pT'       g   Th\        P                  R\        T4      \	        T4      4       \
        P                  ! TP                  ^ 4      4        Rp?Ko  Rp?ii ; i)Tz%s: Retrying %d more times.N)copyLOGdebugr   lentimesleepr<   )r>   r?   sleepse	exceptionfretry_sleepss   *,  r   	decorator)retry.<locals>.wrapper.<locals>.decoratorW   su    !&&(F.d-f--  .!II5s1vs6{ JJvzz!}--.s    BABBr   )rV   rX   rU   rW   s   f r   wrapperretry.<locals>.wrapperV   s!    	q	. 
	. r   r-   )rU   rW   rZ   s   ff r   retryr\   J   s    " Nr   r   c          
          V ^8  d   QhR\         \        \        3,          R\         \        \        3,          R\        R\         \        \        3,          /# )r   	orig_dictnew_dictpathr   )r   r   r   )r   s   "r   r   r   j   sD      CH~)-c3h?B	#s(^r   c                   / pV P                  4        F  w  rEVP                  V\        4      pV'       g   TMVR,           V,           p\        V\        4      '       d5   WA9   d%   \        WQV,          VR7      pV'       d   WV&   Ks  Ku  \        W4&   K  WV8w  g   K  \        P                  RV\        V4      4       WcV&   K  	  VP                  4        F  w  rEW@9  g   K  WSV&   K  	  V# )z<Return a dictionary of delta between orig_dict and new_dict.r   )r`   z'Contract value for '%s' changed to '%s')	rB   getDROPPED_KEYr$   dictget_dict_deltasrN   rO   r   )	r^   r_   r`   deltasrE   rF   rG   key_path	sub_deltas	   &&&      r   re   re   j   s     Foo'
LLk2	"3s
S(8eT""+C=x	 "+3K  *II9I
 $3K% (& nn&
3K ' Mr   c                R    V ^8  d   QhR\         R\        \         ,          R\         /# )r   msgvalid_choicesr   )r   r   )r   s   "r   r   r      s%       c C r   c           
     F   ^ RI Hp VP                  4       pRpRP                  TRP	                  V Uu. uF  qUP                  4       NK  	  up4      4      p VP                  V 4       \        R4      P                  4       pWA9   d    V# VP                  V4       KG  u upi )a3  Interactive prompt message, returning a valid choice from msg.

Expects a structured msg which designates choices with square brackets []
around the characters which indicate a valid choice.

Uppercase and lowercase responses are allowed. Loop on invalid choices.

:return: Valid response character chosen.
)event_loggerr   z{} is not one of: {}z, z> )	uaclientrm   get_event_loggerr   r   upperinfoinputlower)rj   rk   rm   eventrF   choice	error_msgs   &&     r   prompt_choicesrw      s     &))+EE&--tyy}E}V,,.}EFI 

3d!!#!L 	

9 Fs   Bc                H    V ^8  d   QhR\         R\        R\        R\        /# )r   rj   
assume_yesr(   r   )r   bool)r   s   "r   r   r      s,      	#6:	r   c                    V'       d   R# V '       g   \         P                  p \        V 4      P                  4       P	                  4       pVR8X  d   V# VR9   d   R# R# )a}  
Display a confirmation prompt, returning a bool indicating the response

:param msg: String custom prompt text to emit from input call.
:param assume_yes: Boolean set True to skip confirmation input and return
    True.
:param default: Boolean to return when user doesn't enter any text

This function will only prompt a single time, and defaults to "no" (i.e. it
returns False).
Tr   F)yyes)r   PROMPT_YES_NOrr   rs   strip)rj   ry   r(   rF   s   &&& r   prompt_for_confirmationr      sM     $$#J$$&E{r   c                ^    V ^8  d   QhR\         \        \        3,          R\        R\        /# )r   configpath_to_valuer   )r   r   r   rz   )r   s   "r   r   r      s)     $
 $
c3h $
 $
 $
r   c                X   T p/ pVP                  R4      pVR,          pV F5  pWe8X  d   Rp\        V\        4      '       d   VP                  Wc4      pK4   R# 	  \	        V4      pVP                  4       R8X  d   R# VP                  4       R8X  d   R# \        P                  ! VRVR7      h)	a"  Check if value parameter can be translated into a boolean 'True' value.

@param config: A config dict representing
               /etc/ubuntu-advantange/uaclient.conf
@param path_to_value: The path from where the value parameter was
                      extracted.
@return: A boolean value indicating if the value paramater corresponds
         to a 'True' boolean value.
@raises exceptions.UbuntuProError when the value provide by the
        path_to_value parameter can not be translated into either
        a 'False' or 'True' boolean value.
r   falseFtrueTzboolean string: true or false)r   expected_valuerF   )r   r$   rd   rb   r   rs   r
   InvalidBooleanConfigValue)r   r   rF   default_valuepaths
leaf_valuerE   	value_strs   &&      r   is_config_value_truer      s     EM$ErJ#MeT""IIc1E  E
IF"		g	%22':
 	
r   c                F    V ^8  d   QhR\         \        ,          R\        /# )r   redact_regexsr   r   r   )r   s   "r   r   r     s       S	r   c                L    T pV F  p\         P                  ! VRV4      pK  	  V# )z4Redact known sensitive information from log content.z\g<1><REDACTED>)resub)logr   redacted_logredact_regexs   &&  r   redact_sensitive_logsr     s,     L%vvl,>M &r   c                R    V ^8  d   QhR\         \        ,          R\        R\        /# )r   msg_opsry   r   )r   r   rz   )r   s   "r   r   r     s*      )*8<	r   c                    V '       g   R# V  F?  p\        V\        4      '       d   \        V4       K&  Vw  r4WR&   V! R/ VB '       d   K>   R# 	  R# )aP  Emit messages to the console for user interaction

:param msg_op: A list of strings or tuples. Any string items are printed.
    Any tuples will contain a callable and a dict of args to pass to the
    callable. Callables are expected to return True on success and
    False upon failure.

:return: True upon success, False on failure.
Try   Fr-   )r$   r   print)r   ry   msg_opfunctorr>   s   &&   r   handle_message_operationsr     sJ     fc""&M"MG!+?T??  r   c                D    V ^8  d   QhR\         R\        P                  /# )r   dt_strr   )r   r%   )r   s   "r   r   r   &  s      4 4s 4x'8'8 4r   c                    \         P                  ! RRV 4      p\         P                  ! RRV4      pVP                  RR4      p\         P                  ! RRV4      p\        P                  P	                  VR	4      # )
a8  
Parse a datestring in rfc3339 format. Originally written for compatibility
with golang's time.MarshalJSON function. Also handles output of pythons
isoformat datetime method.

This drops subseconds.

:param dt_str: a date string in rfc3339 format

:return: datetime.datetime object of time represented by dt_str
z(\d{2}:\d{2}:\d{2})\.\d+z\g<1>z(\d{2}:\d{2}:\d{2})$z\g<1>ZZz+00:00z(-|\+)(\d{2}):(\d{2})$z\g<1>\g<2>\g<3>z%Y-%m-%dT%H:%M:%S%z)r   r   replacer%   strptime)r   dt_str_without_subsecondsdt_str_with_zdt_str_without_zdt_str_with_pythonish_tzs   &    r   rC   rC   &  s    ( !##Xv! FF,EM %,,S(;  "vv!#57G  %% "7 r   c                0    V ^8  d   QhR\         R\         /# )r   messager   r   )r   s   "r   r   r   ]  s      s s r   c                   \         P                  P                  e.   R\         P                  P                  P                  4       9  d   V P	                  RR4      p V P	                  \
        P                  R,           R4      p V P	                  \
        P                  R,           R4      p V P                  RR4      P                  4       p V # )zq
Verify if the system can output unicode characters and if not,
remove those characters from the message string.
zUTF-8u   —- r   asciiignore)
sysstdoutencodingrp   r   r   OKGREEN_CHECKFAIL_Xencodedecode)r   s   &r   handle_unicode_charactersr   ]  s     	

##**--3355
 //(C0
 //("8"83">C//(//C"7< ..(3::<Nr   c                      \         P                  P                  4        U Uu/ uF@  w  rV P                  4       \        9   g!   V P                  R 4      '       g
   V R8X  g   K>  WbKB  	  upp # u upp i )UA_FEATURESUA_CONFIG_FILE)osenvironrB   rs   r   
startswith)kvs     r   get_pro_environmentr   w  sc     JJ$$&&DA77955<<&&  	 	&  s   6A,A,"A,c                   R pVP                  4        F  w  r4V P                  V4      p\        V\        4      '       d+   \        V\        4      '       d   \	        W,          V4       KV  \        V\
        4      '       d^   \        V\
        4      '       dH   \        V4      '       d0   \        V^ ,          \        4      '       d   V! W,          WCR7       K   W@V&   K  W@V&   K  	  R# )a  Merge the contents of overlay dict into base_dict not only on top-level
keys, but on all on the depths of the overlay_dict object. For example,
using these values as entries for the function:

base_dict = {"a": 1, "b": {"c": 2, "d": 3}}
overlay_dict = {"b": {"c": 10}}

Should update base_dict into:

{"a": 1, "b": {"c": 10, "d": 3}}

@param base_dict: The dict to be updated
@param overlay_dict: The dict with information to be added into base_dict
c                 :   R RRRRR/p. pVP                  V4      pV Fh  pRp\        V 4       F9  w  rV	P                  V4      VP                  V4      8X  g   K,  \        W4       RpK;  	  V'       d   KW  VP                  V4       Kj  	  V P	                  V4       R# )	availableResourcesr   resourceEntitlementstype	overridesselectorFTN)rb   	enumeratedepth_first_merge_overlay_dictappendextend)
base_valuesoverlay_valuesrE   merge_id_key_mapvalues_to_appendid_keyoverlay_valuewas_replacedbase_value_idx
base_values
   &&&       r   update_dict_list8depth_first_merge_overlay_dict.<locals>.update_dict_list  s     &"F

 !%%c*+M L.7.D*>>&)]->->v-FF2:M#'L /E
  < ''6 , 	+,r   )rE   N)rB   rb   r$   rd   r   listrP   )	base_dictoverlay_dictr   rE   rF   r   s   &&    r   r   r     s     -( #((*
]]3'
j$''Jud,C,C*9>5A
D))j.E.E::jmT#B#B @E "'#"cN +r   x86_64amd64i686i386ppc64leppc64elaarch64arm64armv7larmhfc                0    V ^8  d   QhR\         R\         /# )r   archr   r   )r   s   "r   r   r     s     4 4 4 4r   c                 L    V P                  4       p\        P                  W4      # r#   )rs   ARCH_ALIASESrb   )r   
arch_lowers   & r   standardize_arch_namer     s    JJ33r   c                \    V ^8  d   QhR\         \        ,          R\         \        ,          /# )r   archesr   r   )r   s   "r   r   r     s"     - -tCy -T#Y -r   c                     \        4       pV  F  pVP                  \        V4      4       K  	  \        \	        V4      4      # r#   )setaddr   sortedr   )r   deduplicated_archesr   s   &  r   deduplicate_archesr     s9    % 5d ;< $*+,,r   c                $    V ^8  d   QhR\         /# )r   r   )rz   )r   s   "r   r   r     s      t r   c                  2    \         P                  ! 4       ^ 8H  # )r   )r   getuidr-   r   r   we_are_currently_rootr     s    99;!r   c                <    V ^8  d   QhR\         R\         R\         /# )r   filenamenew_extensionr   r   )r   s   "r   r   r     s!     & &S & & &r   c                 d    \         P                  P                  V 4      w  r#VR ,           V,           # )r   )r   r`   splitext)r   r   r   
_extensions   &&  r   set_filename_extensionr     s(    ww''1D#:%%r   c                :    V ^8  d   QhR\         \        ,          /# )r   package_listr   )r   s   "r   r   r     s      s)r   c                     R P                  \        P                  ! RP                  V 4      ^PRRRRR7      4      R ,           # )
r   Fz  )widthbreak_long_wordsbreak_on_hyphensinitial_indentsubsequent_indent)r   textwrapwrap)r   s   &r   create_package_list_strr	    sF     			MM&!&!&#"&		
 
	r   )r   )r   FF)z(Bearer )[^\']+z(\'attach\', \')[^\']+z(\'machineToken\': \')[^\']+(\'token\': \')[^\']+z((\'X-aws-ec2-metadata-token\': \')[^\']+z*(.*\[PUT\] response.*api/token,.*data: ).*z(https://bearer:)[^\@]+z1(/snap/bin/canonical-livepatch\s+enable\s+)[^\s]+z>(Contract\s+value\s+for\s+'resourceToken'\s+changed\s+to\s+).*z(\'resourceToken\': \')[^\']+z(\'contractToken\': \')[^\']+zF(https://contracts.canonical.com/v1/resources/livepatch\?token=)[^\s]+z(\"identityToken\": \")[^\"]+zT(response:\s+http://metadata/computeMetadata/v1/instance/service-accounts.*data: ).*r
  z(\'userCode\': \')[^\']+z(\'magic_token=)[^\']+z(--registration-key=\")[^\"]+z(--registration-key=\')[^\']+z(--registration-key=)[^ ]+z(--registration-key \")[^\"]+z(--registration-key \')[^\']+z(--registration-key )[^\s]+z(-p \")[^\"]+z(-p \')[^\']+z(-p )[^\s]+)3r%   jsonloggingr   r   r   r  rQ   	functoolsr   typingr   r   r   r   r	   rn   r
   r   uaclient.defaultsr   uaclient.typesr   objectrc   r   	getLoggerr.   rN   JSONEncoderr!   JSONDecoderr9   r\   re   rw   r   r   REDACT_SENSITIVE_LOGSr   r   rC   r   r   r   r   r   r   r   r   r	  r-   r   r   <module>r     s      	 	 
    3 3 ) ; .h 5h?@"t// "t// D@< !R 44$
N @ %:44n41#j g
Fywg4
-&
r   