U
    lHJe2                     @   s   d dl Z d dl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 d dlmZmZ d dlmZ d dlmZ ddgZd	d
dZe Ze eeZG dd deZdd ZdS )    N)AnyDictOptionalTuple)event_logger
exceptionshttp	livepatchmessagessnapsystemutil)IncompatibleServiceUAEntitlement)ApplicationStatus)StaticAffordanceg      ?g      ?z)Invalid Auth-Token provided to livepatch.z2Your running kernel is not supported by Livepatch.)zUnknown Auth-Tokenzunsupported kernelc                       s  e Zd ZejjZdZejZ	ej
ZejZdZdZdZdZeeedf dddZeeedf ddd	Zdeed
ddZdeeedddZdddZeeeej f dddZeeeej f dddZ dd Z!de"e#e$f e"e#e$f eed fddZ%  Z&S )LivepatchEntitlementr	   FT.)returnc                 C   s0   ddl m} ddlm} t|tjt|tjfS )Nr   FIPSEntitlement)RealtimeKernelEntitlement)uaclient.entitlements.fipsr   Zuaclient.entitlements.realtimer   r   r
   ZLIVEPATCH_INVALIDATES_FIPSZREALTIME_LIVEPATCH_INCOMPATIBLE)selfr   r    r   A/usr/lib/python3/dist-packages/uaclient/entitlements/livepatch.pyincompatible_services+   s     z*LivepatchEntitlement.incompatible_servicesc                    sZ   ddl m} || j}t| d tjk tjj	| j
ddd dftj fdddffS )Nr   r   titlec                   S   s   t  S N)r   is_containerr   r   r   r   <lambda>J       z9LivepatchEntitlement.static_affordances.<locals>.<lambda>Fc                      s    S r   r   r   Zis_fips_enabledr   r   r    O   r!   )r   r   cfgboolapplication_statusr   ENABLEDr
   Z"SERVICE_ERROR_INSTALL_ON_CONTAINERformatr   Z!LIVEPATCH_ERROR_WHEN_FIPS_ENABLED)r   r   Zfips_entr   r"   r   static_affordances:   s     

z'LivepatchEntitlement.static_affordances)silentr   c              
   C   sV  t  s$ttjjdd t   t  sttjjdd zt 	d W nF t
jk
r } z&tjd|d ttjjdd W 5 d}~X Y nX t   td	| jjtj}td
| jjtj}t j||t jd t s<ttjjdd zt 	d W n6 t
jk
r: } zt
jt|dW 5 d}~X Y nX t|| | jdddS )zYEnable specific entitlement.

        @return: True on success, False otherwise.
        Zsnapd)Zpackagesz
snapd snapz!Failed to install snapd as a snapexc_infozsnap install snapd)ZcommandNr   Zhttps)
http_proxyhttps_proxyZretry_sleepszcanonical-livepatch snapzcanonical-livepatchZ	error_msgTprocess_directivesprocess_token)r   Zis_snapd_installedeventinfor
   ZINSTALLING_PACKAGESr'   Zinstall_snapdZis_snapd_installed_as_a_snapZinstall_snapr   ProcessExecutionErrorLOGZwarningZEXECUTING_COMMAND_FAILEDZrun_snapd_wait_cmdr   Zvalidate_proxyr#   r,   ZPROXY_VALIDATION_SNAP_HTTP_URLr-   ZPROXY_VALIDATION_SNAP_HTTPS_URLZconfigure_snap_proxyZSNAP_INSTALL_RETRIESr	   is_livepatch_installedZErrorInstallingLivepatchstrZconfigure_livepatch_proxysetup_livepatch_config)r   r)   er,   r-   r   r   r   _perform_enableT   s^        
" z$LivepatchEntitlement._perform_enable)r0   r1   r   c              
   C   s  | j jj| j}|rxzt| W nT tjk
rv } z4tj	t
||d ttjjt
|d W Y dS d}~X Y nX |r|d}|std| j | j jd }|  \}}|tjkr(td ttj zttjd	g W n> tjk
r& } ztj	t
||d W Y dS d}~X Y nX ztjtjd
|gdd W n tjk
r } zbtj}t D ]&\}	}
|	t
|krf||
7 } qqf|tjkr|t
|7 }t| W Y dS d}~X Y nX ttjjd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.
        r*   r.   FNresourceTokenzHNo specific resourceToken present. Using machine token as %s credentialsZmachineTokenz&Disabling livepatch before re-enablingdisableenableTZcapturezCanonical Livepatchr   )r#   Zmachine_token_fileZentitlementsgetnameprocess_config_directivesr   r4   r5   errorr7   r2   r3   r
   ZLIVEPATCH_UNABLE_TO_CONFIGUREr'   debugr   Zmachine_tokenr%   r   DISABLEDZLIVEPATCH_DISABLE_REATTACHr   subpr	   LIVEPATCH_CMDZLIVEPATCH_UNABLE_TO_ENABLEERROR_MSG_MAPitemsZENABLED_TMPL)r   r0   r1   Zentitlement_cfgr9   Zlivepatch_tokenr%   Z_detailsmsgZerror_messageZprint_messager   r   r   r8      sd    







z+LivepatchEntitlement.setup_livepatch_configc                 C   s$   t  sdS tjt jdgdd dS )zYDisable specific entitlement

        @return: True on success, False otherwise.
        Tr<   r>   )r	   r6   r   rE   rF   )r   r)   r   r   r   _perform_disable   s    z%LivepatchEntitlement._perform_disablec                 C   s:   t jd f}t st jtjfS t d kr6t jtjfS |S r   )	r   r&   r	   r6   rD   r
   ZLIVEPATCH_NOT_ENABLEDstatusZ+LIVEPATCH_APPLICATION_STATUS_CLIENT_FAILURE)r   rK   r   r   r   r%      s    
z'LivepatchEntitlement.application_statusc                 C   sz   t  }|t jjkr4t }dtjj|j	|j
dfS |t jjkr`t }dtjj|j	|j
dfS |t jjkrvdtjfS dS )NT)versionZarch)FN)r	   on_supported_kernelLivepatchSupportUNSUPPORTEDr   Zget_kernel_infor
   ZLIVEPATCH_KERNEL_NOT_SUPPORTEDr'   Zuname_releaseZuname_machine_archZ
KERNEL_EOLZLIVEPATCH_KERNEL_EOLZKERNEL_UPGRADE_REQUIREDZ!LIVEPATCH_KERNEL_UPGRADE_REQUIRED)r   ZsupportZkernel_infor   r   r   enabled_warning_status   s,    z+LivepatchEntitlement.enabled_warning_statusc                 C   s"   t  t jjkrt stjS d S r   )r	   rM   rN   rO   r   r   r
   Z*LIVEPATCH_KERNEL_NOT_SUPPORTED_DESCRIPTION)r   r   r   r   status_description_override   s    z0LivepatchEntitlement.status_description_override)orig_accessdeltasallow_enabler   c                    s   t  |||rdS |di }|di dd}|rH|  \}}|S |  \}}|tjkrbdS |di }	tddg}
t|
	|	}t|d	d}t
||grtd
 ttjj| jd | 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remoteServerr;   zANew livepatch directives or token. running setup_livepatch_config)servicer/   )superprocess_contract_deltasr?   r=   r%   r   rD   setr$   intersectionanyr5   r3   r2   r
   Z#SERVICE_UPDATING_CHANGED_DIRECTIVESr'   r@   r8   )r   rR   rS   rT   Zdelta_entitlementZprocess_enable_defaultZenable_success_r%   Zdelta_directivesZsupported_deltasr0   r1   	__class__r   r   r[   	  sB     
z,LivepatchEntitlement.process_contract_deltas)F)TT)F)F)'__name__
__module____qualname__r
   ZurlsZLIVEPATCH_HOME_PAGEZhelp_doc_urlr@   ZLIVEPATCH_TITLEr   ZLIVEPATCH_DESCRIPTIONZdescriptionZLIVEPATCH_HELP_TEXTZ	help_textZ#affordance_check_kernel_min_versionZaffordance_check_kernel_flavorZaffordance_check_seriesZaffordance_check_archpropertyr   r   r   r   r(   r$   r:   r8   rJ   r   r   ZNamedMessager%   rP   rQ   r   r7   r   r[   __classcell__r   r   r`   r   r      sD   6    >
 

r   c                 C   s   | sdS |  di  di }| d}|rFtjtjdd|gdd | d	d
}|drh|dd }|rtjtjdd|gdd 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.
    NrU   rV   rW   Zconfigzca-certs={}Tr>   rX    /zremote-server={})r?   r   rE   r	   rF   r'   endswith)r#   rV   Zca_certsZremote_serverr   r   r   rA   A  s.    


rA   ) Zloggingtypingr   r   r   r   Zuaclientr   r   r   r	   r
   r   r   r   Zuaclient.entitlements.baser   r   Z(uaclient.entitlements.entitlement_statusr   Zuaclient.typesr   ZLIVEPATCH_RETRIESrG   Zget_event_loggerr2   Z	getLoggerZreplace_top_level_logger_namerb   r5   r   rA   r   r   r   r   <module>   s   (
  &