U
    2d]                    @   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
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!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/m0Z0m1Z1 ddl2m3Z3m4Z4 ddl5m6Z6 ddl7m8Z8 ddl9m:Z:m;Z; ddl<m=Z=m>Z> ddl?m@Z@ ddlAmBZBmCZCmDZD ddlEmFZFmGZGmHZHmIZI ddlJmKZKmLZL ddlMmNZN ddlOmPZP ddlQmRZRmSZS ddlTmUZUmVZV dZWdZXdZYdZZdZ[d Z\d!d"d#gZ]d$Z^d%e j_ d& Z`ea Zbece&deeZfG d'd( d(ejgZhdd)d*Zid+d, Zjd-d. Zkdd/d0Zld1d2 Zmd3d4 Znd5d6 Zod7d8 Zpeqd9d:d;Zreqd9d<d=Zseqd9d>d?Ztd@dA ZudBdC ZvdDdE ZwdFdG ZxdHdI ZydJdK ZzdLdM Z{dNdO Z|ej}dPdQdRZ~ej}dPdSdTZej}dPdUdVZdWdX ZdYdZ Zd[d\ Zej}eqeqd]d^d_Zd`dadbdcZddde Zdfdg Zejdhdi Zejdjdk Zdldm Zekejeleeidndodp Zekejeleeidqdrds Zekejel eidtedudvdwZej}eedxdydzZej}dd{d|d}Zd~d Zejej}ed{ddZdd Zemejeiddd Zej}dPddZej}dPddZej}dPddZdd Zej}dPddZdddZej}dPddZel ej}dPddZej}dPddZejeidej}dPddZej}e:eqeeq ddddZdd ZddduddZdduddZdddZdd Zdd ZedddZeedk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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)AttachActionsConfigFileIncorrectTypeError)PRINT_WRAP_WIDTH),create_enable_entitlements_not_found_messageentitlements_disable_orderget_valid_entitlement_names)ApplicationStatusCanDisableFailureCanEnableFailureCanEnableFailureReason)noticesstate_files)Notice)JsonArrayFormatter)refresh_motdupdate_motd_messages)	safe_dump	safe_loadproz{name} {command} [flags]zAUse {name} {command} --help for more information about a command.z&Try 'pro --help' for more information.z}Account: {account}
Subscription: {subscription}
Valid until: {contract_expiry}
Technical support level: {tech_support_level}
z$https://auth.contracts.canonical.comZtabularjsonyamlzua_logs.tar.gz
z A new version is available: {version}
Please run:
    sudo apt-get install ubuntu-advantage-tools
to get the latest version with new features and bug fixes.c                       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__ ./usr/lib/python3/dist-packages/uaclient/cli.pyrD   k   s    zUAArgumentParser.__init__c                 C   s,   |  tj |dkrt}| d|d  d S )Nz&the following arguments are required:    r<   )print_usagesysstderrTRY_HELPexit)rE   messagerH   rH   rI   error|   s    zUAArgumentParser.errorFc                    sf   | j rTt \}}t|}|r*t|| }d| j g| | _|  jdtjj 7  _t	 j
|d d S )Nr<   

file)r>   r=   _get_service_descriptionssortedjoindescriptionr   ZPRO_HELP_SERVICE_INFOmsgrC   
print_help)rE   rT   show_allnon_beta_services_descbeta_services_descZservice_descriptionsrF   rH   rI   rZ      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)widthsubsequent_indentbreak_long_wordsbreak_on_hyphens)r
   UAConfigr   Zget_available_resourcesr   entitlement_factoryr   EntitlementNotFoundErrorgetZhelp_doc_urlformattextwrapfillrX   r)   Zis_betaappend)
rb   Zservice_info_tmplr\   r]   Z	resourcesresourceent_clsZpresentation_namerd   Zservice_inforH   rH   rI   rU      s@     

z*UAArgumentParser._get_service_descriptions)NF)__name__
__module____qualname__argparseZHelpFormatterr   strrD   rQ   rZ   staticmethodr   r   rU   __classcell__rH   rH   rF   rI   r=   j   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)rb   lock_holderrb   )r   ZSingleAttemptLock)rb   argskwargsZretval)frz   rH   rI   new_f   s    z0assert_lock_file.<locals>.wrapper.<locals>.new_fr   r}   r~   rz   r}   rI   wrapper   s    z!assert_lock_file.<locals>.wrapperrH   )rz   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)r{   r|   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                    sR   | s | f||S | j dkr>| js>tj}tj|j|jdn | f||S d S )Nr:   rY   msg_code)rm   
assume_yesr   ZJSON_FORMAT_REQUIRE_ASSUME_YESr   UserFacingErrorrY   r`   )cmd_argsr{   r|   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                    s`   t |jsLr@t| dd}t| dd}|||d}t|}nt }| | fd|i|S )Ncommandrc   service)r   service_namesrb   rb   )r$   is_attachedgetattrr   ZUnattachedError)r{   rb   r|   r   r   rY   	exception)r}   msg_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                    s4   t |jr t|jjdd | fd|i|S )Nr`   rc   rb   )r$   r   r   ZAlreadyAttachedErrormachine_token_fileZaccountrl   r{   rb   r|   r   rH   rI   r~     s
    
z"assert_not_attached.<locals>.new_fr   r   rH   r   rI   assert_not_attached  s    r   c                 C   sF   d| _ d| _| jdddd | jddg d	d
d | jddddd | S )z5Build or extend an arg parser for the api subcommand.apiCalls the Client API endpoints.endpoint_pathZendpointzAPI endpoint to call)metavarhelpz--argsoptions*z;Options to pass to the API endpoint, formatted as key=value)destdefaultnargsr   z--datadatarc   z,arguments in JSON format to the API endpoint)r   r   r   )r?   rX   add_argumentparserrH   rH   rI   
api_parser  s*      r   c                 C   s*   d| _ d| _tjt| j d| _d| j_| S )z9Build or extend an arg parser for auto-attach subcommand.auto-attachz5Automatically attach on an Ubuntu Pro cloud instance.r`   r   Flags)r?   rX   
USAGE_TMPLrm   NAMEr@   
_optionalstitler   rH   rH   rI   auto_attach_parser5  s    r   c                 C   s2   d| _ d| _tjt| j d| _| jdddd | S )z<Build or extend an arg parser for 'collect-logs' subcommand.collect-logsz<Collect logs and relevant system information into a tarball.r   z-oz--outputzEtarball where the logs will be stored. (Defaults to ./ua_logs.tar.gz)r   )r?   rX   r   rm   r   r@   r   r   rH   rH   rI   collect_logs_parser@  s    r   parent_commandc                 C   s6   t jtd|d| _d| _d| _| jdddd | S )	z;Build or extend an arg parser for 'config show' subcommand.z{} show [key]r   showz(Show customisable configuration settingskey?z6Optional key or key(s) to show configuration settings.r   r   )r   rm   r   r@   r?   rX   r   r   r   rH   rH   rI   config_show_parserR  s     r   c                 C   sJ   t jtd|d| _d| _d| _d| j_| jddd	t
jd	 | S )
z:Build or extend an arg parser for 'config set' subcommand.z{} set <key>=<value>r   Zasetz/Set and apply Ubuntu Pro configuration settingsr   key_value_pairzKkey=value pair to configure for Ubuntu Pro services. Key must be one of: {}, r   )r   rm   r   r@   r?   rX   r   r   r   rW   r
   UA_CONFIGURABLE_KEYSr   rH   rH   rI   config_set_parsera  s     
	r   c                 C   sL   t jtd|d| _d| _d| _| jdddtj	dd d	| j
_| S )
z<Build or extend an arg parser for 'config unset' subcommand.z{} unset <key>r   unsetz&Unset Ubuntu Pro configuration settingr   z?configuration key to unset from Ubuntu Pro services. One of: {}r   )r   r   r   )r   rm   r   r@   r?   rX   r   rW   r
   r   r   r   r   rH   rH   rI   config_unset_parseru  s     
r   c                 C   s   d}t jtd|d| _|| _d| _d| j_| jdddd	}|j	d
dd}|j
td t||d |j	ddd}|j
td t||d |j	ddd}|j
td t||d | S )z4Build or extend an arg parser for config subcommand.r
   z{} <command>r   zManage Ubuntu Pro configurationr   Available Commandsr   rc   r   r   r   r   z,show all Ubuntu Pro configuration setting(s)r   actionr   setz$set Ubuntu Pro configuration settingr   z&unset Ubuntu Pro configuration setting)r   rm   r   r@   r?   rX   r   r   add_subparsers
add_parserset_defaultsaction_config_showr   action_config_setr   action_config_unsetr   )r   r   
subparsersZparser_showZ
parser_setZparser_unsetrH   rH   rI   config_parser  s@          r   c                 C   s   t jtdd| _tj| _d| _dtj	}|d d | _
d| j_| jdd	d
td | jddddd | jdtddd | jddddgddd | S )z4Build or extend an arg parser for attach subcommand.zattach <token>r   attachz@Attach this machine to Ubuntu Pro with a token obtained from:
{}rR   zWhen running this command without a token, it will generate a short code
and prompt you to attach the machine to your Ubuntu Pro account using
a web browser.r   tokenr   z0token obtained for Ubuntu Pro authentication: {}r   z--no-auto-enableZstore_falseauto_enablez4do not enable any recommended services automatically)r   r   r   z--attach-configrzKuse the provided attach config file instead of passing the token on the cli)typer   --formatstoreclir:   4output enable in the specified format (default: cli)r   choicesr   r   )r   rm   r   r@   rv   RawDescriptionHelpFormatterrB   r?   r   BASE_UA_URLrX   r   r   r   UA_AUTH_TOKEN_URLZFileType)r   r>   rH   rH   rI   attach_parser  sP    	r   c                 C   sV   t jtdd| _d| _d| _d| j_| jddd | jd	d
dd | jdd
dd | S )z1Build or extend an arg parser for fix subcommand.z"fix <CVE-yyyy-nnnn+>|<USN-nnnn-d+>r   fixzLInspect and resolve CVEs and USNs (Ubuntu Security Notices) on this machine.r   security_issuezwSecurity vulnerability ID to inspect and resolve on this system. Format: CVE-yyyy-nnnn, CVE-yyyy-nnnnnnn or USN-nnnn-ddr   z	--dry-run
store_truezrIf used, fix will not actually run but will display everything that will happen on the machine during the command.r   r   z--no-relatedz`If used, when fixing a USN, the command will not try to also fix related USNs to the target USN.	r   rm   r   r@   r?   rX   r   r   r   r   rH   rH   rI   
fix_parser  s.     		r   c                 C   sx   d| _ tj| _td| _| jddddd |  }|jdd	d
d |jddd
d |jddd
d |jddd
d | S )z=Build or extend an arg parser for security-status subcommand.security-statusa]          Show security updates for packages in the system, including all
        available Expanded Security Maintenance (ESM) related content.

        Shows counts of how many packages are supported for security updates
        in the system.

        If called with --format json|yaml it shows a summary of the
        installed packages based on the origin:
        - main/restricted/universe/multiverse: packages from the Ubuntu archive
        - esm-infra/esm-apps: packages from the ESM archive
        - third-party: packages installed from non-Ubuntu sources
        - unknown: packages which don't have an installation source (like local
          deb packages or packages for which the source was removed)

        The output contains basic information about Ubuntu Pro. For a
        complete status on Ubuntu Pro services, run 'pro status'.
        r   zFormat for the output)r:   r;   textr   )r   r   r   z--thirdpartyz7List and present information about third-party packagesr   )r   r   z--unavailablez7List and present information about unavailable packagesz--esm-infraz5List and present information about esm-infra packagesz
--esm-appsz4List and present information about esm-apps packages)	r?   rv   r   rB   rn   dedentrX   r   Zadd_mutually_exclusive_group)r   grouprH   rH   rI   security_status_parser  sB    r   c                 C   sV   d| _ d| _tjtdd| _d| j_tj	| _
td| _| jddd	d
gdddd | S )z5Build or extend an arg parser for refresh subcommand.refreshz9Refresh existing Ubuntu Pro contract and update services.z"refresh [contract|config|messages]r   r   a          Refresh three distinct Ubuntu Pro related artifacts in the system:

        * contract: Update contract details from the server.
        * config:   Reload the config file.
        * messages: Update APT and MOTD messages related to UA.

        You can individually target any of the three specific actions,
        by passing it's target to nome to the command.  If no `target`
        is specified, all targets are refreshed.
        targetr   r
   r   r   NzTarget to refresh.)r   r   r   r   )r?   rX   r   rm   r   r@   r   r   rv   r   rB   rn   r   r   r   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   )rm   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DatetimeAwareJSONEncoderr7   r   rH   rH   rI   action_security_status]  s2    



r   c                K   sD   t tj| js&d| j}t|tj|| j| j	| j
d}|jS )NzYError: issue "{}" is not recognized.
Usage: "pro fix CVE-yyyy-nnnn" or "pro fix USN-nnnn")rb   Zissue_iddry_run
no_related)rematchr   ZCVE_OR_USN_REGEXr   rm   r   r   Zfix_security_issue_idr   r   	exit_code)r{   rb   r|   rY   Z
fix_statusrH   rH   rI   
action_fix{  s    
r   c                 C   sT   t jtdd}|| _d| _d| _d| j_| jdddd | jd	d
ddgddd | S )z4Build or extend an arg parser for detach subcommand.detachr   z-Detach this machine from Ubuntu Pro services.r   --assume-yesr   z;do not prompt for confirmation before performing the detachr   r   r   r   r:   r   r   r   r   r@   rH   rH   rI   detach_parser  s$    r   rb   c                 C   s   t jtdd}|| _d| _d| _d| j_| jdddd	d
	t
j|dd | jddttd dtd d | jdddd | S )z2Build or extend an arg parser for help subcommand.zhelp [service]r   r   z7Provide detailed information about Ubuntu Pro services.	Argumentsr   r   r   z-a service to view help output for. One of: {}r   r   r   r   r   r   r   z1output help in the specified format (default: {})r   --allr   (Allow the visualization of beta servicesr   )r   rm   r   r@   r?   rX   _positionalsr   r   rW   r   valid_servicesSTATUS_FORMATSr   rb   r@   rH   rH   rI   help_parser  s:    	r  c                 C   s   t jtdd}d| _|| _d| _d| j_d| j_| j	ddd	d
d
tj|dd | j	dddd | j	dddd | j	dddd | j	ddddgddd | j	dddd | S )z4Build or extend an arg parser for enable subcommand.zenable <service> [<service>]r   zEnable an Ubuntu Pro service.enabler   r   r   r   +z<the name(s) of the Ubuntu Pro services to enable. One of: {}r   r   r   r   r   z;do not prompt for confirmation before performing the enabler   --access-onlyzHdo not auto-install packages. Valid for cc-eal, cis and realtime-kernel.z--betaz allow beta service to be enabledr   r   r:   r   r   	--variantz8The name of the variant to use when enabling the servicer   rm   r   rX   r@   r?   r   r   r   r   rW   r   r   r  rH   rH   rI   enable_parser  sZ       r  c                 C   s   t jtdd}d| _|| _d| _d| j_d| j_| j	ddd	d
d
tj|dd | j	dddd | j	ddddgddd | S )z5Build or extend an arg parser for disable subcommand.zdisable <service> [<service>]r   zDisable an Ubuntu Pro service.disabler   r   r   r   r  z=the name(s) of the Ubuntu Pro services to disable. One of: {}r   r   r   r   r   z<do not prompt for confirmation before performing the disabler   r   r   r:   z5output disable in the specified format (default: cli)r   r  r  rH   rH   rI   disable_parser  s<     r
  c                 C   sZ   t jtdd| _d| _d| _d| j_| jdddd	}|j	d
dd}|j
td t| | S )z4Build or extend an arg parser for system subcommand.zsystem <command>r   z9Output system related information related to Pro servicessystemr   r   r   rc   r   reboot-requiredz#does the system need to be rebootedr   r   )r   rm   r   r@   rX   r?   r   r   r   r   r   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	d| _
| S )Nzsystem reboot-requiredr   r  al          Report the current reboot-required status for the machine.

        This command will output one of the three following states
        for the machine regarding reboot:

        * no: The machine doesn't require a reboot
        * yes: The machine requires a reboot
        * yes-kernel-livepatches-applied: There are only kernel related
          packages that require a reboot, but Livepatch has already provided
          patches for the current running kernel. The machine still needs a
          reboot, but you can assess if the reboot can be performed in the
          nearest maintenance window.
        )r   rm   r   r@   r9   rv   r   rB   rn   r   rX   r   rH   rH   rI   r  5  s     r  c              	   C   s   t jtdd}|| _d| _d| _tj| _t	
d| _| jddddd	 | jd
dttd dtd d | jddddd | jdddd d| j_| S )z4Build or extend an arg parser for status subcommand.r   r   z6Output the status information for Ubuntu Pro services.u;          Report current status of Ubuntu Pro services on system.

        This shows whether this machine is attached to an Ubuntu Advantage
        support contract. When attached, the report includes the specific
        support contract details including contract name, expiry dates, and the
        status of each service on this system.

        The attached status output has four columns:

        * SERVICE: name of the service
        * ENTITLED: whether the contract to which this machine is attached
          entitles use of this service. Possible values are: yes or no
        * STATUS: whether the service is enabled on this machine. Possible
          values are: enabled, disabled, n/a (if your contract entitles
          you to the service, but it isn't available for this machine) or — (if
          you aren't entitled to this service)
        * DESCRIPTION: a brief description of the service

        The unattached status output instead has three columns. SERVICE
        and DESCRIPTION are the same as above, and there is the addition
        of:

        * AVAILABLE: whether this service would be available if this machine
          were attached. The possible values are yes or no.

        If --simulate-with-token is used, then the output has five
        columns. SERVICE, AVAILABLE, ENTITLED and DESCRIPTION are the same
        as mentioned above, and AUTO_ENABLED shows whether the service is set
        to be enabled when that token is attached.

        If the --all flag is set, beta and unavailable services are also
        listed in the output.
        z--waitr   Fz Block waiting on pro to complete)r   r   r   r   r   r   z3output status in the specified format (default: {})r   z--simulate-with-tokenZTOKENz1simulate the output status using a provided token)r   r   r   r   r   r   r   )r   rm   r   r@   rX   r?   rv   r   rB   rn   r   r   r   r   r   r   rH   rH   rI   status_parserO  sJ    %r  )rb   cmd_namesubcmd_namec                 C   sf   t | d}| d j| }| d j }||krb| d j|   tdd|d S )Nr   r   z
<command> must be one of: {}r   )	
get_parser_get_positional_actionsr   keysrZ   r   r   rm   rW   )rb   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`   
isinstancer.   rP   inforY   rQ   service_processed	ua_statusr   )entitlementrb   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rPd| j dtj}|dd }ttj	|t
d| 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d dS )zPerform the 'config show' action optionally limit output to a single key

    :return: 0 on success
    :raise UserFacingError: on invalid keys
    z
'{}' must be one of: {}r   :rJ    )re   rf   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}zo
Error: Setting global apt proxy and pro scoped apt proxy at the same time is unsupported. No apt proxy is set.)r   r
   r   rm   rW   findr   r   rn   ro   r)   r   r   rw   maxglobal_apt_http_proxyglobal_apt_https_proxyua_apt_http_proxyua_apt_https_proxy)r{   rb   r|   rY   Zindent_positionZ	col_widthZrow_tmplr   rH   rH   rI   r     sB     
 
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d| jY nX |tjkr|
  td	d
tj|dkr4|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|_ nV||j'|j( krzd|krdnd}
|
dkrtj}ntj}||j'kr"t!t"j)j|
d d| }t|
|	| t|j*p>|j+}|r\t!t"j#jddd t$|t%j,||	 d|_*d|_+n|dkrz$t-|	}	|	dk rt	d|W n8 t	k
r   |
  t!d td||	Y nX n2|dkr|	. dk}	|	rt/0| n
t1j23  t4|||	 dS )zMPerform the 'config set' action.

    @return: 0 on success, 1 otherwise
    r   )configure_livepatch_proxy)configure_snap_proxyr   r
   r   =z%
Expected <key>=<value> but found: {}
<key> must be one of: {}r   
http_proxyhttps_proxy_r   rJ   zpro scoped aptz
global apt)Zcurrent_proxyZprevious_proxyNhttpsprotocol_typeglobal_)Zupdate_messaging_timerZmetering_timerzInvalid interval for {}rc   zECannot set {} to {}: <value> for interval must be a positive integer.r	   true)5uaclient.livepatchr8  uaclient.snapr9  r  r  r   r   split
ValueErrorrZ   r   r   rm   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boolr4  r5  r   r   ZWARNING_APT_PROXY_OVERWRITEconfigure_apt_proxyr%   UACLIENT&deprecated_global_scoped_proxy_optionsglobal_scoped_proxy_optionsWARNING_APT_PROXY_SETUPr6  r7  GLOBALintlowerr	   update_apt_newsr2   Zapt_news_contents_filedeletesetattr)r{   rb   r|   r8  r9  r   r   r  set_key	set_valuerB  Zvalidate_urlr"  livepatch_statusr?  Zunset_currentrH   rH   rI   r     s    






 

 

 

r   c                K   sj  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dd	tj| jd
kr| jdd }	||	d tj|}
|
 \}}|tjkr||	d n| j|jkrt||j| jd nh| j|j|j krX| j|jkrFd| jkr"dnd}	ttj j|	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?  rA  Nr@  r   rC  )#uaclient.aptr%   rE  r]  rF  r^  r   r
   r   r  r  r   rZ   r   r   rm   rW   rG  r   rI  rJ  rK  r-   rL  rM  rO  rP  rQ  rR  r  r  r   rS  rT  rY  )r{   rb   r|   r%   r]  r^  r   r   r  rB  r"  r\  r?  rH   rH   rI   r     sL    




r   c                 C   s|   t ||d\}}|r>|r>tj}|jd|| d|dd}n:|rXtjjd|d}n tjj| d|dtjd}|S )zGenerates a custom message for enable/disable commands when unattached.

    Takes into consideration if the services exist or not, and notify the user
    accordingly.)namesrb   r   rc   )valid_service	operationinvalid_serviceservice_msg)ra  zSee {}rb  rc  rd  )	r,   r   Z!MIXED_SERVICES_FAILURE_UNATTACHEDrm   rW   Z VALID_SERVICE_FAILURE_UNATTACHEDZINVALID_SERVICE_OP_FAILUREr   r   )r   r   rb   entitlements_foundentitlements_not_foundrY   rH   rH   rI   %_create_enable_disable_unattached_msg  s,     

rh  zpro disablec                K   s   t | dg }t||\}}d}|D ]4}tj||d}||| 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   Tra   r   zTry r   rb   
allow_beta.r<   P   F)re   rg   rh   r	  re  r   r1  )r   r,   r   rj   r   r&  rW   r   rn   Zwrapr   ZInvalidServiceToDisableErrorr   UAContractClientupdate_activity_tokenr  process_events)r{   rb   r|   r`  rf  rg  r$  ent_namerr   entZvalid_namesrd  contract_clientrH   rH   rI   action_disable  sD    	 
rt  z
pro enablec                K   s$  t | dd}| j}|r(|r(tjdddttj zt	| W n: tj
tjfk
r|   tjtj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 |
sB|dk	rBt|trB|jdk	r(t|jj tj|jj|jj|	d |jtj krr|!|	 n0|
rVtj"|	d n|
sr|dkrrt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%||| jd}t&| tj|j|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#  rc   r  r  )Zoption1Zoption2T)exc_info)Zwarning_msgr   
extra_args)r   rk  access_onlyr#  rv  r   Nr  )r   Frj  r   r   r1  )*r   rw  r   ZInvalidOptionCombinationr  r  r   ZREFRESH_CONTRACT_ENABLEr   r   UrlErrorr   LOGdebugREFRESH_CONTRACT_FAILUREwarningr,   r   enable_entitlement_by_namer   Zbetarl   r!  r   r  r/   rP   rY   rQ   r`   r%  r0   ZIS_BETArp   r   r  r   r*   Zservices_failedrn  ro  rp  )r{   rb   r|   r#  rw  r`  rf  rg  r$  rq  ent_retr%  erY   rs  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
    ri  r   )_detachr   r   startr   stopr  rp  )r{   rb   r|   r$  rH   rH   rI   action_detachV  s    	r  )rb   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|dkr~dnd}t	d
| |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
    ra   )rb   r   T)Zignore_dependent_servicesr1  src   z,Detach will disable the following service{}:z    {}ri  F)r   r  r   )r+   r   rj   r   rk   Zcan_disablerp   r-  r  r  rm   r`   r   Zprompt_for_confirmationr&  Zdelete_cacher   rX  r6   r   ZDETACH_SUCCESS)	rb   r   Z
to_disablerq  rr   rr  r$  r?  suffixrH   rH   rI   r  g  s4    


r  )rb   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_tokenrl   r  r  r   ZATTACH_SUCCESS_TMPLrm   ZATTACH_SUCCESS_NO_CONTRACT_NAMEr   r  Zcleanupr   r   r!  format_tabularr   handle_unicode_charactersrp  )rb   r  r   Z_retoutputrH   rH   rI   _post_cli_attach  s(     

r  c                K   sV   | j r$| jr$tj}tj|j|jdt| j	| j | j|}t
|  |jdkrRdS dS )Nr   Zsuccessr   r1  )r   r   r   Z API_ERROR_ARGS_AND_DATA_TOGETHERr   r   rY   r`   r   r   r   Zto_jsonresult)r{   rb   r|   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)rb   moder1  r   )r   r   r   EventLoggerModeZCLIr   rx  r  r  r   ZATTACH_FAILURErY   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   r<   )	user_code)Zmagic_token)r   rb   )rm   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)r{   rb   r|   Zinitiate_respZwait_optionsZ	wait_respr  Zrevoke_optionsrH   rH   rI   _magic_attach  s4    

r  z
pro attachc             
   K   s  | j r$| jr$tjtjjtjjdn| j sB| jsBt| |d}d }nj| j rT| 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\}}|sd}|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   r   )Zconfig_namerQ   )r   allow_enabler   T)r   rk  r1  r  rj  )	file_typer  r  )$r   attach_configr   r   r   ZATTACH_TOKEN_ARG_XOR_CONFIGrY   r`   r  r'   Z	from_dictr8   r(   ZAttachInvalidConfigFileErrorZenable_servicesr   r   Zattach_with_tokenrx  ZAttachErrorr,   r}  r  r/   rP   r  r  rQ   r   r*   rL   rM   r   rn  ro  r  )r{   rb   r|   r   Zenable_services_overrider  r  r  r$  foundZ	not_foundr`   r~  r%  rY   rs  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arcnamer1  r   )r  UA_COLLECT_LOGS_FILEtempfileZTemporaryDirectoryr   Zcollect_logstarfileopenaddPermissionErrorry  rQ   )r{   rb   r|   Zoutput_fileZ
output_dirZresultsr  rH   rH   rI   action_collect_logs3  s    


,r  c                 C   s  t }tttjtjtddtjtdd|d}|jdddd |jdd	t	
 d
td d|j_|jdddd}d|_|jddd}t| |jtd |jddd}t| |jtd |jddd}t| |jtd |jddd}t| |jtd |jddd}t| |jtd |jddd}	t|	 |	jtd |jd d!d}
t|
| d" |
jtd |jd#d$d}t|| d" |jt d |jd%d&d}|jt!d t"| |jd'd(d}t#| |jt$d |jd)d*d}t%|| d" |jt&d |jd+d,d}|jt'd t(| |jd-d.d}|jt)d t*| |jd	d
td}|jt+d |jd/d0d}|jt,d t-| |S )1Nz	<command>r   )r?   rB   r@   rA   r>   z--debugr   z&show all debug log messages to consoler   z	--versionr   zshow version of {})r   r   r   r   r   r   rc   r   Tr   z1attach this machine to an Ubuntu Pro subscriptionr   r   r   r   r   z+automatically attach on supported platformsr   z&collect Pro logs and debug informationr
   z/manage Ubuntu Pro configuration on this machiner   z3remove this machine from an Ubuntu Pro subscriptionr	  z5disable a specific Ubuntu Pro service on this machiner   r  z4enable a specific Ubuntu Pro service on this machiner   z=check for and mitigate the impact of a CVE/USN on this systemr   z.list available security updates for the systemr   z3show detailed information about Ubuntu Pro servicesr   zrefresh Ubuntu Pro servicesr   z)current status of all Ubuntu Pro servicesr  z/show system information related to Pro services).__doc__r=   r   rv   r   r   rm   EPILOG_TMPLr   r   get_versionr   r   r   Zrequiredr   r   r   r  r   r  r   r  r   r  r   r)  r   r  r
  rt  r  r  r   r   r   r   r  action_helpaction_refreshr   action_statusr  print_versionaction_systemr  )rb   r>   r   r   Zparser_attachZ
parser_apiZparser_auto_attachZparser_collect_logsZparser_configZparser_detachZparser_disableZparser_enableZ
parser_fixZparser_security_statusZparser_helpZparser_refreshZparser_statusZparser_versionZparser_systemrH   rH   rI   r  @  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_tokenr[   Zexecution_statusrl  rc   )endr1  r[   )r
   ri   allr  r!  ZUserFacingConfigStatusZACTIVEr,  r   r   rN  waitr  r  timesleepZset_output_contentr  r   r  rp  )
r{   rb   r|   r[   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_required)r{   rb   r|   r  rH   rH   rI   r    s    r  c                 K   s   t t  d S r   )r   r   r  )_argsrb   r|   rH   rH   rI   r    s    r  c                 C   sh   z|   W nL tk
rX } z.t  t| W 5 Q R X ttj	W 5 d }~X Y nX t
tj d S r   )Zprocess_configRuntimeErrorr   disable_log_to_consolery  r   r   r   r   ZREFRESH_CONFIG_FAILUREr   ZREFRESH_CONFIG_SUCCESS)r{   rb   excrH   rH   rI   _action_refresh_config  s    
r  c                 C   sl   zt | W nN tjk
r\ } z.t  t| W 5 Q R X tt	j
W 5 d }~X Y nX tt	j d S r   )r   r   r   rx  r   r  ry  r   r   r   r{  r   ZREFRESH_CONTRACT_SUCCESSr  rb   r  rH   rH   rI   _action_refresh_contract  s    
r  c                 C   s~   z"t | t  |jr t| W nL tk
rn } z.t  t| W 5 Q R X t	
tjW 5 d }~X Y nX ttj d S r   )r6   r5   r	   rW  	Exceptionr   r  ry  r   r   r   r   ZREFRESH_MESSAGES_FAILUREr   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  r1   remover3   ZCONTRACT_REFRESH_WARNINGr  r   rH   rH   rI   r    s    


r  )rb   scoperZ  r[  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
    r@  )r=  r>  Zproxy_scopeN)r%   rT  r4  r5  rP  r6  r7  r&   )rb   r  rZ  r[  r=  r>  rH   rH   rI   rO  %  s    	

  rO  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  rZ   r
   ri   r!  r   rm   r   r:   r   itemsr   )r{   rb   r|   r   r[   Zhelp_responser   r,  rH   rH   rI   r  =  s    
r  c                 C   sD   | r| j dkst| dddkr"d S t }|r@ttj|d d S )Nr   rm   rc   r:   r;   )r   )r   r   r   Zcheck_for_new_versionry  r|  NEW_VERSION_NOTICErm   )r   Znew_versionrH   rH   rI   _warn_about_new_versionS  s    r  c                 C   sF   | j dkrBtj sBt| dr,| jdkr,dS ttj	j| j d dS )z4Warn users that the user readable output may change.)r   r   rm   r  N)r   )
r   rL   stdoutisattyhasattrrm   ry  r|  r   ZWARNING_HUMAN_READABLE_OUTPUTr   rH   rH   rI   _warn_about_output_redirectionc  s    r  c           	      C   s  |dkrt  }|j}t s&t }t|tr8|	 }t
 }|sNtd}|| |t  g |_ttj}|| ||  |d || 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.
    NZ	ubuntuprozupro-consoleT)parentsexist_oki  )r  z	upro-file)r
   ri   log_filer   r   pro_logZget_user_log_filer  rw   upperZLogFormatterlogging	getLoggerZsetLevelZ	addFilterZRedactionFilterZhandlersZStreamHandlerrL   rM   ZsetFormatterZset_nameZ
addHandlerpathlibPathexistsparentmkdirZtouchZFileHandlerr4   )	console_level	log_levelr  Zloggerrb   Zconsole_formatterZconsole_handlerZlog_file_pathZfile_handlerrH   rH   rI   setup_loggingr  s6    










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   rm   r:   r;   N)
r   r  Zset_commandr  rm   set_event_moder   r  ZJSONZYAMLr  rH   rH   rI   r    s    



r  c                    s    fdd}|S )Nc                     s2  z | |W S  t k
r`   t  td W 5 Q R X tdtjd t	  t
d Y n tjk
rl } zdt|krtj}tdrtj}|j|jd}tj|j|jd tj|jtjd	 npt 8 |j|d
}|jrtj}ntj}t|jf | W 5 Q R X 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rt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 n2 tj k
r } zt  t|j W 5 Q R X tj|j|j!|j"d tjd|jtjd	 t#|tj$stt	  t  t  t
|j% W 5 d }~X Y n t&k
r, } zpt  td W 5 Q R X 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KeyboardInterruptzInterrupt received; exiting.rS   r1  ZCERTIFICATE_VERIFY_FAILEDzca-certificates)rd   r  )Zinfo_msgr  )rd   rQ   )r  r  additional_infoz{}z&Unhandled exception, please file a bugrY   r   )r  Z
error_type))r  r   r  ry  rQ   r   rL   rM   r   Zclear_lock_file_if_presentrO   r   rx  rw   r   Z&SSL_VERIFICATION_ERROR_CA_CERTIFICATESr   Zis_installedZ%SSL_VERIFICATION_ERROR_OPENSSL_CONFIGrm   rd   r  rY   r`   r  Z$LOG_CONNECTIVITY_ERROR_WITH_URL_TMPLZLOG_CONNECTIVITY_ERROR_TMPLr   ZCONNECTIVITY_ERRORrp  r  ZPycurlCACertificatesErrorr   r   r  r  ZLockHeldErrorr   r  ZUNEXPECTED_ERRORr   )r{   r|   r  ZtmplrY   Zmsg_argsZmsg_tmplr  funcrH   rI   r     s    




  z#main_error_handler.<locals>.wrapperrH   )r  r   rH   r  rI   main_error_handler  s    Vr  c              	   C   sh  t tjtjd tjd  | s$tj} t }t	|d}| dd  }|s`|
  tt td d|kr|d}|d | }||d d  }n|}g }|j|d}t| |j}|j}	tj||	d |j}
|jrtjntj}t ||
|j td|   t  |  W 5 Q R X d	d
 tt  D }|rDtd|  t | |j!|||d}t"| |S )Nr  r  r   r1  z--)r{   r<  zExecuted with sys.argv: %rc                 S   s   g | ]\}}d  ||qS )z{}={})rm   )r.  kvrH   rH   rI   r0  0  s   zmain.<locals>.<listcomp>z'Executed with environment variables: %r)rb   rv  )#r  r  INFOr   ZCONFIG_DEFAULTSrL   argvr
   ri   r  rK   r   rN   rO   index
parse_argsr  r=  r>  r   Zconfigure_web_proxyr  rz  DEBUGr  ry  r   r  Zwarn_about_invalid_keysrV   Zget_pro_environmentr  r  r   r  )Zsys_argvrb   r   Zcli_argumentsZdouble_dash_indexZpro_cli_argsrv  r{   r=  r>  r  r  Zpro_environmentZreturn_valuerH   rH   rI   main  sP    



r  __main__)N)N)NN)N)NN)N)r  rv   r:   r  r  r   rL   r  r  rn   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   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$   r_  r%   r&   Zuaclient.data_typesr'   r(   Zuaclient.defaultsr)   Zuaclient.entitlementsr*   r+   r,   Z(uaclient.entitlements.entitlement_statusr-   r.   r/   r0   Zuaclient.filesr1   r2   Zuaclient.files.noticesr3   Zuaclient.logr4   Zuaclient.timer.update_messagingr5   r6   Zuaclient.yamlr7   r8   r   r   r  rN   ZSTATUS_HEADER_TMPLr   r   r  Z	BLUE_INFOr  Zget_event_loggerr  r  Zreplace_top_level_logger_namers   ry  ArgumentParserr=   r   r   r   r   r   r   r   r   rw   r   r   r   r   r   r   r   r   r   r   r   ri   r  r  r
  r  r  r  r  r&  r)  r   r   r   rh  rt  r  rU  r  rN  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rO  r  r  r  r  r  r  r  rO   rH   rH   rH   rI   <module>   s  8

^

 2'9#'4$P  &)
}
/,R,
!H}



/Z9
