Ë
    GKÕiÌ=  ã                   óº  — d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlm	Z	 d dl
mZmZmZmZmZ d dlmZmZ d dlmZ d dlmZ  e«       Zdedefd	„Z ej6                   ee«      «      Z G d
„ dej<                  «      Z G d„ dej@                  «      Z!d„ Z"	 d8deeef   deeef   dedeeef   fd„Z#dg fdedee   defd„Z$	 d9dede%de%de%fd„Z&deeef   dede%fd„Z'g d¢Z(e(fdee   defd„Z)d ee   de%de%fd!„Z*d"ede j                   fd#„Z+d$edefd%„Z,d&„ Z-d'„ Z.d(d)d*d+d,d-œZ/d.edefd/„Z0d0ee   dee   fd1„Z1de%fd2„Z2d3ed4edefd5„Z3d6ee   fd7„Z4y):é    N©Úwraps)ÚAnyÚDictÚListÚOptionalÚUnion)Ú
exceptionsÚmessages)ÚCONFIG_FIELD_ENVVAR_ALLOWLIST)ÚMessagingOperationsÚnameÚreturnc                 ó\   — | dk(  ry| j                  d«      }d|d<   dj                  |«      S )z1Replace the name of the root logger from __name__Ú ú.Ú	ubuntupror   )ÚsplitÚjoin)r   Únamess     ú//usr/lib/python3/dist-packages/uaclient/util.pyÚreplace_top_level_logger_namer      s0   € àˆr‚zØØ�J‰J�s‹O€EØ€Eˆ!�HØ�8‰8�E‹?Ðó    c                   ó"   ‡ — e Zd ZdZˆ fd„Zˆ xZS )ÚDatetimeAwareJSONEncoderzBA json.JSONEncoder subclass that writes out isoformat'd datetimes.c                 óv   •— t        |t        j                  «      r|j                  «       S t        ‰| �  |«      S ©N)Ú
isinstanceÚdatetimeÚ	isoformatÚsuperÚdefault)ÚselfÚoÚ	__class__s     €r   r"   z DatetimeAwareJSONEncoder.default"   s.   ø€ Ü�aœ×*Ñ*Ô+Ø—;‘;“=Ð Ü‰w‰˜qÓ!Ð!r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r"   Ú__classcell__©r%   s   @r   r   r      s   ø„ ÙL÷"ð "r   r   c                   ó2   ‡ — e Zd ZdZˆ fd„Zed„ «       Zˆ xZS )Ú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                 óf   •— d|v r|j                  d«       t        ‰| �  |d| j                  i|¤Ž y )NÚobject_hook)Úpopr!   Ú__init__r/   )r#   ÚargsÚkwargsr%   s      €r   r1   z!DatetimeAwareJSONDecoder.__init__6   s4   ø€ Ø˜FÑ"Ø�J‰J�}Ô%Ü‰Ñ˜$ÐG¨D×,<Ñ,<ÐGÀÓGr   c                 óœ   — | j                  «       D ]'  \  }}t        |t        «      sŒ	 t        |«      }|| |<   Œ) | S # t        $ r |}Y Œw xY wr   )Úitemsr   ÚstrÚparse_rfc3339_dateÚ
ValueError)r$   ÚkeyÚvalueÚ	new_values       r   r/   z$DatetimeAwareJSONDecoder.object_hook;   s_   € àŸ'™'›)ò 		#‰JˆC�Ü˜%¤Õ%ð&Ü 2Øó!�Ið #��#’ð		#ð ˆøô	 "ò &à %’Ið&ús   ©=½AÁ
A)r&   r'   r(   r)   r1   Ústaticmethodr/   r*   r+   s   @r   r-   r-   (   s"   ø„ ñôHð
 ñó ôr   r-   c                 ó   ‡ ‡— ˆ ˆfd„}|S )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                 ó4   •‡ — t        ‰ «      ˆˆ ˆfd„«       }|S )Nc                  ó   •— ‰j                  «       }	 	  ‰| i |¤ŽS # ‰$ r[}|s|‚t        j                  dt        |«      t	        |«      «       t        j                  |j                  d«      «       Y d }~nd }~ww xY wŒm)Nz%s: Retrying %d more times.r   )ÚcopyÚLOGÚdebugr6   ÚlenÚtimeÚsleepr0   )r2   r3   ÚsleepsÚeÚ	exceptionÚfÚretry_sleepss       €€€r   Ú	decoratorz)retry.<locals>.wrapper.<locals>.decoratorW   sz   ø€ à!×&Ñ&Ó(ˆFØð.Ù˜dÐ- fÑ-Ð-øØ ò .Ù!Ø˜Ü—I‘IØ5´s¸1³v¼sÀ6»{ôô —J‘J˜vŸz™z¨!›}×-Ñ-ûð.úð s   ” œA<¡AA7Á7A<r   )rI   rK   rH   rJ   s   ` €€r   Úwrapperzretry.<locals>.wrapperV   s!   ù€ Ü	ˆq‹õ	.ó 
ð	.ð Ðr   © )rH   rJ   rL   s   `` r   ÚretryrN   J   s   ù€ õð" €Nr   r   Ú	orig_dictÚnew_dictÚpathc                 óˆ  — i }| j                  «       D ]Š  \  }}|j                  |t        «      }|s|n|dz   |z   }t        |t        «      r(||v rt        |||   |¬«      }|sŒP|||<   ŒVt        ||<   Œ`||k7  sŒft        j                  d|t        |«      «       |||<   ŒŒ |j                  «       D ]  \  }}|| vsŒ|||<   Œ |S )z<Return a dictionary of delta between orig_dict and new_dict.r   )rQ   z'Contract value for '%s' changed to '%s')	r5   ÚgetÚDROPPED_KEYr   ÚdictÚget_dict_deltasrA   rB   r6   )	rO   rP   rQ   Údeltasr9   r:   r;   Úkey_pathÚ	sub_deltas	            r   rV   rV   j   sâ   € ð €FØ—o‘oÓ'ò $‰
ˆˆUØ—L‘L ¤kÓ2ˆ	Ù"‘3¨¨s©
°SÑ(8ˆÜ�eœTÔ"Ø�h‰Ü+Ø˜8 C™=¨xô�	ò Ø"+�F˜3’Kä)��s’Ø�iÓÜ�I‰IØ9ØÜ�I“ôð
 $ˆF�3ŠKð%$ð& —n‘nÓ&ò  ‰
ˆˆUØ�iÒØˆF�3ŠKð ð €Mr   ÚmsgÚvalid_choicesc           
      ó>  — ddl m} |j                  «       }d}dj                  |dj	                  |D �cg c]  }|j                  «       ‘Œ c}«      «      }	 |j                  | «       t        d«      j                  «       }||v r	 |S |j                  |«       ŒCc c}w )aG  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.
    r   )Úevent_loggerr   z{} is not one of: {}z, z> )	Úuaclientr]   Úget_event_loggerÚformatr   ÚupperÚinfoÚinputÚlower)rZ   r[   r]   Úeventr:   ÚchoiceÚ	error_msgs          r   Úprompt_choicesrh   ˆ   s”   € õ &à×)Ñ)Ó+€EØ€EØ&×-Ñ-Øˆt�y‰y°}ÖE¨V˜&Ÿ,™,�.ÒEÓFó€Ið Ø�
‰
�3ŒÜ�d“×!Ñ!Ó#ˆØ�MÑ!Øà€Lð 	�
‰
�9Ôð ùò Fs   ´BÚ
assume_yesr"   c                 ó”   — |ry| st         j                  } t        | «      j                  «       j	                  «       }|dk(  r|S |dv ryy)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   )ÚyÚyesF)r   ÚPROMPT_YES_NOrc   rd   Ústrip)rZ   ri   r"   r:   s       r   Úprompt_for_confirmationro   ¢   sM   € ñ ØÙÜ×$Ñ$ˆÜ�#‹J×ÑÓ×$Ñ$Ó&€EØ�‚{ØˆØ�ÑØØr   ÚconfigÚpath_to_valuec                 ó0  — | }i }|j                  d«      }|d   }|D ]-  }||k(  rd}t        |t        «      r|j                  ||«      }Œ- y t	        |«      }|j                  «       dk(  ry|j                  «       dk(  ryt        j                  |d|¬«      ‚)	aJ  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)rq   Úexpected_valuer:   )r   r   rU   rS   r6   rd   r
   ÚInvalidBooleanConfigValue)rp   rq   r:   Údefault_valueÚpathsÚ
leaf_valuer9   Ú	value_strs           r   Úis_config_value_truer|   ¼   s«   € ð €EØ€MØ×Ñ Ó$€EØ�r‘€JØò ˆØ�*ÒØ#ˆMä�eœTÔ"Ø—I‘I˜c =Ó1‰Eáðô �E“
€IØ‡�Ó˜FÒ"ØØ	�‰Ó	˜gÒ	%Øä×2Ñ2Ø'Ø:Øô
ð 	
r   )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]+Úredact_regexsc                 óF   — | }|D ]  }t        j                  |d|«      }Œ |S )z4Redact known sensitive information from log content.z\g<1><REDACTED>)ÚreÚsub)Úlogr~   Úredacted_logÚredact_regexs       r   Úredact_sensitive_logsr…     s3   € ð €LØ%ò NˆÜ—v‘v˜lÐ,>ÀÓM‰ðNàÐr   Úmsg_opsc                 óx   — | sy| D ]2  }t        |t        «      rt        |«       Œ|\  }}||d<    |di |¤ŽrŒ2 y y)ah  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.
    Tri   FrM   )r   r6   Úprint)r†   ri   Úmsg_opÚfunctorr2   s        r   Úhandle_message_operationsr‹     sN   € ñ Øàò ˆÜ�fœcÔ"Ü�&�Mà"‰MˆG�TØ!+ˆD�ÑÙ‘?˜T“?Ùðð r   Údt_strc                 óð   — t        j                  dd| «      }t        j                  dd|«      }|j                  dd«      }t        j                  dd|«      }t        j                  j	                  |d	«      S )
aT  
    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   r7   r7   &  s‚   € ô( !#§¡Ø# X¨vó!Ðô —F‘FØ Ð,Eó€Mð %×,Ñ,¨S°(Ó;Ðô  "Ÿv™vØ!Ð#5Ð7Gó Ðô ×Ñ×%Ñ%Ø Ð"7óð r   Úmessagec                 ó~  — t         j                  j                  �*dt         j                  j                  j                  «       vrx| j	                  dd«      } | j	                  t
        j                  dz   d«      } | j	                  t
        j                  dz   d«      } | j                  dd«      j                  «       } | S )z}
    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Úencodingra   r�   r   ÚOKGREEN_CHECKÚFAIL_XÚencodeÚdecode)r•   s    r   Úhandle_unicode_charactersr¢   ]  s—   € ô 	�
‰
×ÑÐ#Øœ#Ÿ*™*×-Ñ-×3Ñ3Ó5Ñ5ð
 —/‘/ (¨CÓ0ˆð
 —/‘/¤(×"8Ñ"8¸3Ñ">ÀÓCˆØ—/‘/¤(§/¡/°CÑ"7¸Ó<ˆð —.‘. ¨(Ó3×:Ñ:Ó<ˆà€Nr   c                  óÊ   — t         j                  j                  «       D � �ci c]4  \  } }| j                  «       t        v s| j                  d«      s| dk(  r| |“Œ6 c}} S c c}} w )NÚUA_FEATURESÚUA_CONFIG_FILE)ÚosÚenvironr5   rd   r   Ú
startswith)ÚkÚvs     r   Úget_pro_environmentr«   w  s]   € ô —J‘J×$Ñ$Ó&÷áˆAˆqØ�7‰7‹9Ô5Ñ5Ø�<‰<˜Ô&ØÐ Ò ð	 	
ˆ1‰óð ùó s   ¢9Ac                 ón  — d„ }|j                  «       D ]Ÿ  \  }}| j                  |«      }t        |t        «      r t        |t        «      rt	        | |   |«       ŒGt        |t
        «      rDt        |t
        «      r4t        |«      r"t        |d   t        «      r || |   ||¬«       Œ”	 || |<   Œ›|| |<   Œ¡ y)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                 ó  — ddddœ}g }|j                  |«      }|D ]]  }d}t        | «      D ]7  \  }}	|	j                  |«      |j                  |«      k(  sŒ*t        |	|«       d}Œ9 |rŒM|j                  |«       Œ_ | j	                  |«       y )Nr   ÚtypeÚselector)ÚavailableResourcesÚresourceEntitlementsÚ	overridesFT)rS   Ú	enumerateÚdepth_first_merge_overlay_dictÚappendÚextend)
Úbase_valuesÚoverlay_valuesr9   Úmerge_id_key_mapÚvalues_to_appendÚid_keyÚoverlay_valueÚwas_replacedÚbase_value_idxÚ
base_values
             r   Úupdate_dict_listz8depth_first_merge_overlay_dict.<locals>.update_dict_list‘  s§   € à"(Ø$*Ø#ñ
Ðð
 ÐØ!×%Ñ% cÓ*ˆØ+ò 	7ˆMØ ˆLÜ.7¸Ó.Dò (Ñ*� 
Ø—>‘> &Ó)¨]×->Ñ->¸vÓ-FÓFÜ2°:¸}ÔMØ#'‘Lð(ò
  Ø ×'Ñ'¨Õ6ð	7ð 	×ÑÐ+Õ,r   r   )r9   N)r5   rS   r   rU   r´   ÚlistrC   )Ú	base_dictÚoverlay_dictrÀ   r9   r:   r¿   s         r   r´   r´   �  s¥   € ò -ð( #×(Ñ(Ó*ò #‰
ˆˆUØ—]‘] 3Ó'ˆ
Ü�j¤$Ô'¬J°u¼dÔ,CÜ*¨9°S©>¸5ÕAÜ˜
¤DÔ)¬j¸ÄÔ.EÜ�:Œ¤:¨j¸©m¼TÔ#BÙ  ¨3¡°¸CÖ@ðEð "'�	˜#’à"ˆI�cŠNñ#r   Úamd64Úi386Úppc64elÚarm64Úarmhf)Úx86_64Úi686Úppc64leÚaarch64Úarmv7lÚarchc                 óN   — | j                  «       }t        j                  ||«      S r   )rd   ÚARCH_ALIASESrS   )rÎ   Ú
arch_lowers     r   Ústandardize_arch_namerÒ   ¾  s    € Ø—‘“€JÜ×Ñ˜J¨
Ó3Ð3r   Úarchesc                 ó€   — t        «       }| D ]  }|j                  t        |«      «       Œ t        t	        |«      «      S r   )ÚsetÚaddrÒ   ÚsortedrÁ   )rÓ   Údeduplicated_archesrÎ   s      r   Údeduplicate_archesrÙ   Ã  s>   € Ü›%ÐØò =ˆØ×ÑÔ 5°dÓ ;Õ<ð=ä”$Ð*Ó+Ó,Ð,r   c                  ó0   — t        j                  «       dk(  S )Nr   )r¦   ÚgetuidrM   r   r   Úwe_are_currently_rootrÜ   Ê  s   € Ü�9‰9‹;˜!ÑÐr   ÚfilenameÚnew_extensionc                 óV   — t         j                  j                  | «      \  }}|dz   |z   S )Nr   )r¦   rQ   Úsplitext)rÝ   rÞ   r   Ú
_extensions       r   Úset_filename_extensionrâ   Î  s*   € Ü—w‘w×'Ñ'¨Ó1Ñ€Dˆ*Ø�#‰:˜Ñ%Ð%r   Úpackage_listc           
      óz   — dj                  t        j                  dj                  | «      ddddd¬«      «      dz   S )Nú
r˜   éP   Fz  )ÚwidthÚbreak_long_wordsÚbreak_on_hyphensÚinitial_indentÚsubsequent_indent)r   ÚtextwrapÚwrap)rã   s    r   Úcreate_package_list_strrî   Ó  sF   € ð 	�	‰	Ü�M‰MØ—‘˜Ó&ØØ!&Ø!&Ø#Ø"&ôó		
ð ñ
	ðr   )r   )r   FF)5r   ÚjsonÚloggingr¦   r€   r›   rì   rD   Ú	functoolsr   Útypingr   r   r   r   r	   r^   r
   r   Úuaclient.defaultsr   Úuaclient.typesr   ÚobjectrT   r6   r   Ú	getLoggerr&   rA   ÚJSONEncoderr   ÚJSONDecoderr-   rN   rV   rh   Úboolro   r|   ÚREDACT_SENSITIVE_LOGSr…   r‹   r7   r¢   r«   r´   rÐ   rÒ   rÙ   rÜ   râ   rî   rM   r   r   ú<module>rû      sD  ðÛ Û Û Û 	Û 	Û 
Û Û Ý ß 3Õ 3ç )Ý ;Ý .á‹h€ð¨ð °ó ð €g×ÑÑ5°hÓ?Ó@€ô"˜t×/Ñ/ô "ô˜t×/Ñ/ô òDðB FHñØ�C˜�H‰~ðØ)-¨c°3¨h©ðØ?Bðà	ˆ#ˆsˆ(�^óð< !¸Rñ ˜ð °°c±ð ÀCó ð6 >CñØ	ðØ#ðØ6:ðà	óð4$
  c¨3 h¡ð $
Àð $
Èó $
òNÐ ð@ %:ñØ˜S™	ðàóðØÐ)Ñ*ðØ8<ðà	óð44˜sð 4 x×'8Ñ'8ó 4ðn sð ¨só ò4ò1#ðj ØØØØñ€ð4 ð 4¨ó 4ð
-˜t C™yð -¨T°#©Yó -ð˜tó ð& Sð &¸ð &Àó &ð
Ø�s‘)ôr   