o
    K&b3                  	   @   s$  d dl Z d dlZd dl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 d dlmZmZ d dlmZ d dlmZ ddgZd	Zd
ZdddZdZe
 Z	ddedeee  ddfddZ 			d dee dee deee  ddfddZ!dedee fddZ"G dd deZ#dd Z$dS )!    N)AnyDictListOptionalTuple)aptevent_logger
exceptionsmessagessnapstatusutil)IncompatibleServiceUAEntitlement)ApplicationStatus)StaticAffordanceg      ?g      ?z
http-proxyzhttps-proxyz)Invalid Auth-Token provided to livepatch.z2Your running kernel is not supported by Livepatch.)zUnknown Auth-Tokenzunsupported kernelz/snap/bin/canonical-livepatchprotocol_typeretry_sleepsreturnc                 C   s,   t tsdS t jtdd| g|d dS )a  
    Unset livepatch configuration settings for http and https proxies.

    :param protocol_type: String either http or https
    :param retry_sleeps: Optional 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.
    Nconfigz	{}-proxy=r   )r   whichLIVEPATCH_CMDsubpformat)r   r    r   A/usr/lib/python3/dist-packages/uaclient/entitlements/livepatch.pyunconfigure_livepatch_proxy    s   

r   
http_proxyhttps_proxyc                 C   sb   | s|rt tjjtjd | rtjt	dd| g|d |r/tjt	dd|g|d dS dS )a  
    Configure livepatch to use http and https proxies.

    :param http_proxy: http proxy to be used by livepatch. If None, it will
                       not be configured
    :param https_proxy: https proxy to be used by livepatch. If None, it will
                        not be configured
    :@param retry_sleeps: Optional list of sleep lengths to apply between
                               snap calls
    )servicer   zhttp-proxy={}r   zhttps-proxy={}N)
eventinfor
   ZSETTING_SERVICE_PROXYr   LivepatchEntitlementtitler   r   r   r   r   r   r   r   r   configure_livepatch_proxy4   s"   
r&   keyc                 C   s\   t tdg\}}td| |tj}|r|dnd}|r&tdd|}|r,|	 S dS )z
    Gets the config value from livepatch.
    :param protocol: can be any valid livepatch config option
    :return: the value of the livepatch config option, or None if not set
    r   z
^{}: (.*)$   Nz\"(.*)\"z\g<1>)
r   r   r   researchr   	MULTILINEgroupsubstrip)r'   out_matchvaluer   r   r   get_config_option_valueW   s   r3   c                	       s   e Zd ZdZdZdZdZedee	df fddZ
edeedf fd	d
ZddedefddZ	ddededefddZdddZdeeeej f fddZ	ddeeef deeef dedef fddZ  ZS )r#   z%https://ubuntu.com/security/livepatchZ	livepatchZ	LivepatchzCanonical Livepatch servicer   .c                 C   s   ddl m} t|tjfS )Nr   FIPSEntitlement)uaclient.entitlements.fipsr5   r   r
   ZLIVEPATCH_INVALIDATES_FIPS)selfr5   r   r   r   incompatible_servicesm   s
   z*LivepatchEntitlement.incompatible_servicesc                    sP   ddl m} || j}t| d tjk tjdd dftj	 fdddffS )Nr   r4   c                   S   s   t  S N)r   Zis_containerr   r   r   r   <lambda>   s    z9LivepatchEntitlement.static_affordances.<locals>.<lambda>Fc                      s    S r9   r   r   Zis_fips_enabledr   r   r:      s    )
r6   r5   cfgboolapplication_statusr   ENABLEDr
   Z$LIVEPATCH_ERROR_INSTALL_ON_CONTAINERZ!LIVEPATCH_ERROR_WHEN_FIPS_ENABLED)r7   r5   Zfips_entr   r;   r   static_affordancesw   s   

z'LivepatchEntitlement.static_affordancesFsilentc              
   C   s  t tjs?td ttj zt	  W n t
jy2 } ztdt| W Y d}~nd}~ww t jg ddtjd ndt vrNt
jtj| jdzt jtjd	d
dgdd W n% t
jy } ztdt| rvttj n W Y d}~nd}~ww t d| jjt j}t d| jjt j}tj ||tj!d t t"std zt jtjddgdtj!d W n t
jy } zt
j#t|dd}~ww t$|| | j%dddS )zYEnable specific entitlement.

        @return: True on success, False otherwise.
        zInstalling snapdz<Trying to install snapd. Ignoring apt-get update failure: %sN)zapt-getinstallz--assume-yessnapdT)capturer   rC   )Zsnap_cmdr    waitsystemzseed.loadedrD   zunknown command .*waitZhttpZhttpsr%   z#Installing canonical-livepatch snaprB   zcanonical-livepatch)Z	error_msgprocess_directivesprocess_token)&r   r   r   ZSNAP_CMDr!   r"   r
   ZAPT_UPDATING_LISTSr   Zrun_apt_update_commandr	   ZUserFacingErrorloggingdebugstrr   ZAPT_RETRIESZget_installed_packagesZSnapdNotProperlyInstalledErrorr$   ProcessExecutionErrorr)   r*   lowerZwarningZSNAPD_DOES_NOT_HAVE_WAIT_CMDZvalidate_proxyr<   r   ZPROXY_VALIDATION_SNAP_HTTP_URLr   ZPROXY_VALIDATION_SNAP_HTTPS_URLZconfigure_snap_proxyZSNAP_INSTALL_RETRIESr   ZErrorInstallingLivepatchr&   setup_livepatch_config)r7   rA   er   r   r   r   r   _perform_enable   sv   






z$LivepatchEntitlement._perform_enableTrI   rJ   c              
   C   s  | j j| j}|r5zt| W n$ tjy4 } zdt| }t	| t
| W Y d}~dS d}~ww |r|d}|sKt
d| j | j jd }|  \}}|tjjkrt
	d| j z	ttdg W n tjy } zt
t| W Y d}~dS d}~ww ztjtd	|gd
d W n: tjy } z-d}t D ]\}	}
|	t|v r||
7 } nq|dkr|t|7 }t	| W Y d}~dS d}~ww t	d d
S )a  Processs configuration setup for livepatch directives.

        :param process_directives: Boolean set True when directives should be
            processsed.
        :param process_token: Boolean set True when token should be
            processsed.
        zUnable to configure Livepatch: NFresourceTokenzHNo specific resourceToken present. Using machine token as %s credentialsZmachineTokenz.Disabling %s prior to re-attach with new tokendisableenableTrG   zUnable to enable Livepatch: zCanonical livepatch enabled.)r<   Zentitlementsgetnameprocess_config_directivesr	   rN   rM   r!   r"   rK   errorrL   r$   Zmachine_tokenr>   r   r   DISABLEDr   r   r   ERROR_MSG_MAPitems)r7   rI   rJ   Zentitlement_cfgrQ   msgZlivepatch_tokenr>   Z_detailsZerror_messageZprint_messager   r   r   rP      sf   








z+LivepatchEntitlement.setup_livepatch_configc                 C   s$   t tsdS t jtdgdd dS )zYDisable specific entitlement

        @return: True on success, False otherwise.
        TrT   rG   )r   r   r   r   )r7   rA   r   r   r   _perform_disable  s   
z%LivepatchEntitlement._perform_disablec              
   C   s   t jd f}ttst jtjfS ztjtdgt	d W |S  t
jyC } ztdt| t jtjdt|dfW  Y d }~S d }~ww )Nr   r   zLivepatch not enabled. %s )rW   r]   )r   r?   r   r   r   rZ   r
   ZLIVEPATCH_NOT_ENABLEDr   LIVEPATCH_RETRIESr	   rN   rK   rL   rM   NamedMessage)r7   r   rQ   r   r   r   r>     s   


z'LivepatchEntitlement.application_statusorig_accessdeltasallow_enablec                    s   t  |||r
dS |di }|di dd}|r$|  \}}|S |  \}}|tjjkr2dS |di }	tddg}
t	|

|	}t	|d	d}t||gratd
| j | j||dS dS )a1  Process any contract access deltas for this entitlement.

        :param orig_access: Dictionary containing the original
            resourceEntitlement access details.
        :param deltas: Dictionary which contains only the changed access keys
        and values.
        :param allow_enable: Boolean set True if allowed to perform the enable
            operation. When False, a message will be logged to inform the user
            about the recommended enabled service.

        :return: True when delta operations are processed; False when noop.
        TentitlementZobligationsZenabledByDefaultF
directivescaCertsremoteServerrS   z$Updating '%s' on changed directives.rH   )superprocess_contract_deltasrV   rU   r>   r   r   rZ   setr=   intersectionanyrK   r"   rW   rP   )r7   rb   rc   rd   Zdelta_entitlementZprocess_enable_defaultZenable_successr0   r>   Zdelta_directivesZsupported_deltasrI   rJ   	__class__r   r   rj   '  s2   z,LivepatchEntitlement.process_contract_deltas)F)TT)__name__
__module____qualname__Zhelp_doc_urlrW   r$   descriptionpropertyr   r   r8   r   r@   r=   rR   rP   r^   r   r   r
   ra   r>   r   rM   r   rj   __classcell__r   r   rn   r   r#   f   s@    	B

8



r#   c                 C   s   | sdS |  di  di }| d}|r"tjtdd|gdd | d	d
}|dr3|dd }|rDtjtdd|gdd dS dS )a  Process livepatch configuration directives.

    We process caCerts before remoteServer because changing remote-server
    in the canonical-livepatch CLI performs a PUT against the new server name.
    If new caCerts were required for the new remoteServer, this
    canonical-livepatch client PUT could fail on unmatched old caCerts.

    @raises: ProcessExecutionError if unable to configure livepatch.
    Nre   rf   rg   r   zca-certs={}TrG   rh   r_   /zremote-server={})rV   r   r   r   r   endswith)r<   rf   Zca_certsZremote_serverr   r   r   rX   W  s*   



rX   r9   )NNN)%rK   r)   typingr   r   r   r   r   Zuaclientr   r   r	   r
   r   r   r   Zuaclient.entitlements.baser   r   Zuaclient.statusr   Zuaclient.typesr   r`   ZHTTP_PROXY_OPTIONZHTTPS_PROXY_OPTIONr[   r   Zget_event_loggerr!   rM   floatr   r&   r3   r#   rX   r   r   r   r   <module>   sN    $	



# r