
Kev              %   @   s  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 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 d  d l m Z d  d l m Z m Z d  d l m Z m Z d  d	 l m Z m Z d  d
 l  m! Z! d  d l" 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 j.   Z/ e j0 e j1 e2   Z3 d Z4 d Z5 d Z6 e& j7 j8 e- j9 e j: e- j; e& j< j8 e- j= e j> e- j; e& j? j8 e- j@ e jA e- j; e& jB j8 e- j@ e jC e- j; e& jD j8 e- jE e jF e- j; e# jG j8 e- j9 e jH e- j; e# jI j8 e- j@ e jJ e- j; e4 e- j9 e jK e- j; e5 e- j9 e jL e- j; e6 e- j9 e jM e- j; i
 ZN d ZO d ZP d jQ d e jR d e jS d e jT d e jU  ZV d ZW d ZX d d d d d e jY   d  d d! d" d# d d$ d d% d d& g  d' e% j< j8 d( e jZ d) i  d* g  d+ d, d- d d- d. d- d/ g  d0 e& j? j8 i d1 d d- d, d- d. d- d2 g  i d3 d" i Z[ d4 d5   Z\ e
 e] e	 f d6 d7 d8    Z^ e e
 e] e	 f d9 d: d;    Z_ e e
 e] e	 f d9 d< d=    Z` e
 e] e	 f d6 d> d?    Za e
 e] e	 f d6 d@ dA    Zb d" e ec e
 e] e	 f dB dC d   Zd e e
 e] e	 f e] e
 e] e	 f dD dE dF    Ze d" e] ec e e
 e] e	 f ef f dG dH dI   Zg e] e] dJ dK dL    Zh e e e] e] dM dN dO    Zi d e e e] e] f e e] e e] dP dQ dR   Zj e e e] dS dT dU    Zk d" e
 e] e	 f ec e] dV dW dX   Zl dY dZ   Zm d S)[    N)OrderedDict)datetimetimezone)AnyDictListOptionalTuple)event_logger
exceptions	livepatchmessagesutilversion)_is_attached)UA_CONFIGURABLE_KEYSUAConfig)get_available_resourcesget_contract_information)ATTACH_FAIL_DATE_FORMATPRINT_WRAP_WIDTH)entitlement_factory)ContractStatusUserFacingAvailabilityUserFacingConfigStatusUserFacingStatus)noticesstate_files)Notice)TxtColorZ	essentialZstandardZadvancedz({name: <17}{available: <11}{description}zJ{name: <17}{available: <11}{entitled: <11}{auto_enabled: <16}{description}z4{name: <17}{entitled: <10}{status: <13}{description}nameentitledstatusdescriptionz4{name: <17}{entitled: <19}{status: <22}{description}z={marker} {name: <15}{entitled: <19}{status: <22}{description}Z_doczUContent provided in json response is currently considered Experimental and may changeZ_schema_versionz0.1r   
machine_idattachedF	effectiveexpiresoriginservicesexecution_statusexecution_detailsfeaturesr   contractid 
created_atproductstech_support_levelaccountexternal_account_ids	simulatedc             C   s   d d   |  j    D S)Nc             S   sR   g  |  ]H } d  | j  j s' | j  j n	 | j  j d | j j d | j j i  q S)r    Zreason_codereason)entitlement
is_variantr    variant_nameZ	named_msgmsg).0service r=   1/usr/lib/python3/dist-packages/uaclient/status.py
<listcomp>   s   	z,_get_blocked_by_services.<locals>.<listcomp>)Zblocking_incompatible_services)entr=   r=   r>   _get_blocked_by_services   s    	rA   )returnc                s  d  } d } |  j    } |  j   } |  j  k r9 d n d } i  } | t j k r` t j }	 n |  j  k r t j }	  |  j } n |  j   \ }	 }
 |	 t j	 k r d |
 j d |
 j
 i } n |
 r |
 j
 } |	 t j k r d } |  j r   f d d   |  j j   D } t |   } d |  j d	 |  j d
 | j d |	 j d | d | d | d | d | i	 } |  j s}| | d <| S)Nr/   noyescodemessagec                s4   i  |  ]* \ } } t  | d         |  q S)cfg)_attached_service_status)r;   r9   Zvariant_cls)rG   inapplicable_resourcesr=   r>   
<dictcomp>   s   	z,_attached_service_status.<locals>.<dictcomp>r    r#   r!   r"   status_detailsdescription_override	available
blocked_bywarningvariants)status_description_overridecontract_statusr    r   
UNENTITLEDr   UNAVAILABLEINAPPLICABLEZuser_facing_statusWARNINGr:   rP   itemsrA   Zpresentation_namer#   valuer8   )r@   rI   rG   rO   rK   rL   rR   rM   rP   Z
ent_statusZdetailsrN   service_statusr=   )rG   rI   r>   rH      sF    									
rH   )rG   rB   c             C   s  t  j t j  t  j t j  t j t  } |  j d } | d } t	 j
 j } | j d | d d d d | j d  d t  j   p g  d	 d
 | d
 d | d d | j d d  d | j d g   d | i d d |  j j d d
 |  j j d
 d |  j j j d d  d |  j j j d g   i i  | j d  rI|  j j | d <| j d  rf| d | d <|  j j d  } | st |   } d d   t | d d d   D } xw | D]o } y% t d |  d | j d d   } Wn t j k
 rwYn X| |   }	 | d j t |	 | |    qW| d j d d  d    |  j j j d! i   j d"  }
 |
 r|
 j d# i   j d$  } | r| | d	 d <| S)%z8Return configuration of attached status as a dictionary.machineTokenInfocontractInfor$   Z	machineIdr%   Tr(   r   r-   r.   r    r0   	createdAtr/   r1   r2   r3   r4   externalAccountIDseffectiveTor'   effectiveFromr&   ZavailableResourcesc             S   s5   i  |  ]+ } | j  d   s | j  d  | d  q S)rM   r#   r    )get)r;   resourcer=   r=   r>   rJ      s   	z$_attached_status.<locals>.<dictcomp>keyc             S   s   |  j  d d  S)Nr    r/   )r`   )xr=   r=   r>   <lambda>   s    z"_attached_status.<locals>.<lambda>rG   r)   c             S   s   |  j  d d  S)Nr    r/   )r`   )rc   r=   r=   r>   rd   
  s    supportr7   affordancessupportLevel)r   remover   ZAUTO_ATTACH_RETRY_FULL_NOTICEZAUTO_ATTACH_RETRY_TOTAL_FAILUREcopydeepcopyDEFAULT_STATUSZmachine_tokenr   rU   rX   updater`   listZmachine_token_filer3   Zcontract_expiry_datetimer   sortedr   r   EntitlementNotFoundErrorappendrH   sortentitlements)rG   responserZ   r[   r2   	resourcesrI   ra   ent_clsr@   re   rg   r=   r=   r>   _attached_status   sd    



			
	rv   c             C   sT  t  j t  } t |   } x| D]} | j d  rF t j j } n t j j } y% t	 d |  d | j d d   } Wn4 t
 j k
 r t j d | j d d   w" Yn X| j d k r t j   t j j k r | |   } | j   } n d } | d	 j d | j d
 | d  d | j d | d | i  q" W| d	 j d d d    | S)z#Return unattached status as a dict.rM   rG   r    r/   z@Ignoring availability of unknown service %s from contract serverzwithout a 'name' keyr   Nr)   presentedAsr#   rL   rb   c             S   s   |  j  d d  S)Nr    r/   )r`   )rc   r=   r=   r>   rd   B  s    z$_unattached_status.<locals>.<lambda>)ri   rj   rk   r   r`   r   	AVAILABLErX   rT   r   r   ro   LOGdebugr    r   on_supported_kernelLivepatchSupportUNSUPPORTEDrQ   rp   r#   rq   )rG   rs   rt   ra   rM   ru   Zlpdescr_overrider=   r=   r>   _unattached_status  s6    	
	r   c       
      C   s   t  j d |  j d d  } | | O} | r/ | St j |  } g  } x | j d i   D] } | d } y t d |  d |  } Wn% t j k
 r | j	 |  wW Yn Xt
 j j }	 | j s | j d d  |	 k rW | j	 |  qW W| r | | d <| S)	z1Remove beta services from response dict if neededconfigZpath_to_valuezfeatures.allow_betar)   r    rG   r"   r/   )r   Zis_config_value_truerG   ri   rj   r`   r   r   ro   rp   r   ACTIVErX   is_beta)
rG   show_allrs   Zconfig_allow_betaZnew_responseZreleased_resourcesra   resource_nameru   Zenabled_statusr=   r=   r>   _handle_beta_resourcesG  s(    	

"
r   c             C   s&  t  } | j j } t j } |  j   \ } } t j   p< g  } | d k ru | j j } t j	 j
 d | d |  } n3 t j j r | j j } d } t j j
 d |  } d | d | d | d	 |  j d
 |  j d |  j i } i  }	 x0 t D]( }
 t |  |
  r t |  |
  |	 |
 <q W|	 | d
 d <| S)aG  Return a dict with execution_status, execution_details and notices.

    Values for execution_status will be one of UserFacingConfigStatus
    enum:
        inactive, active, reboot-required
    execution_details will provide more details about that state.
    notices is a list of tuples with label and description items.
    r   pidlock_holderzconfiguration changes	operationr*   r+   r   Zconfig_pathr   r,   	ua_config)r   INACTIVErX   r   NO_ACTIVE_OPERATIONSZcheck_lock_infor   rm   r   Z	LOCK_HELDformatr   Zreboot_cmd_marker_fileZ
is_presentZREBOOTREQUIREDZENABLE_REBOOT_REQUIRED_TMPLZcfg_pathrG   r,   r   hasattrgetattr)rG   Z
userStatusZ
status_valZstatus_descZlock_pidr   Znotices_listr   retr   rb   r=   r=   r>   _get_config_statusk  s4    					r   )rG   r   rB   c             C   s   t  |   j r t |   } n t |   } | j t |    t j   rY |  j d |  t	 |  | |  } | s d d   | j
 d g   D } | | d <| S)a  Return status as a dict, using a cache for non-root users

    When unattached, get available resources from the contract service
    to report detailed availability of different resources for this
    machine.

    Write the status-cache when called by root.
    zstatus-cachec             S   s.   g  |  ]$ } | j  d  d  d k r |  q S)rM   rD   )r`   )r;   r<   r=   r=   r>   r?     s   	zstatus.<locals>.<listcomp>r)   )r   is_attachedrv   r   rl   r   r   Zwe_are_currently_rootZwrite_cacher   r`   )rG   r   rs   available_servicesr=   r=   r>   r"     s    		
)rr   entitlement_namerB   c          	   C   s   x{ |  D]s } | j  d  | k r d | j  d  r: d n d d | j  d i   j  d  ra d n d d | j  d i   i Sq Wd d d d d i  i S)	z0Extract information from the entitlements array.typer!   rD   rC   auto_enabledZobligationsZenableByDefaultrf   )r`   )rr   r   r7   r=   r=   r>   _get_entitlement_information  s    !r   )tokenr   rB   c          #   C   s  d } t  j t  } y t |  |  } WnX t j k
 r } z5 t | d  rj | j d k rj t j    |  WYd d } ~ Xn X| j	 d i   } | j	 d i   } | j
 d d | j	 d d	  d
 | j	 d
 d	  d | j	 d d	  d | j	 d g   i d d
 | j	 d
 d	  d | j	 d  d | j	 d d	  d | j	 d g   i d d i  t j t j  }	 | j	 d  r| j	 d  | d <| d }
 |
 |	 } | j   d k rt j j d | d d d |
 j t   } t j d | j d | j  t j t j d | j d  d } | j	 d  r| j	 d  | d <| d } |	 | } | j   d k rt j j d | d d d | j t   } t j d | j d | j  t j t j d | j d  d } t |   } d d   t | d d  d!   D } | j	 d" g   } x | D] } | j	 d
 d	  } y t d# |  d
 |  } Wn t j k
 rdwYn X| d# |   } t  | |  } | d$ j! d
 | j	 d% | j  d& | j" d' | d' d( | d( d) | j | k rd* n d+ i  qW| d$ j# d d, d!    t  | d-  } | d' r?| d. j	 d/  } | r?| | d d0 <| j
 t$ |    t% |  | |  } | sd1 d   | j	 d$ g   D } | | d$ <| | f S)2zGet a status dictionary based on a token.

    Returns a tuple with the status dictionary and an integer value - 0 for
    success, 1 for failure
    r   rE   i  Nr[   ZaccountInfor-   r.   r/   r    r0   r\   r1   r3   r4   r]   r5   Tr^   r'   Zcontract_idZdateZ	error_msgZ
error_code
   r_   r&   c             S   s$   g  |  ] } | d  s | d  q S)rM   r    r=   )r;   ra   r=   r=   r>   r?     s   	z#simulate_status.<locals>.<listcomp>rb   c             S   s   |  d S)Nr    r=   )rc   r=   r=   r>   rd     s    z!simulate_status.<locals>.<lambda>ZresourceEntitlementsrG   r)   rw   r#   r!   r   rM   rD   rC   c             S   s   |  j  d d  S)Nr    r/   )r`   )rc   r=   r=   r>   rd   *  s    re   rf   rg   r2   c             S   s.   g  |  ]$ } | j  d  d  d k r |  q S)rM   rD   )r`   )r;   r<   r=   r=   r>   r?   7  s   	)&ri   rj   rk   r   r   ZContractAPIErrorr   rE   ZAttachInvalidTokenErrorr`   rl   r   nowr   ZutcZtotal_secondsr   ZE_ATTACH_FORBIDDEN_EXPIREDr   strftimer   eventerrorr:   r    infoZSTATUS_TOKEN_NOT_VALIDZE_ATTACH_FORBIDDEN_NOT_YETr   rn   r   ro   r   rp   r#   rq   r   r   )rG   r   r   r   rs   Zcontract_informationeZcontract_infoZaccount_infor   Zexpiration_datetimeZdeltarF   Zeffective_datetimert   rI   rr   ra   r   ru   r@   Zentitlement_informationre   rg   r   r=   r=   r>   simulate_status  s    	



	
	


	
r   )stringrB   c             C   s#   t  j j   r t j |  |   S|  S)z=Return colorized string if using a tty, else original string.)sysstdoutisattySTATUS_HUMANIZE_COLORIZEr`   )r   r=   r=   r>   for_human_colorized@  s    r   )commandsrB   c             C   s   d } x1 |  D]) } | r# | d 7} | d j  |  7} q Wd j  t j | d t d d d  } d	 | k r} d
 } d } n d } d } d j d t j d | d | d | d t j  S)Nr/   z &&  z \
width   Zsubsequent_indentz  r   z{
  z
}z{ z }z%{color}{prefix}{content}{suffix}{end}Zcolorprefixcontentsuffixend)jointextwrapZwrapr   r   r   DISABLEGREYENDC)r   r   cmdZwrapped_contentr   r   r=   r=   r>   colorize_commandsI  s&    
			r   )column_dataheaderrB   c                s   g  } | r | j  |  t d d   |  D  } | d k rp d j |    | j   f d d   |  D  n | j d d   |  D  | S)zReturn a list of content lines to print to console for a section

    Content lines will be center-aligned based on max value length of first
    column.
    c             S   s    g  |  ] } t  | d    q S)r   )len)r;   pairr=   r=   r>   r?   p  s   	 z.get_section_column_content.<locals>.<listcomp>r   z{{:>{}}}: {{}}c                s   g  |  ] }   j  |    q Sr=   )r   )r;   r   )templater=   r>   r?   s  s   	 c             S   s   g  |  ] } | d   q S)r   r=   )r;   r   r=   r=   r>   r?   v  s   	 )rp   maxr   extend)r   r   r   Ztemplate_lengthr=   )r   r>   get_section_column_contente  s    #r   )r'   rB   c             C   sE   |  d  k r t  j Sy |  j   }  Wn t k
 r7 Yn X|  j d  S)Nz%c %Z)r   ZSTATUS_CONTRACT_EXPIRES_UNKNOWNZ
astimezone	Exceptionr   )r'   r=   r=   r>   format_expiresz  s    r   )r"   r   rB   c             C   sf  |  j  d  s|  j  d  r |  j  d d  s7 t j St j d t j d t j d t j d t j d	 t j	  g } x0 |  j  d g   D] } | j
 t j |    q Wd
 j |  S|  j  d d  s t j g } n t j d t j d t j d	 t j	  g } x |  j  d g   D] } | j  d  } | r2| n | j  d	 d  } | j  d  d k rbt j n t j } | j
 t j d | j  d d  d | d	 |   qW|  j  d  } | r| j
 t j  | j |  |  j  d  r=| j
 d
 t j  xE t |  j  d i   j    D]% \ } }	 | j
 d j | |	   qW| sY| j d t j g  | j d t j j g  t j   t j j k r| j d t j g  d
 j |  Sg  }
 d } |  j  d d  st j g } n t g } x|  j  d g   D]} | j  d d  } | j  d  } | r)| n | j  d	 d  } d | j  d d  d t |  d t | j  d d   d	 | i } | j  d d  } | d k	 r| j  d d  } | d k	 r|
 j
 |  | j  d  } | r| rd } d j | d  | d <| j
 t j |    | r| rx t | j    D] \ } \ } } | t  |  d k rbd n d } | j
 t! j d | d | j  d  d t | j  d d   d t | j  d d   d	 | j  d	 d    q4WqW| r| j
 d  | j
 t j"  |  j  d  st  |
  d k r|| j
 d  | j
 t j  |  j  d  } | r]| j |  t  |
  d k r|| j |
  |  j  d  r| j
 d
 t j  xE t |  j  d i   j    D]% \ } }	 | j
 d j | |	   qW| j
 d  | s#| r| j
 t j#  n | j
 t j  | j
 t j$ j d d   g  } |  j  d i   j  d d   } | r| j
 t j% | f  |  j  d! i   j  d d   } | r| j
 t j& | f  |  j  d" d  d# k r0| j
 t j' t( |  j  d$   f  |  j  d! i   j  d% d   } | j
 t j) t |  f  | rY| j
 d  | j t* d& |   d
 j |  S)'z&Format status dict for tabular output.r%   r5   r)   Nr    rM   r!   r   r#   r   rL   r/   rD   r   r,   z{}: {}Fr"   rO   rF   rP   Tz{}*r   u   ├u   └markerr   Zcommandzpro enable <service>r3   unknownr-   r(   Zfreer'   r2   r   )+r`   r   ZSTATUS_NO_SERVICES_AVAILABLESTATUS_SIMULATED_TMPLr   STATUS_SERVICEZSTATUS_AVAILABLESTATUS_ENTITLEDZSTATUS_AUTO_ENABLEDSTATUS_DESCRIPTIONrp   r   STATUS_UNATTACHED_TMPLZSTANDALONE_YESZSTANDALONE_NOZSTATUS_NOTICESr   ZSTATUS_FEATURESrn   rW   ZSTATUS_ALL_HINTZE_UNATTACHEDr:   r   r{   r|   r}   Z)LIVEPATCH_KERNEL_NOT_SUPPORTED_UNATTACHEDSTATUS_HEADERr   STATUS_TMPL	enumerater   VARIANT_STATUS_TMPLZSTATUS_SERVICE_HAS_VARIANTSZSTATUS_ALL_HINT_WITH_VARIANTSZ"STATUS_FOOTER_ENABLE_SERVICES_WITHZSTATUS_FOOTER_ACCOUNTZSTATUS_FOOTER_SUBSCRIPTIONZSTATUS_FOOTER_VALID_UNTILr   ZSTATUS_FOOTER_SUPPORT_LEVELr   )r"   r   r   r<   r~   r#   rM   r   rb   rX   Zservice_warningsZhas_variantsrY   r!   Zfmt_argsrO   Zwarning_messagerP   idx_Zvariantr   ZpairsZaccount_nameZcontract_namer2   r=   r=   r>   format_tabular  s    										+		%"	!+
r   c             C   si  t  |   } d } t   } | | d <x~ | D]v } | d | k sW | j d  | k r, y t d |  d | d  } Wn t j k
 r w, Yn X| } | |   } Pq, W| d k r t j d |   t |   j r)t	 | i  |   } | d }	 | d | d <|	 | d <|	 d k rX| j
 rXd | d	 <n/ | d
 rBt j j }
 n t j j }
 |
 | d
 <| j | d <| S)zReturn help information from an uaclient service as a dict

    :param name: Name of the service for which to return help data.

    :raises: UbuntuProError when no help is available.
    Nr    rw   rG   r"   r!   enabledTZbetarM   help)r   r   r`   r   r   ro   ZNoHelpContentr   r   rH   r   r   rx   rX   rT   Z	help_info)rG   r    rt   Zhelp_resourceZresponse_dictra   Zhelp_ent_clsZhelp_entrY   Z
status_msgrM   r=   r=   r>   r   @  s:    	
%



r   )nri   Zloggingr   r   collectionsr   r   r   Ztypingr   r   r   r   r	   Zuaclientr
   r   r   r   r   r   Z(uaclient.api.u.pro.status.is_attached.v1r   Zuaclient.configr   r   Zuaclient.contractr   r   Zuaclient.defaultsr   r   Zuaclient.entitlementsr   Z(uaclient.entitlements.entitlement_statusr   r   r   r   Zuaclient.filesr   r   Zuaclient.files.noticesr   Zuaclient.messagesr   Zget_event_loggerr   Z	getLoggerZreplace_top_level_logger_name__name__ry   Z	ESSENTIALZSTANDARDZADVANCEDr   rX   ZOKGREENZSTATUS_STATUS_ENABLEDr   r   ZFAILZSTATUS_STATUS_DISABLEDrU   r   ZSTATUS_STATUS_INAPPLICABLErT   ZSTATUS_STATUS_UNAVAILABLErV   ZWARNINGYELLOWZSTATUS_STATUS_WARNINGZENTITLEDZSTATUS_ENTITLED_ENTITLEDrS   ZSTATUS_ENTITLED_UNENTITLEDZSTATUS_SUPPORT_ESSENTIALZSTATUS_SUPPORT_STANDARDZSTATUS_SUPPORT_ADVANCEDr   r   r   r   r   r   ZSTATUS_STATUSr   r   r   r   Zget_versionr   rk   rA   strrH   rv   r   r   r   boolr"   r   intr   r   r   r   r   r   r   r=   r=   r=   r>   <module>   s   (."													9"H"1$+(!	)x	 
(