U
    lHJec                     @   s`  d 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Zddl	Z	ddl
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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" dd	lm#Z#m$Z$m%Z% dd
l&m'Z' ddl(m)Z)m*Z* ddl+m,Z, ddl-m.Z.m/Z/ ddl0m1Z1m2Z2 ddl3m4Z4 ddl5m6Z6 ddl7m8Z8m9Z9 ddl:m;Z;m<Z< ddl=m>Z> ddl?m@Z@mAZA ddlBmCZC ddlDmEZEmFZFmGZG ddlHmIZImJZJmKZKmLZL ddlMmNZNmOZO ddlPmQZQ ddlRmSZS ddlTmUZUmVZV ddlWmXZXmYZY dZZddd gZ[d!Z\e] Z^e_e$`eaZbG d"d# d#ejcZddd$d%Zed&d' Zfd(d) Zgdd*d+Zhd,d- Zid.d/ Zjd0d1 Zkd2d3 Zlemd4d5d6Znemd4d7d8Zoemd4d9d:Zpd;d< Zqd=d> Zrd?d@ ZsdAdB ZtdCdD ZudEdF ZvejwdGdHdIZxejwdGdJdKZyejwdGdLdMZzdNdO Z{dPdQ Z|dRdS Z}ejwememdTdUdVZ~dWdXdYdZZd[d\ Zd]d^ Zefd_d` Zefdadb Zdcdd Zegefeheeededfdg Zegefeheeedhdidj Zegefeh eedkedldmdnZejweedodpdqZejwddrdsdtZdudv ZefejwedrdwdxZdydz Zeiefeed{d|d} ZejwdGd~dZejwdGddZejwdGddZdd ZejwdGddZdddZejwdGddZeh ejwdGddZejwdGddZefeedejwdGddZejwe8emeem ddddZdd ZdddlddZddlddZdddZdd Zdd ZedddZeadkr\ee  dS )z2Client to manage Ubuntu Pro services on a machine.    Nwraps)ListOptionalTuple)actionsaptapt_newsconfigcontractdaemondefaultsentitlementsevent_logger
exceptionshttplock)log)messagessecurity_status)status)timerutilversion)call_api)FullAutoAttachOptions_full_auto_attach)	_initiate)MagicAttachRevokeOptions_revoke)MagicAttachWaitOptions_wait)_reboot_required)_is_attached)AptProxyScopesetup_apt_proxy)NAME
USAGE_TMPL)set_fix_parser)AttachActionsConfigFileIncorrectTypeError)PRINT_WRAP_WIDTH)*create_enable_entitlements_not_found_errorentitlements_disable_orderget_valid_entitlement_names)ApplicationStatusCanDisableFailureCanEnableFailureCanEnableFailureReason)noticesstate_files)Notice)JsonArrayFormatter)refresh_motdupdate_motd_messages)	safe_dump	safe_loadz$https://auth.contracts.canonical.comZtabularjsonyamlzua_logs.tar.gzc                       sl   e Zd Zdddejdfee d fddZdd Zd fdd		Z	e
eee ee f d
ddZ  ZS )UAArgumentParserN)	base_descc                    s   t  j||||d || _d S )N)progusageepilogformatter_class)super__init__r>   )selfr?   r@   rA   rB   r>   	__class__ 7/usr/lib/python3/dist-packages/uaclient/cli/__init__.pyrD   T   s    zUAArgumentParser.__init__c                 C   s.   |  tj |dkrtj}| d|d  d S )Nz&the following arguments are required:    
)print_usagesysstderrr   CLI_TRY_HELPexit)rE   messagerH   rH   rI   errore   s    zUAArgumentParser.errorFc                    sd   | j rRt \}}t|}|r*t|| }d| j g| | _|  jdtj 7  _t j	|d d S )NrK   z

file)
r>   r=   _get_service_descriptionssortedjoindescriptionr   ZPRO_HELP_SERVICE_INFOrC   
print_help)rE   rT   show_allnon_beta_services_descbeta_services_descZservice_descriptionsrF   rH   rI   rY   u   s    
zUAArgumentParser.print_helpreturnc            
   	   C   s   t  } d}g }g }tt  }|D ]}ztj| |d d}W n tjk
rZ   Y q&Y nX |d|d }|j	rd
|j	}nd}tj|j
||j|dtdd	d	d
}	|jr||	 q&||	 q&||fS )Nz - {name}: {description}{url}namecfgr_   ZpresentedAsz ({}) )r_   rX   urlz   F)widthZsubsequent_indentbreak_long_wordsbreak_on_hyphens)r
   UAConfigr   Zget_available_resourcesr   entitlement_factoryr   EntitlementNotFoundErrorgetZhelp_doc_urlformattextwrapZfillrX   r+   Zis_betaappend)
ra   Zservice_info_tmplr[   r\   Z	resourcesresourceent_clsZpresentation_namerc   Zservice_inforH   rH   rI   rU      s@     

z*UAArgumentParser._get_service_descriptions)NF)__name__
__module____qualname__argparseZHelpFormatterr   strrD   rR   rY   staticmethodr   r   rU   __classcell__rH   rH   rF   rI   r=   S   s   r=   c                    s    fdd}|S )z1Decorator asserting exclusive access to lock filec                    s   t   fdd}|S )Nc              	      s0   t j| d  |d| i|}W 5 Q R X |S )N)ra   lock_holderra   )r   ZSingleAttemptLock)ra   argskwargsZretval)frw   rH   rI   new_f   s    z0assert_lock_file.<locals>.wrapper.<locals>.new_fr   rz   r{   rw   rz   rI   wrapper   s    z!assert_lock_file.<locals>.wrapperrH   )rw   r   rH   r}   rI   assert_lock_file   s    	r   c                    s   t   fdd}|S )zDecorator asserting root userc                     s    t  st n
 | |S d S N)r   we_are_currently_rootr   ZNonRootUserError)rx   ry   r~   rH   rI   r{      s    
zassert_root.<locals>.new_fr   r|   rH   r~   rI   assert_root   s    r   c                    s   t   fdd}|S )z>Decorator to verify if correct params are used for json formatc                    sB   | s | f||S | j dkr.| js.t n | f||S d S )Nr;   )rk   
assume_yesr   ZCLIJSONFormatRequireAssumeYes)cmd_argsrx   ry   r~   rH   rI   r{      s
    
z&verify_json_format_args.<locals>.new_fr   r|   rH   r~   rI   verify_json_format_args   s    	r   c                    s    fdd}|S )zDecorator asserting attached config.
    :param msg_function: Optional function to generate a custom message
    if raising an UnattachedError
    c                    s   t   fdd}|S )Nc                    sR   t |js>r6t| dd}t| dd}|||d nt  | fd|i|S )Ncommandrb   service)r   service_namesra   ra   )r#   is_attachedgetattrr   ZUnattachedError)rx   ra   ry   r   r   )rz   raise_custom_error_functionrH   rI   r{      s    
  z/assert_attached.<locals>.wrapper.<locals>.new_fr   r|   r   r~   rI   r      s    z assert_attached.<locals>.wrapperrH   )r   r   rH   r   rI   assert_attached   s    r   c                    s   t   fdd}|S )z&Decorator asserting unattached config.c                    s6   t |jr"tj|jjddd | fd|i|S )Nr_   rb   )Zaccount_namera   )r#   r   r   ZAlreadyAttachedErrormachine_token_fileZaccountrj   rx   ra   ry   r~   rH   rI   r{      s
    
z"assert_not_attached.<locals>.new_fr   r|   rH   r~   rI   assert_not_attached   s    r   c                 C   sN   d| _ tj| _| jddtjd | jddg dtjd | jd	d
dtjd | S )z5Build or extend an arg parser for the api subcommand.apiendpoint_pathZendpoint)metavarhelpz--argsoptions*)destdefaultnargsr   z--datadatarb   )r   r   r   )r?   r   ZCLI_API_DESCrX   add_argumentZCLI_API_ENDPOINTZCLI_API_ARGSZCLI_API_DATAparserrH   rH   rI   
api_parser  s*         r   c                 C   s.   d| _ tj| _tjt| j d| _tj| j	_
| S )z9Build or extend an arg parser for auto-attach subcommand.auto-attachr_   r   )r?   r   ZCLI_AUTO_ATTACH_DESCrX   r'   rk   r&   r@   	CLI_FLAGS
_optionalstitler   rH   rH   rI   auto_attach_parser  s
    
r   c                 C   s6   d| _ tj| _tjt| j d| _| jddtj	d | S )z<Build or extend an arg parser for 'collect-logs' subcommand.collect-logsr   z-oz--outputr   )
r?   r   ZCLI_COLLECT_LOGS_DESCrX   r'   rk   r&   r@   r   ZCLI_COLLECT_LOGS_OUTPUTr   rH   rH   rI   collect_logs_parser!  s    r   parent_commandc                 C   s:   t jtd|d| _d| _tj| _| jddtj	d | S )z;Build or extend an arg parser for 'config show' subcommand.z{} show [key]r   showkey?r   r   )
r'   rk   r&   r@   r?   r   CLI_CONFIG_SHOW_DESCrX   r   ZCLI_CONFIG_SHOW_KEYr   r   rH   rH   rI   config_show_parser.  s     r   c                 C   sR   t jtd|d| _d| _tj| _tj| j	_
| jdtjjdtjdd | S )z:Build or extend an arg parser for 'config set' subcommand.z{} set <key>=<value>r   Zasetkey_value_pair, r   r   )r'   rk   r&   r@   r?   r   CLI_CONFIG_SET_DESCrX   r   r   r   r   ZCLI_CONFIG_SET_KEY_VALUErW   r
   UA_CONFIGURABLE_KEYSr   rH   rH   rI   config_set_parser=  s     

r   c                 C   sT   t jtd|d| _d| _tj| _| jdtj	jd
tjddd tj| j_| S )z<Build or extend an arg parser for 'config unset' subcommand.z{} unset <key>r   unsetr   r   r   )r   r   )r'   rk   r&   r@   r?   r   CLI_CONFIG_UNSET_DESCrX   r   ZCLI_CONFIG_UNSET_KEYrW   r
   r   r   r   r   r   rH   rH   rI   config_unset_parserP  s     
	
r   c                 C   s   d}t jtd|d| _|| _tj| _tj| j	_
| jtjddd}|jdtjd}|jtd	 t||d
 |jdtjd}|jtd	 t||d
 |jdtjd}|jtd	 t||d
 | S )z4Build or extend an arg parser for config subcommand.r
   z{} <command>r   r   rb   r   r   r   r   r   actionr   setr   )r'   rk   r&   r@   r?   r   ZCLI_CONFIG_DESCrX   r   r   r   add_subparsersCLI_AVAILABLE_COMMANDS
add_parserr   set_defaultsaction_config_showr   r   action_config_setr   r   action_config_unsetr   )r   r   
subparsersZparser_showZ
parser_setZparser_unsetrH   rH   rI   config_parserd  s@     
     r   c                 C   s   t jtdd| _tj| _d| _tj	| _
tj| j_| jddtjd | jddd	tjd
 | jdtdtjd | jddddgdtjjddd | S )z4Build or extend an arg parser for attach subcommand.zattach <token>r   attachtokenr   r   z--no-auto-enableZstore_falseauto_enable)r   r   r   z--attach-configr)typer   --formatstoreclir;   r   r   choicesr   r   )r'   rk   r&   r@   rs   RawDescriptionHelpFormatterrB   r?   r   ZCLI_ATTACH_DESCrX   r   r   r   r   ZCLI_ATTACH_TOKENZCLI_ATTACH_NO_AUTO_ENABLEZFileTypeZCLI_ATTACH_ATTACH_CONFIGCLI_FORMAT_DESCr   rH   rH   rI   attach_parser  s2    
r   c                 C   s   d| _ tj| _tj| _| jdtjj	ddddd | 
 }|jdtjdd	 |jd
tjdd	 |jdtjdd	 |jdtjdd	 | S )z=Build or extend an arg parser for security-status subcommand.security-statusr   textr   )r;   r<   r   )r   r   r   z--thirdparty
store_true)r   r   z--unavailablez--esm-infraz
--esm-apps)r?   rs   r   rB   r   ZCLI_SS_DESCrX   r   r   rk   Zadd_mutually_exclusive_groupZCLI_SS_THIRDPARTYZCLI_SS_UNAVAILABLEZCLI_SS_ESM_INFRAZCLI_SS_ESM_APPS)r   grouprH   rH   rI   security_status_parser  s>    r   c                 C   sP   d| _ tjtdd| _tj| j_t	j
| _tj| _| jddddgdd	tjd
 | S )z5Build or extend an arg parser for refresh subcommand.refreshz"refresh [contract|config|messages]r   targetr   r
   r   r   N)r   r   r   r   )r?   r'   rk   r&   r@   r   r   r   r   rs   r   rB   ZCLI_REFRESH_DESCrX   r   ZCLI_REFRESH_TARGETr   rH   rH   rI   refresh_parser  s      
r   c                K   s   | j dkrZ| jrt  q| jr*t  q| jr<t| q| jrNt	| qt| n>| j dkrt
tjt|dtjd nt
tt|dd dS )Nr   r;   T)Z	sort_keysclsF)Zdefault_flow_styler   )rk   Z
thirdpartyr   Zlist_third_party_packagesZunavailableZlist_unavailable_packagesZ	esm_infraZlist_esm_infra_packagesZesm_appsZlist_esm_apps_packagesprintr;   dumpsZsecurity_status_dictr   ZDatetimeAwareJSONEncoderr9   r   rH   rH   rI   action_security_status  s2    



r   c                 C   sj   t jtdd}|| _d| _tj| _d| j_	| j
ddtjjddd | j
dd	d
dgd
tjjd
dd | S )z4Build or extend an arg parser for detach subcommand.detachr   Flags--assume-yesr   r   r   r   r   r   r   r;   r   r   )r'   rk   r&   r@   r?   r   ZCLI_DETACH_DESCrX   r   r   r   CLI_ASSUME_YESr   r   r@   rH   rH   rI   detach_parser  s$    r   ra   c              
   C   s   t jtdd}|| _d| _tj| _tj| j	_
| jdddtjjdtj|dd	d
 | jddttd tjjtd dd | jddtjd | S )z2Build or extend an arg parser for help subcommand.zhelp [service]r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   --allr   r   )r'   rk   r&   r@   r?   r   ZCLI_HELP_DESCrX   CLI_ARGS_positionalsr   r   ZCLI_HELP_SERVICErW   r   valid_servicesSTATUS_FORMATSr   ZCLI_HELP_ALLr   ra   r@   rH   rH   rI   help_parser  s4    
	  r   c              
   C   s   t jtdd}tj| _|| _d| _tj| j	_
tj| j_
| jdddtjjdtj|dd	d
 | jddtjjddd | jddtjd | jddtjd | jddddgdtjjddd | jddtjd | S )z4Build or extend an arg parser for enable subcommand.zenable <service> [<service>]r   enabler   r   +r   r   r   r   r   r   r   r   --access-onlyz--betar   r   r;   r   r   	--variant)r'   rk   r&   r   ZCLI_ENABLE_DESCrX   r@   r?   r   r   r   r   r   r   ZCLI_ENABLE_SERVICErW   r   r   r   ZCLI_ENABLE_ACCESS_ONLYZCLI_ENABLE_BETAr   ZCLI_ENABLE_VARIANTr   rH   rH   rI   enable_parser.  sZ     


    r   c              
   C   s   t jtdd}tj| _|| _d| _tj| j	_
tj| j_
| jdddtjjdtj|dd	d
 | jddtjjddd | jddddgdtjjddd | jddtjd | S )z5Build or extend an arg parser for disable subcommand.zdisable <service> [<service>]r   disabler   r   r   r   r   r   r   r   r   r   r   r   r   r;   r   r   --purge)r'   rk   r&   r   ZCLI_DISABLE_DESCrX   r@   r?   r   r   r   r   r   r   ZCLI_DISABLE_SERVICErW   r   r   r   r   Z	CLI_PURGEr   rH   rH   rI   disable_parser\  sF     


r   c                 C   sb   t jtdd| _tj| _d| _tj| j	_
| jtjddd}|jdtjd}|jtd	 t| | S )
z4Build or extend an arg parser for system subcommand.zsystem <command>r   systemr   rb   r   reboot-requiredr   r   )r'   rk   r&   r@   r   ZCLI_SYSTEM_DESCrX   r?   r   r   r   r   r   r   ZCLI_SYSTEM_REBOOT_REQUIREDr   action_system_reboot_requiredreboot_required_parser)r   r   Zparser_reboot_requiredrH   rH   rI   system_parser  s     
   r   c                 C   s*   t jtdd| _d| _tj| _tj	| _
| S )Nzsystem reboot-requiredr   r   )r'   rk   r&   r@   Zprors   r   rB   r   ZCLI_SYSTEM_REBOOT_REQUIRED_DESCrX   r   rH   rH   rI   r     s     r   c                 C   s   t jtdd}|| _d| _tj| _tj	| _
| jdddtjd | jddttd	 tjjtd	 d
d | jdddtjd | jddtjd d| j_| S )z4Build or extend an arg parser for status subcommand.r   r   z--waitr   F)r   r   r   r   r   r   r   r   z--simulate-with-tokenZTOKEN)r   r   r   r   r   r   )r'   rk   r&   r@   r?   rs   r   rB   r   ZCLI_STATUS_DESCrX   r   ZCLI_STATUS_WAITr   r   ZCLI_STATUS_SIMULATE_WITH_TOKENZCLI_STATUS_ALLr   r   r   rH   rH   rI   status_parser  s>      r   )ra   cmd_namesubcmd_namec                 C   sd   t | d}| d j| }| d j }||kr`| d j|   tjdd|dd S )Nr   r   	<command>r   argr   )
get_parser_get_positional_actionsr   keysrY   r   InvalidArgChoicerW   )ra   r  r  r   	subparserZvalid_choicesrH   rH   rI   _print_help_for_subcommand  s    
 r  T)update_statusc                C   s   | j }|dk	r|} |  \}}|stt| j |dk	rt|tr|jdk	rt|jj	 tj
|jj	|jj| jd nt| j |rtj|d |S )a=  Perform the disable action on a named entitlement.

    :param entitlement_name: the name of the entitlement to enable
    :param cfg: the UAConfig to pass to the entitlement
    :param assume_yes:
        Assume a yes response for any prompts during service enable

    @return: True on success, False otherwise
    N	error_msg
error_coder   r   )Zenabled_variantr   eventservice_failedr_   
isinstancer0   rQ   infomsgrR   service_processed	ua_statusr   )entitlementra   r   r  variantretreasonrH   rH   rI   _perform_disable  s$    
r  c                K   s   t |d| jd dS )zGPerform the config action.

    :return: 0 on success, 1 otherwise
    r
   r  r  r   r  r   r   rH   rH   rI   action_config  s      r  c                K   s   | j rR| j tjkr0tjd| j dtjdtdj| j t|| j dd dS t	t
dd	 tjD d
 }d| d }tjD ]}t|j|t||dd q|js|jr|js|jrttj dS )zPerform the 'config show' action optionally limit output to a single key

    :return: 0 on success
    :raise UbuntuProError: on invalid keys
    z'{}'r   r  z{key} {value}Nr   valuer   c                 S   s   g | ]}t |qS rH   )len).0xrH   rH   rI   
<listcomp>  s     z&action_config_show.<locals>.<listcomp>   z{key: <z	} {value})r   r
   r   r   r	  rk   rW   r   r   rt   maxglobal_apt_http_proxyglobal_apt_https_proxyua_apt_http_proxyua_apt_https_proxyr   ZCLI_CONFIG_GLOBAL_XOR_UA_PROXY)rx   ra   ry   Z	col_widthZrow_tmplr   rH   rH   rI   r     s.    

 
r   c                K   s,  ddl m} ddlm} t|d}| d jd }| d jd }z| jd\}}	W n, t	k
r   |
  tjd| jd	Y nX |tjkr|
  tjd
dtjd|dkr0|dd }
|
dkrtj}ntj}t|
|	| ||	i}|f | tj|}| \}}|tjkr|f | n||jkr|dd }
|
dkr\tj}ntj}t|
|	| t|jp~|j }|rt!t"j#j$ddd t%|t&j'||	 d|_d|_ n`||j(|j) krd|krdnd}
|
dkrtj}ntj}||j(kr,t!t"j*j$d$|
d$|
d d| }t|
|	| t|j+pH|j,}|rft!t"j#j$ddd t%|t&j-||	 d|_+d|_,n|dkrz$t.|	}	|	dk rt	d$|W n4 t	k
r   |
  t!d tj/||	dY nX n2|dkr|	0 dk}	|	rt12| n
t3j45  t6|||	 dS ) zMPerform the 'config set' action.

    @return: 0 on success, 1 otherwise
    r   )configure_livepatch_proxy)configure_snap_proxyr   r
   r   =z<key>=<value>)ZexpectedZactual<key>r   r  
http_proxyhttps_proxy_r   rJ   zpro scoped aptz
global apt)Zcurrent_proxyZprevious_proxyNhttpsapt_{}_proxyglobal_apt_{}_proxyoldnewglobal_)Zupdate_messaging_timerZmetering_timerzInvalid interval for {}rb   r  r	   true)7uaclient.livepatchr+  uaclient.snapr,  r  r  r   r   split
ValueErrorrY   r   ZGenericInvalidFormatr
   r   r	  rW   r   ZPROXY_VALIDATION_SNAP_HTTP_URLZPROXY_VALIDATION_SNAP_HTTPS_URLZvalidate_proxyr   	livepatchLivepatchEntitlementapplication_statusr/   ENABLEDua_scoped_proxy_optionsZPROXY_VALIDATION_APT_HTTP_URLZPROXY_VALIDATION_APT_HTTPS_URLboolr'  r(  r   r   ZWARNING_APT_PROXY_OVERWRITErk   configure_apt_proxyr$   UACLIENT&deprecated_global_scoped_proxy_optionsglobal_scoped_proxy_optionsWARNING_CONFIG_FIELD_RENAMEr)  r*  GLOBALintZInvalidPosIntConfigValuelowerr	   update_apt_newsr4   Zapt_news_contents_filedeletesetattr)rx   ra   ry   r+  r,  r   r   r
  set_key	set_valueprotocol_typeZvalidate_urlr  livepatch_statusr2  Zunset_currentrH   rH   rI   r   !  s    
 
 



 

 

 

r   c                K   sv  ddl m} ddlm} ddlm} | jtjkr|t	|d}|
 d jd }|
 d jd }|  tjdd	tjd
| jdkr| jdd }	||	d tj|}
|
 \}}|tjkr||	d n| j|jkrt||j| jd nv| j|j|j krd| j|jkrRd| jkr dnd}	ttjj d |	d |	d d| j | _t||j!| jd t"|| jd dS )zOPerform the 'config unset' action.

    @return: 0 on success, 1 otherwise
    r   )r$   )unconfigure_livepatch_proxy)unconfigure_snap_proxyr   r
   r   r.  r   r  r/  r2  )rR  Nr3  r   r4  r5  r6  r9  )#uaclient.aptr$   r;  rT  r<  rU  r   r
   r   r  r  r   rY   r   r	  rW   r=  r   r?  r@  rA  r/   rB  rC  rE  rF  rG  rH  r  r  r   rI  rk   rJ  rO  )rx   ra   ry   r$   rT  rU  r   r   r
  rR  r  rS  r2  rH   rH   rI   r     sL    
 



r   c                 C   sj   t ||d\}}|r8|r8tjd|| d|ddn.|rPtjd|dntj| d|dddS )zRaises a custom error for enable/disable commands when unattached.

    Takes into consideration if the services exist or not, and notify the user
    accordingly.)namesra   r   rb   )valid_service	operationinvalid_serviceservice_msg)rX  rY  rZ  r[  N)r.   r   ZUnattachedMixedServicesErrorrW   ZUnattachedValidServicesErrorZUnattachedInvalidServicesError)r   r   ra   entitlements_foundentitlements_not_foundrH   rH   rI   &_raise_enable_disable_unattached_error  s(     
r_  zpro disablec                K   s   | j r| jrtjdddt| dg }t||\}}d}|D ]8}tj||d}||| j| j d}	|t|	|| jdM }q<|rd	d
	tj
|dd d }
d	tj|
dddd}tjdd
	||dt|}|  t  |rdS dS )zbPerform the disable action on a list of entitlements.

    @return: 0 on success, 1 otherwise
    r   r   Zoption1Zoption2r   Tr`   )r   purger   zTry r   ra   
allow_beta.rK   P   F)rd   re   rf   r   r\  r   r%  )ra  r   r   InvalidOptionCombinationr   r.   r   rh   r  rW   r   rl   ZwrapZInvalidServiceOpErrorr   UAContractClientupdate_activity_tokenr  process_events)rx   ra   ry   rW  r]  r^  r  ent_namero   entZvalid_namesr[  contract_clientrH   rH   rI   action_disable  sN    	  
rn  z
pro enablec                K   s  t | dd}| j}|r(|r(tjdddttj zt	| W n8 tj
tjfk
rz   tjddd tjtjd	 Y nX t | d
g }t||\}}d}|D ]&}	ztj||	| j| j|||dd\}
}tj|d |
s@|dk	r@t|tr@|jdk	r&t|jj tj|jj|jj|	d |jtjkrp| |	 n0|
rTtj!|	d n|
sp|dkrptj"|	d ||
M }W q tjk
r } z(t|j tj|j|j#|	d d}W 5 d}~X Y qX q|rt$| t%||| jdt&|}|'  t(  |rdS dS )z^Perform the enable action on a named entitlement.

    @return: 0 on success, 1 otherwise
    r  rb   r   r   r`  zFailed to refresh contractTexc_info)Zwarning_msgr   
extra_args)r   rd  access_onlyr  rq  r   Nr  )r   Frc  r   r%  ))r   rr  r   rg  r  r  r   ZREFRESH_CONTRACT_ENABLEr   r   UrlErrorUbuntuProErrorLOGwarningZE_REFRESH_CONTRACT_FAILUREr.   r   enable_entitlement_by_namer   Zbetarj   r  r   r  r1   rQ   r  rR   r_   r  r2   ZIS_BETArm   r  r  msg_codeZservices_failedr,   rh  ri  rj  )rx   ra   ry   r  rr  rW  r]  r^  r  rk  ent_retr  erm  rH   rH   rI   action_enable  s    	  

	  
  
r{  z
pro detachr]   c                K   s2   t || jd}|dkr&t  t  t  |S )zXPerform the detach action for this machine.

    @return: 0 on success, 1 otherwise
    rb  r   )_detachr   r   startr   stopr  rj  )rx   ra   ry   r  rH   rH   rI   action_detachm  s    	r  )ra   r   r^   c              	   C   s   g }t | D ]\}ztj| |d}W n tjk
r<   Y qY nX || |d}|jdd\}}|r|| q|rtt	j
t| |D ]}td|j qtj|dsdS |D ]}t|| |dd	 q|   | j  t|  tt	j d
S )a7  Detach the machine from the active Ubuntu Pro subscription,

    :param cfg: a ``config.UAConfig`` instance
    :param assume_yes: Assume a yes answer to any prompts requested.
         In this case, it means automatically disable any service during
         detach.

    @return: 0 on success, 1 otherwise
    r`   )ra   r   T)Zignore_dependent_servicesz    {}rb  r%  F)r   r  r   )r-   r   rh   r   ri   Zcan_disablerm   r  r  r   ZDETACH_WILL_DISABLEZ	pluralizer!  rk   r_   r   Zprompt_for_confirmationr  Zdelete_cacher   rN  r8   ZDETACH_SUCCESS)ra   r   Z
to_disablerk  ro   rl  r  r2  rH   rH   rI   r|  ~  s.    


r|  )ra   r^   c                 C   s   d }| j r&| j di di d}|r@ttjj|d nttj t	  t
|  t| \}}t|}tt| t  d S )NZmachineTokenInfoZcontractInfor_   )contract_name)Zmachine_tokenrj   r  r  r   ZATTACH_SUCCESS_TMPLrk   ZATTACH_SUCCESS_NO_CONTRACT_NAMEr   r~  Zcleanupr   r   r  format_tabularr   handle_unicode_charactersrj  )ra   r  r   Z_retoutputrH   rH   rI   _post_cli_attach  s(     

r  c                K   sF   | j r| jrt t| j| j | j|}t|  |jdkrBdS dS )NZsuccessr   r%  )	r   r   r   ZCLIAPIOptionsXORDatar   r   r   Zto_jsonresultrx   ra   ry   r  rH   rH   rI   
action_api  s
    r  c                K   sP   zt t |tjjd W n& tjk
r>   tt	j
j Y dS X t| dS d S )N)ra   moder%  r   )r   r   r   EventLoggerModeZCLIr   rs  r  r  r   ZE_ATTACH_FAILUREr  r  r   rH   rH   rI   action_auto_attach  s    
r  c             
   K   s   | j dkrtjd| j dttj t|d}tdtjj |j	d  t
|jd}zt||d}W nL tjk
r } z,ttj t|jd}t||d |W 5 d }~X Y nX tdtj  |jS )	Nr;   r   )Zparamr   r   rK   )	user_code)Zmagic_token)r   ra   )rk   r   ZMagicAttachInvalidParamr  r  r   ZCLI_MAGIC_ATTACH_INITr   ZCLI_MAGIC_ATTACH_SIGN_INr  r    r   r!   ZMagicAttachTokenErrorZCLI_MAGIC_ATTACH_FAILEDr   r   ZCLI_MAGIC_ATTACH_PROCESSINGZcontract_token)rx   ra   ry   Zinitiate_respZwait_optionsZ	wait_resprz  Zrevoke_optionsrH   rH   rI   _magic_attach  s4    

r  z
pro attachc             
   K   s  | j r| jrt n| j s4| js4t| |d}d }nj| j rF| j }d }nXztt| j}W n6 tk
r } ztj	| jj
|jdW 5 d }~X Y nX |j }|j}| jo|d k}ztj|||d W n  tjk
r   t Y n X d}|d k	r| jrt||\}	}
|	D ]z}tj||ddd\}}|sxd}|d k	rt|tr|jd k	rt|jj tj|jj|jj
|d n
t| q
|
rt|
|dd	}tj|jtjd
 tj|j|jd d}t |}|!  t"| |S d S )Nr   )Zconfig_namerR   )r   allow_enabler   T)r   rd  r%  r  rc  	file_typer  r  )#r   attach_configr   ZCLIAttachTokenArgXORConfigr  r)   Z	from_dictr:   r*   ZAttachInvalidConfigFileErrorr_   r  Zenable_servicesr   r   Zattach_with_tokenrs  ZAttachErrorr.   rw  r  r1   rQ   r  r  rR   r  r,   rM   rN   rx  r   rh  ri  r  )rx   ra   ry   r   Zenable_services_overrider  rz  r  r  foundZ	not_foundr_   ry  r  rR   rm  rH   rH   rI   action_attach  s    
     
  
r  c                K   s   | j pt}t z}t|| z*t|d}|j|dd W 5 Q R X W n< t	k
r } zt
| W Y W 5 Q R  dS d }~X Y nX W 5 Q R X dS )Nzw:gzzlogs/)Zarcnamer%  r   )r  UA_COLLECT_LOGS_FILEtempfileZTemporaryDirectoryr   Zcollect_logstarfileopenaddPermissionErrorru  rR   )rx   ra   ry   Zoutput_fileZ
output_dirZresultsrz  rH   rH   rI   action_collect_logsC  s    


,r  c                 C   s  t }tttjtjtddtjjtdd|d}|j	ddtj
d |j	ddt tjjtd	d
 tj|j_|jtjddd}d|_|jdtjd}t| |jtd |jdtjd}t| |jtd |jdtjd}t| |jtd |jdtjd}t | |jt!d |jdtj"d}t#| |jt$d |jdtj%d}	t&|	 |	jt'd |jdtj(d}
t)|
| d |
jt*d |jdtj+d}t,|| d |jt-d t.| |jdtj/d}t0| |jt1d |jdtj2d}t3|| d |jt4d |jdtj5d}|jt6d t7| |jdtj8d}|jt9d t:| |jdtjjtd	d}|jt;d |jdtj<d}|jt=d t>| |S )Nr  r   )r?   rB   r@   rA   r>   z--debugr   r   z	--versionr   )r_   )r   r   r   r   rb   r   Tr   r   r   r   r   r   r
   r   r   r   r   r   r   r   r   r   )?__doc__r=   r&   rs   r   r'   rk   r   ZCLI_HELP_EPILOGr   ZCLI_ROOT_DEBUGr   get_versionZCLI_ROOT_VERSIONr   r   r   r   r   Zrequiredr   ZCLI_ROOT_ATTACHr   r   r  ZCLI_ROOT_APIr   r  ZCLI_ROOT_AUTO_ATTACHr   r  ZCLI_ROOT_COLLECT_LOGSr   r  ZCLI_ROOT_CONFIGr   r  ZCLI_ROOT_DETACHr   r  ZCLI_ROOT_DISABLEr   rn  ZCLI_ROOT_ENABLEr   r{  r(   ZCLI_ROOT_SECURITY_STATUSr   r   ZCLI_ROOT_HELPr   action_helpZCLI_ROOT_REFRESHaction_refreshr   ZCLI_ROOT_STATUSaction_statusr   print_versionZCLI_ROOT_SYSTEMaction_systemr   )ra   r>   r   r   Zparser_attachZ
parser_apiZparser_auto_attachZparser_collect_logsZparser_configZparser_detachZparser_disableZparser_enableZparser_security_statusZparser_helpZparser_refreshZparser_statusZparser_versionZparser_systemrH   rH   rI   r  P  s      
              r  c          
      K   s   |st  }| r| jnd}| r$| jnd }tjjj}tj	|||d\}}t
|d |k}| r| jr|r|d |krtjddd td tj	|||d\}}qdtd t| tj||d}	tt|	 t  |S )	NF)simulate_with_tokenrZ   Zexecution_statusre  rb   )endr%  rZ   )r
   rg   allr  r  ZUserFacingConfigStatusZACTIVEr   r   r   rD  waitr  r  timesleepZset_output_contentr  r   r  rj  )
rx   ra   ry   rZ   r   Zactive_valuer   r  Zconfig_activer  rH   rH   rI   r    s4    
  



r  c                K   s   t |d| jd dS )zGPerform the system action.

    :return: 0 on success, 1 otherwise
    r   r  r   r  r   rH   rH   rI   r    s      r  c                K   s   t |}t|j dS )Nr   )r"   r  r  Zreboot_requiredr  rH   rH   rI   r     s    r   c                 K   s   t t  d S r   )r   r   r  )_argsra   ry   rH   rH   rI   r    s    r  c              
   C   sP   z|   W n4 tk
r@ } zt| t W 5 d }~X Y nX ttj d S r   )	Zprocess_configRuntimeErrorru  	exceptionr   ZRefreshConfigFailurer   r   ZREFRESH_CONFIG_SUCCESS)rx   ra   excrH   rH   rI   _action_refresh_config  s    
r  c              
   C   sT   zt | W n6 tjk
rD } zt| t W 5 d }~X Y nX ttj	 d S r   )
r   r   r   rs  ru  r  ZRefreshContractFailurer   r   ZREFRESH_CONTRACT_SUCCESSr  ra   r  rH   rH   rI   _action_refresh_contract  s    
r  c              
   C   sf   z"t | t  |jr t| W n4 tk
rV } zt| t W 5 d }~X Y nX t	t
j d S r   )r8   r7   r	   rM  	Exceptionru  r  r   ZRefreshMessagesFailurer   r   ZREFRESH_MESSAGES_SUCCESSr  rH   rH   rI   _action_refresh_messages   s    
r  zpro refreshc                K   sj   | j d ks| j dkrt| | | j d ks2| j dkrHt| | ttj | j d ks\| j dkrft| | dS )Nr
   r   r   r   )r   r  r  r3   remover5   ZCONTRACT_REFRESH_WARNINGr  r   rH   rH   rI   r    s    


r  )ra   scoperP  rQ  r^   c                 C   sR   |t jkr| j}| j}n|t jkr.| j}| j}d|kr<|}n|}t|||d dS )zS
    Handles setting part the apt proxies - global and uaclient scoped proxies
    r3  )r0  r1  Zproxy_scopeN)r$   rJ  r'  r(  rF  r)  r*  r%   )ra   r  rP  rQ  r0  r1  rH   rH   rI   rE     s    	

  rE  c                K   s   | j }| j}|s&t|dj|d dS |s2t }t||}| jdkrXt	t
| n&| D ]\}}t	d| | q`dS )Nr   r  r   r;   z{}:
{}
)r   r  r  rY   r
   rg   r  r   rk   r   r;   r   itemsr   )rx   ra   ry   r   rZ   Zhelp_responser   r   rH   rH   rI   r  8  s    
r  c                 C   sX   | r| j dkst| dddkr"d S t }|rTtd| tjtj	j
|dtjd d S )Nr   rk   rb   r;   r<   zNew version available: %s)r   r  )r   r   r   Zcheck_for_new_versionru  rv  r  r  r   ZWARN_NEW_VERSION_AVAILABLE_CLIrk   rM   rN   )r   Znew_versionrH   rH   rI   _warn_about_new_versionN  s     r  c                 C   sV   | j dkrRtj sRt| dr,| jdkr,dS td tj	t
jj| j dtjd dS )z4Warn users that the user readable output may change.)r   r   rk   r  Nz.Not in a tty and human-readable command calledr   r  )r   rM   stdoutisattyhasattrrk   ru  rv  r  r  r   ZWARNING_HUMAN_READABLE_OUTPUTrN   r   rH   rH   rI   _warn_about_output_redirectiond  s    
r  c                 C   s   |dkrt  }|j}t s&t }t| tr8| 	 } |sFt
d}||  |t  g |_t|}| s|jjddd |jdd t
|}|t  ||  |d || dS )zSetup console logging and debug logging to log_file

    It configures the pro client logger.
    If run as non_root and cfg.log_file is provided, it is replaced
    with another non-root log file.
    N	ubuntuproT)parentsexist_oki  )r  z	upro-file)r
   rg   log_filer   r   pro_logZget_user_log_filer  rt   upperlogging	getLoggersetLevelZ	addFilterZRedactionFilterZhandlerspathlibPathexistsparentmkdirZtouchZFileHandlerZsetFormatterr6   Zset_name
addHandler)	log_levelr  Zloggerra   Zlog_file_pathZfile_handlerrH   rH   rI   setup_loggingu  s*    






r  c                 C   sT   | j dkrPt| j  t| drP| jdkr8ttjj | jdkrPttjj	 dS )z3Set the right event mode based on the args provided)r   r   r   r   r   rk   r;   r<   N)
r   r  Zset_commandr  rk   set_event_moder   r  ZJSONZYAMLr  rH   rH   rI   r    s    



r  c                    s    fdd}|S )Nc               
      s  z | |W S  t k
rN   td ttjtjd t	  t
d Y nr tjk
r& } zdt|krtj}tdrtj}|j|jd}tj|j|jd tj|jtjd n<tjd	|j|d
 tj}tj|j|jd tj|jtjd t	  t  t  t
d W 5 d }~X Y n tjk
r } zntj}tdrRtj}|j|jd}tj|j|jd tj|jtjd t	  t  t  t
d W 5 d }~X Y n
 tjk
rD } znt|j tj|j|j|jd tjd|jtjd t |tj!st	  t  t  t
|j" W 5 d }~X Y n| t#k
r } z\td t	  tjtj$jtjd tjt%|dt|dd t  t  t
d W 5 d }~X Y nX d S )NKeyboardInterruptrS   r%  ZCERTIFICATE_VERIFY_FAILEDzca-certificates)rc   r  )Zinfo_msgr  zFailed to access URL: %sro  )r  r  additional_infoz{}z&Unhandled exception, please file a bugr  r  )r  Z
error_type)&r  ru  rR   r   r   ZCLI_INTERRUPT_RECEIVEDrM   rN   r   Zclear_lock_file_if_presentrP   r   rs  rt   Z&SSL_VERIFICATION_ERROR_CA_CERTIFICATESr   Zis_installedZ%SSL_VERIFICATION_ERROR_OPENSSL_CONFIGrk   rc   r  r  r_   r  r  ZE_CONNECTIVITY_ERRORrj  r  ZPycurlCACertificatesErrorrt  rx  r  r  ZLockHeldErrorZ	exit_coder  ZUNEXPECTED_ERRORr   )rx   ry   r  Ztmplr  rz  funcrH   rI   r     s    

  
  z#main_error_handler.<locals>.wrapperrH   )r  r   rH   r  rI   main_error_handler  s    Lr  c                 C   sh  t tjd tjd  t }t |j|j | s6tj} t	|d}| dd  }|sl|
  ttj td d|kr|d}|d | }||d d  }n|}g }|j|d}|jrttj}|tj td| t| |j}	|j}
tj|	|
d td	|   |  d
d t t!" # D }|rDtd|  t$| |j%|||d}t&| |S )Nr  r  r   r%  z--)rx   r  r/  zExecuted with sys.argv: %rc                 S   s   g | ]\}}d  ||qS )z{}={})rk   )r"  kvrH   rH   rI   r$  !  s   zmain.<locals>.<listcomp>z'Executed with environment variables: %r)ra   rq  )'r  r   ZCONFIG_DEFAULTSr
   rg   r  r  rM   argvr  rL   r   r   rO   rP   index
parse_argsdebugr  ZStreamHandlerrN   r  DEBUGr  r  r  r0  r1  r   Zconfigure_web_proxyru  Zwarn_about_invalid_keysrV   r   Zget_pro_environmentr  r  r   r  )Zsys_argvra   r   Zcli_argumentsZdouble_dash_indexZpro_cli_argsrq  rx   Zconsole_handlerr0  r1  Zpro_environmentZreturn_valuerH   rH   rI   main  sP    



r  __main__)N)N)NN)N)NN)N)r  rs   r;   r  r  rM   r  r  rl   r  	functoolsr   typingr   r   r   Zuaclientr   r   r	   r
   r   r   r   r   r   r   r   r   r   r  r   r   r   r  r   r   r   Zuaclient.api.apir   Z2uaclient.api.u.pro.attach.auto.full_auto_attach.v1r   r   Z+uaclient.api.u.pro.attach.magic.initiate.v1r   Z)uaclient.api.u.pro.attach.magic.revoke.v1r   r   Z'uaclient.api.u.pro.attach.magic.wait.v1r    r!   Z5uaclient.api.u.pro.security.status.reboot_required.v1r"   Z(uaclient.api.u.pro.status.is_attached.v1r#   rV  r$   r%   Zuaclient.cli.constantsr&   r'   Zuaclient.cli.fixr(   Zuaclient.data_typesr)   r*   Zuaclient.defaultsr+   Zuaclient.entitlementsr,   r-   r.   Z(uaclient.entitlements.entitlement_statusr/   r0   r1   r2   Zuaclient.filesr3   r4   Zuaclient.files.noticesr5   Zuaclient.logr6   Zuaclient.timer.update_messagingr7   r8   Zuaclient.yamlr9   r:   ZUA_AUTH_TOKEN_URLr   r  Zget_event_loggerr  r  Zreplace_top_level_logger_namerp   ru  ArgumentParserr=   r   r   r   r   r   r   r   r   rt   r   r   r   r   r   r   r   r   r   rg   r   r   r   r   r   r   r  r  r  r   r   r   r_  rn  r{  rK  r  rD  r|  r  r  r  r  r  r  r  r  r  r   r  r  r  r  r  rE  r  r  r  r  r  r  r  rP   rH   rH   rH   rI   <module>   s  8
^

	 &.($  &
w
.1Q)	!Ek
		
%P;
