o
    ÙKÕi¡K  ã                   @   s  d dl Z d dlZd dlZd dlmZmZ d dlmZmZm	Z	 d dl
mZmZmZmZmZmZmZmZ d dlmZmZmZmZmZmZmZmZmZ d dlmZmZ d dl m!Z! e "e #e$¡¡Z%dd	d
œZ&dZ'dZ(dZ)e *¡ Z+G dd„ dƒZ,de-fdd„Z.ddd„Z/de-fdd„Z0dS )é    N)Ú	lru_cacheÚwraps)ÚAnyÚDictÚOptional)ÚaptÚevent_loggerÚ
exceptionsÚhttpÚmessagesÚsnapÚsystemÚutil)	ÚAPT_NEWS_URLÚBASE_CONTRACT_URLÚBASE_LIVEPATCH_URLÚBASE_SECURITY_URLÚBASE_VULNERABILITY_DATA_URLÚCONFIG_DEFAULTSÚCONFIG_FIELD_ENVVAR_ALLOWLISTÚDEFAULT_CONFIG_FILEÚDEFAULT_DATA_DIR)Ústate_filesÚuser_config_file)Ú	safe_loadÚnameÚtype)ÚavailableResourcesÚresourceEntitlementsÚ_unset)Ú
http_proxyÚhttps_proxyÚapt_http_proxyÚapt_https_proxyÚua_apt_http_proxyÚua_apt_https_proxyÚglobal_apt_http_proxyÚglobal_apt_https_proxyÚupdate_messaging_timerÚmetering_timerÚapt_newsÚapt_news_urlÚvulnerability_data_url_prefixÚlxd_guest_attach)
Úcontract_urlÚdata_dirÚfeaturesÚlog_fileÚ	log_levelÚsecurity_urlr,   Úsettings_overridesÚ	ua_configÚlivepatch_urlc                	   @   s  e Zd ZdZdZdZ			dIdeeee	f  dee
j dee ddfd	d
„Zedefdd„ƒZedefdd„ƒZedefdd„ƒZedee fdd„ƒZejdefdd„ƒZedee fdd„ƒZejdefdd„ƒZedee fdd„ƒZejdefdd„ƒZedee fdd„ƒZejdefdd„ƒZedefdd„ƒZejdefd d„ƒZeedd!�dee fd"d#„ƒƒZejdefd$d#„ƒZeedd!�dee fd%d&„ƒƒZejdefd'd&„ƒZedefd(d)„ƒZejdefd*d)„ƒZedefd+d,„ƒZejdefd-d,„ƒZedefd.d/„ƒZejdefd0d/„ƒZedefd1d2„ƒZejdefd3d2„ƒZedefd4d5„ƒZ e jdefd6d5„ƒZ edefd7d8„ƒZ!e!jdefd9d8„ƒZ!ede
j"fd:d;„ƒZ#e#jde
j"fd<d;„ƒZ#ed=d>„ ƒZ$ed?d@„ ƒZ%edefdAdB„ƒZ&edCdD„ ƒZ'dEdF„ Z(dGdH„ Z)dS )JÚUAConfig)r$   r%   )r&   r'   )r"   r#   NÚcfgÚuser_configÚseriesÚreturnc              
   C   sÐ   |rd| _ || _d| _ntƒ | _ t| j ƒ\| _| _|r|| _n,ztj ¡ | _W n# tyJ } zt	j
d|d� t	 
d¡ t ¡ | _W Y d}~nd}~ww d| jv rctjji | j ¡ ¥| jd ¥dd�| _|| _dS )Ú NzError loading user config)Úexc_infozUsing default config valuesr5   T)Ú optional_type_errors_become_null)Úcfg_pathr8   Úinvalid_keysÚget_config_pathÚparse_configr9   r   ÚreadÚ	ExceptionÚLOGÚwarningÚUserConfigDataÚ	from_dictÚto_dictr:   )Úselfr8   r9   r:   Úe© rL   ú1/usr/lib/python3/dist-packages/uaclient/config.pyÚ__init__V   s,   
€ý
þ
zUAConfig.__init__c                 C   ó   | j  dt¡S )Nr.   )r8   Úgetr   ©rJ   rL   rL   rM   r.   y   ó   zUAConfig.contract_urlc                 C   rO   )Nr3   )r8   rP   r   rQ   rL   rL   rM   r3   }   rR   zUAConfig.security_urlc                 C   rO   )Nr6   )r8   rP   r   rQ   rL   rL   rM   r6   �   rR   zUAConfig.livepatch_urlc                 C   ó   | j jS ©N)r9   r    rQ   rL   rL   rM   r    …   ó   zUAConfig.http_proxyÚvaluec                 C   ó   || j _tj  | j ¡ d S rT   )r9   r    r   Úwrite©rJ   rV   rL   rL   rM   r    ‰   ó   c                 C   rS   rT   )r9   r!   rQ   rL   rL   rM   r!   Ž   rU   zUAConfig.https_proxyc                 C   rW   rT   )r9   r!   r   rX   rY   rL   rL   rM   r!   ’   rZ   c                 C   rS   rT   )r9   r%   rQ   rL   rL   rM   r%   —   rU   zUAConfig.ua_apt_https_proxyc                 C   rW   rT   )r9   r%   r   rX   rY   rL   rL   rM   r%   ›   rZ   c                 C   rS   rT   )r9   r$   rQ   rL   rL   rM   r$       rU   zUAConfig.ua_apt_http_proxyc                 C   rW   rT   )r9   r$   r   rX   rY   rL   rL   rM   r$   ¤   rZ   c                 C   ó   | j j}|d u r
tS |S rT   )r9   r,   r   ©rJ   ÚvalrL   rL   rM   r,   ©   ó   z&UAConfig.vulnerability_data_url_prefixc                 C   rW   rT   )r9   r,   r   rX   rY   rL   rL   rM   r,   °   rZ   )Úmaxsizec                 C   ó:   | j j}|r|S | j j}|rt tjjddd�¡ |S d S )Nr"   r&   ©ÚoldÚnew)r9   r&   r"   ÚeventÚinfor   ÚWARNING_DEPRECATED_FIELDÚformat©rJ   Ú
global_valÚold_apt_valrL   rL   rM   r&   µ   ó   ÿÿzUAConfig.global_apt_http_proxyc                 C   ó.   || j _d | j _tjj ¡  tj  | j ¡ d S rT   )r9   r&   r"   r7   ÚfgetÚcache_clearr   rX   rY   rL   rL   rM   r&   Æ   ó   c                 C   r`   )Nr#   r'   ra   )r9   r'   r#   rd   re   r   rf   rg   rh   rL   rL   rM   r'   Í   rk   zUAConfig.global_apt_https_proxyc                 C   rl   rT   )r9   r'   r#   r7   rm   rn   r   rX   rY   rL   rL   rM   r'   Þ   ro   c                 C   ó   | j j}|d u r
dS |S )Ni`T  )r9   r(   r\   rL   rL   rM   r(   å   r^   zUAConfig.update_messaging_timerc                 C   rW   rT   )r9   r(   r   rX   rY   rL   rL   rM   r(   ì   rZ   c                 C   rp   )Ni@8  )r9   r)   r\   rL   rL   rM   r)   ñ   r^   zUAConfig.metering_timerc                 C   rW   rT   )r9   r)   r   rX   rY   rL   rL   rM   r)   ø   rZ   c                 C   rp   )NF)r9   Úpoll_for_pro_licenser\   rL   rL   rM   rq   ý   s   zUAConfig.poll_for_pro_licensec                 C   rW   rT   )r9   rq   r   rX   rY   rL   rL   rM   rq     rZ   c                 C   rp   )NiX  )r9   Úpolling_error_retry_delayr\   rL   rL   rM   rr     s   z"UAConfig.polling_error_retry_delayc                 C   rW   rT   )r9   rr   r   rX   rY   rL   rL   rM   rr     rZ   c                 C   rp   )NT)r9   r*   r\   rL   rL   rM   r*     r^   zUAConfig.apt_newsc                 C   rW   rT   )r9   r*   r   rX   rY   rL   rL   rM   r*   !  rZ   c                 C   r[   rT   )r9   r+   r   r\   rL   rL   rM   r+   &  r^   zUAConfig.apt_news_urlc                 C   rW   rT   )r9   r+   r   rX   rY   rL   rL   rM   r+   -  rZ   c                 C   s   | j j}|d u rtjjS |S rT   )r9   r-   r   ÚLXDGuestAttachEnumÚOFFr\   rL   rL   rM   r-   2  s   zUAConfig.lxd_guest_attachc                 C   s*   |d u rt jj}|| j_t j | j¡ d S rT   )r   rs   rt   r9   r-   rX   rY   rL   rL   rM   r-   9  s   c                 C   rO   )Nr/   )r8   rP   r   rQ   rL   rL   rM   r/   @  rR   zUAConfig.data_dirc                 C   s8   | j  dd¡}ztt| ¡ ƒW S  ty   tj Y S w )Nr2   ÚDEBUG)r8   rP   ÚgetattrÚloggingÚupperÚAttributeErrorru   )rJ   r2   rL   rL   rM   r2   D  s   
ÿzUAConfig.log_levelc                 C   s   | j  dtd ¡S )Nr1   )r8   rP   r   rQ   rL   rL   rM   r1   L  s   zUAConfig.log_filec                 C   s.   | j  d¡}|rt|tƒr|S t d|¡ i S )z>Return a dictionary of any features provided in uaclient.conf.r0   zDUnexpected uaclient.conf features value. Expected dict, but found %s)r8   rP   Ú
isinstanceÚdictrE   rF   )rJ   r0   rL   rL   rM   r0   P  s   
ýzUAConfig.featuresc           
      C   sV  dD ]"}t | |ƒ}|d u rt d|¡ qt|tƒr|dk r$tj||d�‚q| js+| jr5| j	s1| j
r5t ¡ ‚t d| jtj¡ t d| jtj¡ t d| j	tj¡ t d| j
tj¡ t d| jtj¡ t d| jtj¡ | jsq| jr}t | j| jtjj¡ n| j	sƒ| j
rŽt | j	| j
tjj¡ g }t ¡ r³t | j| j¡ | js¥t tj¡s®| js³t tj¡r³| d¡ ddl m!} dd	l"m#} || ƒj$}t%d
d„ |D ƒƒ}|rî| &| j| j¡ | jsà| |j¡sé| jsî| |j¡rî| d¡ t'|ƒdk�rd (|¡}t)t*j+j,|d�ƒ ddl-m.}	 | j/t0j1j2k�r|	| ƒj3�st)t*j4ƒ d S t5j6 7t5j8| j/d�¡ d S )N)r(   r)   z1No config set for %s, default value will be used.r   ©ÚkeyrV   r
   Úhttpsr   )Ú	livepatch)Ú_enabled_servicesc                 s   s   � | ]
}|j d kr|V  qdS )r   N)r   )Ú.0ÚentrL   rL   rM   Ú	<genexpr>¬  s   € ÿz*UAConfig.process_config.<locals>.<genexpr>r   z, )Úservices)Ú_is_attached)Úguest_attach)9rv   rE   Údebugrz   Úintr	   ÚInvalidPosIntConfigValuer&   r'   r$   r%   ÚInvalidProxyCombinationConfigr
   Úvalidate_proxyÚPROXY_VALIDATION_APT_HTTP_URLÚPROXY_VALIDATION_APT_HTTPS_URLr    ÚPROXY_VALIDATION_SNAP_HTTP_URLr!   ÚPROXY_VALIDATION_SNAP_HTTPS_URLr   Úsetup_apt_proxyÚAptProxyScopeÚGLOBALÚUACLIENTr   Úis_snapd_installedÚconfigure_snap_proxyÚget_config_option_valueÚHTTP_PROXY_OPTIONÚHTTPS_PROXY_OPTIONÚappendÚuaclientr   Ú-uaclient.api.u.pro.status.enabled_services.v1r€   Úenabled_servicesÚanyÚconfigure_livepatch_proxyÚlenÚjoinÚprintr   Ú!PROXY_DETECTED_BUT_NOT_CONFIGUREDrg   Ú(uaclient.api.u.pro.status.is_attached.v1r…   r-   r   rs   rt   Úis_attachedÚ-WARNING_LXD_GUEST_ATTACH_SET_BUT_NOT_ATTACHEDr   Úlxd_pro_config_filerX   ÚLXDProConfig)
rJ   ÚproprV   Úservices_with_proxiesr   r€   rœ   Úlivepatch_enabledr„   r…   rL   rL   rM   Úprocess_config_  sÎ   
ÿÿÿÿÿýý
ÿý
ÿ
ÿýýÿ
þü
û

ÿÿÿÿþúÿù

ÿÿÿÿzUAConfig.process_configc                 C   s`   | j d urt| j ƒD ]}t d|¡ q
d| jv r.t d¡ t d¡ t d¡ t d¡ d S d S )Nz&Ignoring invalid uaclient.conf key: %sr5   z)legacy "ua_config" found in uaclient.confzPlease do the following:z…  1. run `sudo pro config set field=value` for each field/value pair present under "ua_config" in /etc/ubuntu-advantage/uaclient.confzQ  2. Delete "ua_config" and all sub-fields in /etc/ubuntu-advantage/uaclient.conf)r@   ÚsortedrE   rF   r8   )rJ   Úinvalid_keyrL   rL   rM   Úwarn_about_invalid_keysÕ  s   
ÿ


ÿÿöz UAConfig.warn_about_invalid_keys)NNN)*Ú__name__Ú
__module__Ú__qualname__Úua_scoped_proxy_optionsÚglobal_scoped_proxy_optionsÚ&deprecated_global_scoped_proxy_optionsr   r   Ústrr   r   rG   rN   Úpropertyr.   r3   r6   r    Úsetterr!   r%   r$   r,   r   r&   r'   rˆ   r(   r)   Úboolrq   rr   r*   r+   rs   r-   r/   r2   r1   r0   r«   r®   rL   rL   rL   rM   r7   K   s´    üþýü
û#	


vr7   r;   c                  C   s   t j d¡} | r
| S tS )z4Get config path to be used when loading config dict.ÚUA_CONFIG_FILE)ÚosÚenvironrP   r   )Úconfig_filerL   rL   rM   rA   ë  s   rA   c           	      C   sp  t   t¡}| s
tƒ } t d| ¡ tj | ¡r | t	t
 | ¡ƒ¡ i }tj ¡ D ]Q\}}| ¡ }| d¡rx|dd… }| d¡rp|dd… }| d¡r^tj |¡rXt	t
 |¡ƒ}ntj|d�‚d	|vri||i|d	< q'||d	 |< q'|tv rx|||< q'| |¡ d
|v rŒtj |d
 ¡|d
< dD ]}t || ¡s tj||| d�‚qŽt| ¡ ƒ t¡}|D ]}| |¡ q¬||fS )aŽ  Parse known Pro config file

    Attempt to find configuration in cwd and fallback to DEFAULT_CONFIG_FILE.
    Any missing configuration keys will be set to CONFIG_DEFAULTS.

    Values are overridden by any environment variable with prefix 'UA_'.

    @param config_path: Fullpath to pro configfile. If unspecified, use
        DEFAULT_CONFIG_FILE.

    @return: Dict of configuration values.
    z%Using client configuration file at %sÚua_é   NÚ	features_é	   Úyaml)Úfilepathr0   r/   )r.   r3   r|   )Úcopyr   rA   rE   r‡   rº   ÚpathÚexistsÚupdater   r   Ú	load_filer»   ÚitemsÚlowerÚ
startswithÚendswithr	   ÚInvalidFeatureYamlConfigValuer   Ú
expanduserr
   Úis_service_urlÚInvalidURLConfigValueÚsetÚkeysÚ
differenceÚVALID_UA_CONFIG_KEYSÚpop)	Úconfig_pathr8   Úenv_keysr}   rV   Ú
field_nameÚfeature_field_namer@   r­   rL   rL   rM   rB   ô  sH   



ÿ€
ÿrB   Úoverride_keyc                    s   ‡ fdd„}|S )aì  Decorator used to override function return by config settings.

    To identify if we should override the function return, we check
    if the config object has the expected override key, we use it
    has, we will use the key value as the function return. Otherwise
    we will call the function normally.

    @param override_key: key to be looked for in the settings_override
     entry in the config dict. If that key is present, we will return
     its value as the function return.
    c                    s   t ˆ ƒ‡ ‡fdd„ƒ}|S )Nc                     s@   t ƒ \} }|  di ¡ ˆt¡}|tkrˆdkr|d fS |S ˆ ƒ S )Nr4   Ú
cloud_type)rB   rP   ÚUNSET_SETTINGS_OVERRIDE_KEY)r8   Ú_Úvalue_override)ÚfrÙ   rL   rM   Únew_fA  s   
ÿz>apply_config_settings_override.<locals>.wrapper.<locals>.new_f)r   )rÞ   rß   ©rÙ   )rÞ   rM   Úwrapper@  s   z/apply_config_settings_override.<locals>.wrapperrL   )rÙ   rá   rL   rà   rM   Úapply_config_settings_override3  s   râ   rT   )1rÃ   rw   rº   Ú	functoolsr   r   Útypingr   r   r   rš   r   r   r	   r
   r   r   r   r   Úuaclient.defaultsr   r   r   r   r   r   r   r   r   Úuaclient.filesr   r   Úuaclient.yamlr   Ú	getLoggerÚreplace_top_level_logger_namer¯   rE   ÚMERGE_ID_KEY_MAPrÛ   ÚUA_CONFIGURABLE_KEYSrÓ   Úget_event_loggerrd   r7   rµ   rA   rB   râ   rL   rL   rL   rM   Ú<module>   s0    (,
þ   #
	?