a ì)g5mã @sVddlmZmZmZeZddlZddlZddlZej dkrRe dd  ej   ¡¡ƒ‚dd„Zeƒdd „Zeƒdd lm Z dd lmZe d ƒZeed ƒkr¦e deƒ‚ddlZddlZddlZddlZddlmZmZddlmZz"ddlmZddl m!Z!e!ƒZ"WnBe#�yFZ$z(e%de$ej&d�e 'd¡WYdZ$[$n dZ$[$00ddlm(Z(ddl)m*Z+ddl,m-Z-m.Z.m/Z/ddl0m1Z1ddl2m3Z3ddl4m5Z5m6Z6ddl7m8Z8ddl9m:Z:ddl;mm?Z?dd l@mAZAdd!lBmCZCdd"lDmEZEdd#lFmGZGdd$lHmIZIdd%lJmKZKzddlLZLd&ZMWneN�y@d'ZMYn0Gd(d)„d)eƒZOdS)*é)Úabsolute_importÚdivisionÚprint_functionN)éé zRERROR: Ansible requires Python 3.9 or newer on the controller. Current version: %sÚc Cs†g}tjtjtjfD]L}z | ¡}Wnty:YqYn0t |¡s| t |ddƒp\d|¡q|r‚t dd  dd„|Dƒ¡ƒ‚dS)zBCheck stdin/stdout/stderr to make sure they are using blocking IO.ÚnameNz#%szbERROR: Ansible requires blocking IO on stdin/stdout/stderr. Non-blocking file handles detected: %sz, css|] }|VqdS)N©)Ú.0Ú_ior r ú8/usr/lib/python3.9/site-packages/ansible/cli/__init__.pyÚ 'óz$check_blocking_io..) ÚsysÚstdinÚstdoutÚstderrÚfilenoÚ ExceptionÚosÚ get_blockingÚappendÚgetattrÚ SystemExitÚjoin)ZhandlesZhandleÚfdr r r Úcheck_blocking_ios    ÿrc Cs–zt tjd¡t ¡\}}Wn6tjtfyT}ztd|ƒ‚WYd}~n d}~00|rf| ¡dvrrtd|ƒ‚t  ¡}| ¡dkr’td|ƒ‚dS)zmSet the locale to the users default setting and ensure the locale and filesystem encoding are UTF-8. rz|sV|rVdtjdf}| |¡|S)Nz%s@%sÚprompt_ask_vault_pass)rMÚDEFAULT_VAULT_IDENTITYr)Ú vault_idsÚvault_password_filesÚask_vault_passÚcreate_new_passwordÚ auto_promptZ password_fileZid_slugr r r Úbuild_vault_ids½s   zCLI.build_vault_idsc Cs"g}i}|pg}tjr"| tj¡|r@ddg|d<ddg|d<ndg|d<dg|d<tj|||||d �}d}} |D�]–} t | ¡\} } | d v�r| pštj} t|| | d �}z | ¡Wn8t yð}z t   d | |f¡‚WYd}~n d}~00d } | | |f¡|  |¡qtt   d| ¡zt| | |d�}WnLt �y|}z2t   d| t|ƒf¡|}WYd}~qtWYd}~n d}~00z | ¡WnLt �yÖ}z2t   d| t|ƒf¡|}WYd}~qtWYd}~n d}~00d } | �rò| | |f¡n| tj|f¡|  |¡qt|�r| �s|‚|S)Nz#New vault password (%(vault_id)s): z+Confirm new vault password (%(vault_id)s): ÚpromptzNew Vault password: zConfirm New Vault password: rezVault password (%(vault_id)s): zVault password: )rk)rmre)Úprompt_formatsraz'Error in vault password prompt (%s): %sTzReading vault password file: %s)ÚfilenameraÚloaderz*Error getting vault password file (%s): %sz-Error in vault password file loading (%s): %s)rMZDEFAULT_VAULT_PASSWORD_FILErrHrlrdrfr>Úloadr5rOrPÚset_vault_secretsZvvvvvr?r;)rprgrhrirjrkÚ vault_secretsrnZlast_exceptionZfound_vault_secretZ vault_id_slugZ vault_id_nameZvault_id_valueZbuilt_vault_idZprompted_vault_secretÚexcZfile_vault_secretr r r Úsetup_vault_secretsØsz ÿÿ   ü   ÿ  þ " "  zCLI.setup_vault_secretscCstj|d�}|rt|ƒ}|S)N)rm)ÚgetpassrF)rmÚsecretr r r Ú _get_secret?s zCLI._get_secretcCsÀtj}d}d}d}tjrdn |d ¡}z|d|}|drNt d¡}d|}n|d rdt |d ¡}|d rŒt |¡}|dr¢|dkr¢|}n|d r¢t |d ¡}Wnty¶Yn0||fS) z6 prompt for connection and become passwords if needed NrZBECOMEZ become_methodz %s password: Zask_passzSSH password: z'%s password[defaults to SSH password]: Zconnection_password_fileZbecome_ask_passZbecome_password_file) r3ÚCLIARGSrMZAGNOSTIC_BECOME_PROMPTÚupperrHrxÚget_password_from_fileÚEOFError)ÚopZsshpassZ becomepassZ become_promptZbecome_prompt_methodr r r Ú ask_passwordsGs*    zCLI.ask_passwordscCs|r|jdkr|j d¡|S)z check for conflicting options rSz.The number of processes (--forks) must be >= 1)ZforksrKÚerror)rQr}Z runas_optsZ fork_optsr r r Úvalidate_conflictsfs  zCLI.validate_conflictsrcCstj|j|||d�|_dS)a_ Create an options parser for most ansible scripts Subclasses need to implement this method. They will usually call the base class's init_parser to create a basic version and then add their own options on top of that. An implementation will look something like this:: def init_parser(self): super(MyCLI, self).init_parser(usage="My Ansible CLI", inventory_opts=True) ansible.arguments.option_helpers.add_runas_options(self.parser) self.parser.add_option('--my-option', dest='my_option', action='store') )ÚusageÚdescÚepilogN)rXZcreate_base_parserrrK)rQr�r‚rƒr r r Ú init_parseroszCLI.init_parsercCsøt|dƒr|jsdg|_t|dƒrb|jrbtƒ}|jD]"}| d¡D]}| | ¡¡qBq4t|ƒ|_t|dƒr¬|jr¬tƒ}|jD]"}| d¡D]}| | ¡¡qŒq~t|ƒ|_t|dƒrô|jsô|j rìt |j t ƒrØ|j g|_ dd„|j Dƒ|_ nt j |_ |S)a Process the command line args Subclasses need to implement this method. This method validates and transforms the command line arguments. It can be used to check whether conflicting values were given, whether filenames exist, etc. An implementation will look something like this:: def post_process_args(self, options): options = super(MyCLI, self).post_process_args(options) if options.addition and options.subtraction: raise AnsibleOptionsError('Only one of --addition and --subtraction can be specified') if isinstance(options.listofhosts, string_types): options.listofhosts = string_types.split(',') return options ÚtagsÚallú,Ú skip_tagsÚ inventorycSs$g|]}d|vrt|dd�n|‘qS)r‡F)ÚfollowrD)r Úoptr r r Ú ³rz)CLI.post_process_args..)Úhasattrr…Úsetr_ÚaddÚstripÚlistrˆÚSKIP_INVENTORY_DEFAULTSr‰Ú isinstancer9rMZDEFAULT_HOST_LIST)rQÚoptionsr…Ztag_setÚtagrˆr r r Úpost_process_args€s*      zCLI.post_process_argsc Cs–| ¡trt |j¡z|j |jdd…¡}WnJty|}z2|jdkrf|jj dd|j  ¡d�‚WYd}~n d}~00|  |¡}t   |¡dS)a‹Parse the command line args This method parses the command line arguments. It uses the parser stored in the self.parser attribute and saves the args and options in context.CLIARGS. Subclasses need to implement two helper methods, init_parser() and post_process_args() which are called from this function before and after parsing the arguments. rSNréz %s)ÚstatusÚmessage)r„ÚHAS_ARGCOMPLETEÚ argcompleteZ autocompleterKÚ parse_argsrJrÚcodeÚexitÚ format_helpr–r3Z_init_global_context)rQr”Úexr r r rW¹s    z CLI.parsec CsÀ|rt ¡}nt}| ¡d}| d¡}tt|ƒƒD]@}||dkrLd||<zt||ƒ||<Wq4tyrYq40q4t|ƒdkr tt|ƒdƒD]}| d¡q�|  ¡||d|d|ddœS)z" return full ansible version info rÚ.rrrSr—)ÚstringZfullÚmajorÚminorZrevision) rXr*rAr_ÚrangeÚlenÚintrrr�)ÚgitinfoZansible_version_stringZansible_versionZansible_versionsZcounterr r r Ú version_infoÑs*       üzCLI.version_infocCsštj ¡stj|dd�n|dtjvrRtjdkr>tj|dd�q–t |tjd¡nDt j ddt j t j d�}|  ¡|j dkrˆt |d¡ntj|dd�d S) z% find reasonable way to display text T)Z screen_onlyÚPAGERÚwin32zless --version)ÚshellrrrrIN)rrÚisattyrOrÚenvironÚplatformrHÚ pager_pipeÚ subprocessÚPopenÚPIPEÚ communicateÚ returncode)ÚtextÚpr r r Úpagerës    z CLI.pagercCshdtjvrtjtjd<z*tj|dtjtjd�}|j t |ƒd�Wn"t yRYnt ybYn0dS)z pipe text through a pager ÚLESST)r¬rr)ÚinputN) rr®rHÚ LESS_OPTSr±r²r³rrr´r:ÚIOErrorÚKeyboardInterrupt)r¶Úcmdr r r r°þs    zCLI.pager_pipec CsÔtj}tƒ}| dd¡}|rV| |¡t|ƒ|t_t|ƒ}|rVt   d  |¡¡|t_ t |dƒ}tj}||}tj||t |dƒ|ddd�}| |¡t||d| d ¡ d �}t||tjdd �d �}|||fS) NÚbasedirFz#running with default collection {0}rgrhri)rgrhrirkr‰Z flush_cache)rpZsourcesÚcache)r¨)rpr‰r©)r3ryr=r[Z set_basedirr@rBZplaybook_pathsrCrOrPÚformatÚdefault_collectionr‘rMZDEFAULT_VAULT_IDENTITY_LISTrHrurrr8rGr©) r”rpr¿rÂrgZdefault_vault_idsrsr‰Zvariable_managerr r r Ú _play_prereqs s0    ü zCLI._play_prereqsr†cCs^d}t| ¡ƒdkr2tjr.|tjvr.t d¡d}| |¡| |¡}|sZ|durZtdƒ‚|S)NFrzpprovided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'TzSSpecified inventory, host pattern and/or --limit leaves us with no hosts to target.) r¦Z list_hostsrMZLOCALHOST_WARNINGZ LOCALHOSTrOrPÚsubsetr5)r‰rÄÚpatternZno_hostsÚhostsr r r Ú get_host_list0s    zCLI.get_host_listc Cs^t|ƒ}d}|dkr$tjj ¡}�ntj |¡s>td|ƒ‚nüt |ƒrÜt   dt |ƒ¡|g}zt j|t jt jd�}Wn4tyª}ztd||fƒ‚WYd}~n d}~00| ¡\}}|jdkrÖtd||j|fƒ‚|}n^z"t|dƒ}| ¡ ¡}| ¡Wn:ttf�y8}ztd ||fƒ‚WYd}~n d}~00| d ¡}|�sVtd |ƒ‚t|ƒS) Nó-z"The password file %s was not foundz!The password file %s is a script.)rrz�Problem occured when trying to run the password script %s (%s). If this is not a script, remove the executable bit from the file.rz4The password script %s returned an error (rc=%s): %sÚrbz#Could not read password file %s: %ss z*Empty password was provided from file (%s))r:rrÚbufferÚreadrÚpathÚexistsr5r<rOZvvvvr;r±r²r³ÚOSErrorr´rµÚopenr�Úcloser¼rF) Zpwd_fileZ b_pwd_filerwr¾r·r(rrÚfr r r r{Bs: ÿ     &  zCLI.get_password_from_filec CsÆ|durtj}zât d¡ttjƒ ¡}z|jdd�WnJt y‚}z2|j t j krnt  d|t |dd�f¡WYd}~nd}~00t d|¡zdd „|Dƒ}Wn6tyÚt d ¡t d t t ¡ƒ¡d }Yn0||ƒ}| ¡}W�nÆt�y8}z.|j ¡tjt |ƒd d�d}WYd}~�nˆd}~0t�yt}z$tjt |ƒd d�d}WYd}~�nLd}~0t�y°}z$tjt |ƒd d�d}WYd}~�nd}~0t�yÐt d¡d}Ynèt�y¶}zÎtj�rê‚ttjƒ}tjdt |ƒd d�|�r&|�rvtjddk�rvd }t|dƒ�r„t dt t |j!ƒƒ¡t |j!ƒ} t |ƒ| k�r„t d| ¡nt d¡d}tjdt t ¡ƒ|d�d}WYd}~n d}~00t "|¡dS)Nz starting runiÀ)Úmodez'Failed to create the directory '%s': %sZsurrogate_or_replace©ÚerrorszCreated the '%s' directorycSsg|]}t|dd�‘qS)Zsurrogate_or_strictrÓ)r;)r Úar r r rŒ€rz$CLI.cli_executor..zaCommand line args are not in utf-8, unable to continue. Ansible currently only understands utf-8zThe full traceback was: %séF)Z wrap_textr2érSzUser interrupted executionécz0Unexpected Exception, this is probably a bug: %sÚ verbosityr—Úorig_excz exception type: %sz original msg: %sz#to see the full traceback, use -vvvTzthe full traceback was: %s)Úlog_onlyéú)#rÚargvrOÚdebugr.rMZ ANSIBLE_HOMEÚ expanduserÚmkdirrÎÚerrnoZEEXISTrPr;Ú UnicodeErrorrÚ tracebackÚ format_excr]r6rKÚ print_helpr7r5r½rZ DEFAULT_DEBUGÚboolr3ryr�ZvvvÚtyperÚrž) ÚclsrJZ ansible_dirrtZ exit_codeZclir(Zhave_cli_optionsrÛrTr r r Ú cli_executorlsf  ÿ         zCLI.cli_executor)N)NNNT)NNFT)FF)rNN)F)r†)N)Ú__name__Ú __module__Ú __qualname__Ú__doc__rªr»r’rRr-r]Ú staticmethodrdrlrurxr~r€r„r–rWr©r¸r°rÃrÇr{Ú classmethodrér r r r rHwsV   þ þ f     8    $  )rH)PZ __future__rrrrçZ __metaclass__rrrr©rrr*Ú splitlinesrr)Úimportlib.metadataZ#ansible.module_utils.compat.versionr+Zjinja2_versionrárvr±rãÚabcr,r-Úpathlibr.Zansibler/rMZansible.utils.displayr0rOrr(Úprintrržr3Zansible.cli.argumentsr4rXZansible.errorsr5r6r7Zansible.inventory.managerr8Zansible.module_utils.sixr9Zansible.module_utils._textr:r;Z ansible.module_utils.common.filer<Zansible.parsing.dataloaderr=Zansible.parsing.vaultr>r?Zansible.plugins.loaderr@Zansible.releaserAZansible.utils.collection_loaderrBZ2ansible.utils.collection_loader._collection_finderrCZansible.utils.pathrEZansible.utils.unsafe_proxyrFZansible.vars.managerrGr›ršÚ ImportErrorrHr r r r Úst ÿÿ   ÿÿ