a )g5m @sVddlmZmZmZeZddlZddlZddlZej dkrRe dd ej ddZedd Zedd lm Z dd lmZe d Zeed kre deddlZddlZddlZddlZddlmZmZddlmZz"ddlmZddl m!Z!e!Z"WnBe#yFZ$z(e%de$ej&de'dWYdZ$[$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&ZMWneNy@d'ZMYn0Gd(d)d)eZOdS)*)absolute_importdivisionprint_functionN) zRERROR: Ansible requires Python 3.9 or newer on the controller. Current version: %sc Csg}tjtjtjfD]L}z |}Wnty:YqYn0t|s|t |ddp\d|q|rt dd dd|DdS)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..) sysstdinstdoutstderrfileno Exceptionos get_blockingappendgetattr SystemExitjoin)ZhandlesZhandlefdr r r check_blocking_ios    rc Cszttjdt\}}Wn6tjtfyT}ztd|WYd}~n d}~00|rf|dvrrtd|t }|dkrtd|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@%sprompt_ask_vault_pass)rMDEFAULT_VAULT_IDENTITYr) vault_idsvault_password_filesask_vault_passcreate_new_password auto_promptZ password_fileZid_slugr r r build_vault_idss   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 vr| ptj} t|| | d }z |Wn8t y}z t d | |fWYd}~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|| |fn|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)filenameraloaderz*Error getting vault password file (%s): %sz-Error in vault password file loading (%s): %s)rMZDEFAULT_VAULT_PASSWORD_FILErrHrlrdrfr>loadr5rOrPset_vault_secretsZvvvvvr?r;)rprgrhrirjrk vault_secretsrnZlast_exceptionZfound_vault_secretZ vault_id_slugZ vault_id_nameZvault_id_valueZbuilt_vault_idZprompted_vault_secretexcZfile_vault_secretr r r setup_vault_secretssz          " "  zCLI.setup_vault_secretscCstj|d}|rt|}|S)N)rm)getpassrF)rmsecretr r r _get_secret?s zCLI._get_secretcCstj}d}d}d}tjrdn |d}z|d|}|drNtd}d|}n|d rdt|d }|d rt|}|dr|dkr|}n|d rt|d }WntyYn0||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) r3CLIARGSrMZAGNOSTIC_BECOME_PROMPTupperrHrxget_password_from_fileEOFError)opZsshpassZ becomepassZ become_promptZbecome_prompt_methodr r r ask_passwordsGs*    zCLI.ask_passwordscCs|r|jdkr|jd|S)z check for conflicting options rSz.The number of processes (--forks) must be >= 1)ZforksrKerror)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') )usagedescepilogN)rXZcreate_base_parserrrK)rQrrrr r r init_parseroszCLI.init_parsercCst|dr|jsdg|_t|drb|jrbt}|jD]"}|dD]}||qBq4t||_t|dr|jrt}|jD]"}|dD]}||qq~t||_t|dr|js|j rt |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 tagsall, skip_tags inventorycSs$g|]}d|vrt|ddn|qS)rF)followrD)r optr r r rz)CLI.post_process_args..)hasattrrsetr_addstriplistrSKIP_INVENTORY_DEFAULTSr isinstancer9rMZDEFAULT_HOST_LIST)rQoptionsrZtag_settagrr r r post_process_argss*      zCLI.post_process_argsc Cs|trt|jz|j|jdd}WnJty|}z2|jdkrf|jj dd|j dWYd}~n d}~00| |}t |dS)aParse 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. rSNrz %s)statusmessage)rHAS_ARGCOMPLETE argcompleteZ autocompleterK parse_argsrJrcodeexit format_helprr3Z_init_global_context)rQrexr r r rWs    z CLI.parsec Cs|rt}nt}|d}|d}tt|D]@}||dkrLd||<zt||||<Wq4tyrYq40q4t|dkrtt|dD]}|dq| ||d|d|ddS)z" return full ansible version info r.rrrSr)stringZfullmajorminorZrevision) rXr*rAr_rangelenintrrr)gitinfoZansible_version_stringZansible_versionZansible_versionsZcounterr r r version_infos*       zCLI.version_infocCstjstj|ddn|dtjvrRtjdkr>tj|ddqt|tjdnDt j ddt j t j d}| |j dkrt|dntj|ddd S) z% find reasonable way to display text T)Z screen_onlyPAGERwin32zless --version)shellrrrrIN)rrisattyrOrenvironplatformrH pager_pipe subprocessPopenPIPE communicate returncode)textpr r r pagers    z CLI.pagercCshdtjvrtjtjd<z*tj|dtjtjd}|j t |dWn"t yRYnt ybYn0dS)z pipe text through a pager LESST)rrr)inputN) rrrH LESS_OPTSrrrrrrr:IOErrorKeyboardInterrupt)rcmdr r r rs    zCLI.pager_pipec Cstj}t}|dd}|rV||t||t_t|}|rVt d ||t_ t |d}tj}||}tj||t |d|ddd}||t||d|d  d }t||tjdd d }|||fS) NbasedirFz#running with default collection {0}rgrhri)rgrhrirkrZ flush_cache)rpZsourcescache)r)rprr)r3ryr=r[Z set_basedirr@rBZplaybook_pathsrCrOrPformatdefault_collectionrrMZDEFAULT_VAULT_IDENTITY_LISTrHrurrr8rGr) rrprrrgZdefault_vault_idsrsrZvariable_managerr r r _play_prereqs s0     zCLI._play_prereqsrcCs^d}t|dkr2tjr.|tjvr.tdd}||||}|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.) rZ list_hostsrMZLOCALHOST_WARNINGZ LOCALHOSTrOrPsubsetr5)rrpatternZno_hostshostsr r r get_host_list0s    zCLI.get_host_listc Cs^t|}d}|dkr$tjj}ntj|s>td|nt |rt dt ||g}zt j|t jt jd}Wn4ty}ztd||fWYd}~n d}~00|\}}|jdkrtd||j|f|}n^z"t|d}|}|Wn:ttfy8}ztd ||fWYd}~n d}~00|d }|sVtd |t|S) N-z"The password file %s was not foundz!The password file %s is a script.)rrzProblem 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): %srbz#Could not read password file %s: %ss z*Empty password was provided from file (%s))r:rrbufferreadrpathexistsr5r<rOZvvvvr;rrrOSErrorrropenrcloserrF) Zpwd_fileZ b_pwd_filerwrrr(rrfr r r r{Bs:      &  zCLI.get_password_from_filec Cs|durtj}ztdttj}z|jddWnJt y}z2|j t j krnt d|t |ddfWYd}~nd}~00td|zdd |D}Wn6tytd td t td }Yn0||}|}Wnty8}z.|jtjt |d dd}WYd}~nd}~0tyt}z$tjt |d dd}WYd}~nLd}~0ty}z$tjt |d dd}WYd}~nd}~0tytdd}Ynty}ztjrttj}tjdt |d d|r&|rvtjddkrvd }t|drtdt t |j!t |j!} t || krtd| ntdd}tjdt t|dd}WYd}~n d}~00t"|dS)Nz starting runi)modez'Failed to create the directory '%s': %sZsurrogate_or_replaceerrorszCreated the '%s' directorycSsg|]}t|ddqS)Zsurrogate_or_strictr)r;)r ar r r rrz$CLI.cli_executor..zaCommand line args are not in utf-8, unable to continue. Ansible currently only understands utf-8zThe full traceback was: %sF)Z wrap_textr2rSzUser interrupted executioncz0Unexpected Exception, this is probably a bug: %s verbosityrorig_excz exception type: %sz original msg: %sz#to see the full traceback, use -vvvTzthe full traceback was: %s)log_only)#rargvrOdebugr.rMZ ANSIBLE_HOME expandusermkdirrerrnoZEEXISTrPr; UnicodeErrorr traceback format_excr]r6rK print_helpr7r5rrZ DEFAULT_DEBUGboolr3ryrZvvvtyperr) clsrJZ ansible_dirrtZ exit_codeZclir(Zhave_cli_optionsrrTr r r cli_executorlsf           zCLI.cli_executor)N)NNNT)NNFT)FF)rNN)F)r)N)__name__ __module__ __qualname____doc__rrrrRr-r] staticmethodrdrlrurxr~rrrrWrrrrrr{ classmethodrr r r r rHwsV     f     8    $  )rH)PZ __future__rrrrZ __metaclass__rrrrrrr* splitlinesrr)importlib.metadataZ#ansible.module_utils.compat.versionr+Zjinja2_versionrrvrrabcr,r-pathlibr.Zansibler/rMZansible.utils.displayr0rOrr(printrrr3Zansible.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.managerrGrr ImportErrorrHr r r r st