a )g @svddlmZmZmZeZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl Z ddlmZmZddlmZddlmZddlmZmZmZmZmZddlmZddlmZm Z dd l!m"Z"dd l#m$Z$dd l%m&Z&dd l'm(Z(m)Z)m*Z*dd l+m,Z,m-Z-m.Z.ddl/m0Z0ddl1m2Z2ddl3m4Z4ddl5m6Z6ddl7m8Z8m9Z9ddl:m;Z;ddlGdddeZ?dS))absolute_importdivisionprint_functionN)ABCabstractmethod)Sequence) constants) AnsibleErrorAnsibleConnectionFailureAnsibleActionSkipAnsibleActionFailAnsibleAuthenticationFailure) modify_module)discover_interpreter!InterpreterDiscoveryRequiredError)ArgumentSpecValidator)UnsupportedError)_filter_non_json_lines) binary_type string_types text_type)to_bytes to_nativeto_text)jsonify) __version__)resource_from_fqcr)Display)wrap_varAnsibleUnsafeText)remove_internal_keys)get_versioned_doclinkc@speZdZdZegZddZedPddZdQddZ dRd d Z dSd d Z dTddZ dUddZ dVddZddZddZdWddZddZdXddZddZd d!Zd"d#Zd$d%ZdYd&d'Zd(d)ZdZd*d+Zd,d-Zd.d/Zd[d1d2Zd\d3d4Zd]d5d6Zd^d7d8Z d_d9d:Z!d`d;d<Z"dad=d>Z#dbd?d@Z$dAdBZ%dCdDZ&dcdEdFZ'dGdHZ(dddJdKZ)dedLdMZ*dNdOZ+dS)f ActionBasez This class is the base class for all action plugins, and defines code common to all actions. The base class handles the connection by putting/getting files and executing commands based on the current action in use. cCs^||_||_||_||_||_||_d|_d|_d|_d|_ d|_ g|_ g|_ t |_d|_dS)NFT)_task _connection _play_context_loader_templar_shared_loader_obj_cleanup_remote_tmp_supports_check_mode_supports_async_discovered_interpreter_key_discovered_interpreter_discovery_deprecation_warnings_discovery_warningsdisplay_display_used_interpreter)selfZtaskZ connectionZ play_contextloaderZtemplarZshared_loader_objr5C/usr/lib/python3.9/site-packages/ansible/plugins/action/__init__.py__init__6szActionBase.__init__NcCsi}|durdg|d<~|jjr0|js0tdn0|jjrH|jsHtdn|jjr`|jjr`td|jrt|jj }| |j}|rtd|jj d t|f|jjjdur|r||S) a Action Plugins should implement this method to perform their tasks. Everything else in this base class is a helper method for the action plugin to do that. :kwarg tmp: Deprecated parameter. This is no longer used. An action plugin that calls another one and wants to use the same remote tmp for both should set self._connection._shell.tmpdir rather than this parameter. :kwarg task_vars: The variables (host vars, group vars, config vars, etc) associated with this task. :returns: dictionary of results from the module Implementors of action modules may find the following variables especially useful: * Module parameters. These are stored in self._task.args NzActionModule.run() no longer honors the tmp parameter. Action plugins should set self._connection._shell.tmpdir to share the tmpdirwarningz%async is not supported for this task.z*check mode is not supported for this task.z1check mode and async cannot be used on same task.zInvalid options for %s: %s,)r# async_valr+r check_moder*r _VALID_ARGS frozensetargskeys differenceactionjoinlistr$_shelltmpdir_early_needs_tmp_path_make_tmp_path)r3tmp task_varsresultZ task_optsZbad_optsr5r5r6runMs$    zActionBase.runc Cs|jj}t||||||d}||} || jz| jd} WntyZd} Yn0| r| jj } t | t rd|j d| } t | | |fS)aZValidate an argument spec against the task args This will return a tuple of (ValidationResult, dict) where the dict is the validated, coerced, and normalized task args. Be cautious when directly passing ``new_module_args`` directly to a module invocation, as it will contain the defaults, and not only the args supplied from the task. If you do this, the module should not define ``mututally_exclusive`` or similar. This code is roughly copied from the ``validate_argument_spec`` action plugin for use by other action plugins. )mutually_exclusiverequired_togetherrequired_one_of required_if required_byrNzUnsupported parameters for (z ) module: )r#r>copyrZvalidateupdateZvalidated_parameterserrors IndexErrormsg isinstancerZ _load_namer ) r3Z argument_specrLrMrNrOrPZnew_module_argsZ validatorZvalidation_resulterrorrUr5r5r6validate_argument_spec{s*      z!ActionBase.validate_argument_specFcCs |s |jjs||jjjdS)a?Method to perform a clean up at the end of an action plugin execution By default this is designed to clean up the shell tmpdir, and is toggled based on whether async is in use Action plugins may override this if they deem necessary, but should still call this method via super N)r#r:_remove_tmp_pathr$rDrE)r3forcer5r5r6cleanups zActionBase.cleanupc Cs,z ||WSttfy&|YS0dS)z}Helper to get an option from a plugin without having to use the try/except dance everywhere to set a default N) get_optionAttributeErrorKeyError)r3Zpluginoptiondefaultr5r5r6get_plugin_options zActionBase.get_plugin_optioncCs|j|jj||dSNr`)rar$becomer3r_r`r5r5r6get_become_optionszActionBase.get_become_optioncCs|j|j||dSrb)rar$rer5r5r6get_connection_optionsz ActionBase.get_connection_optioncCs|j|jj||dSrb)rar$rDrer5r5r6get_shell_optionszActionBase.get_shell_optioncCs0|jj|}|j|dd}|ddkr,dSdS)NT)cmdsudoablercrF)r$rDexists_low_level_execute_command)r3pathrirJr5r5r6_remote_file_existss  zActionBase._remote_file_existsc Cs|jjr|d|jj}n|}|d}t|dkrHd|ddnd}t|}|jjD]}|dkrd} gd} |d vr|| vr|jj |krd | |f}n|d kr|| vrd | |f}|d vr|rt |jj drdD]"} | |vr|jj || || <q|j jj|||jjd} | jsP| jrPt| jdkrP| jd} td|| | j}|r\qnq\td|t}||i}|jjrd|d<|jjj|d<|jjjd|jd|d<|jjjd|jd|d<|jjjd|jd|d<dD]}zLt||||jf||jj|jj|t t!|jddd |\}}}WqWnt"y}zt#t$||j%|j&|d!|_'d"|j%}|j'|d#|<|jjr|jj(r|j'|d#|<||_)n|j'|d|jjd#|<WYd$}~n d$}~00q||||fS)%zu Handles the loading and templating of the module code through the modify_module() function. Zansible_delegated_vars.rz.ps1zansible.windows)zansible.builtinzansible.legacyrr)statfilerQZpingz %s.win_%sZ async_statusz%s.%s)Zwin_statZwin_fileZwin_copyZslurp_unquote)srcdestrn)Zcollection_listz@The module {0} was redirected to {1}, which could not be loaded.z6The module %s was not found in configured module pathsTrdZ become_method become_user)Z playcontextZ become_passZbecome_passwordZ become_flags)rxrq_remote_is_localF)rImodule_compressionZ async_timeout environmentZremote_is_local)rAinterpreter_namediscovery_moderIzdiscovered_interpreter_%s ansible_factsN)*r#Z delegate_togetsplitlenrBrr$Z!module_implementation_preferencesrAhasattrrDrur(Z module_loaderZfind_plugin_with_context collectionsZresolvedZ redirect_listr formatZplugin_resolved_pathdict_compute_environment_stringrdnamer\r%rr'r|r:boolgetattrrrrr~rr-Zdelegate_factsr,)r3 module_name module_argsrIZuse_varsZsplit_module_nameZcollection_nameZleaf_module_namemod_typeZwin_collectionZrewrite_collection_nameskeyrJZtarget_module_name module_pathfinal_environmentZ become_kwargsZdummy module_data module_styleZmodule_shebangZidreZdiscovered_keyr5r5r6_configure_modules "                  4zActionBase._configure_modulecCst}|jjdur~|jj}t|ts*|g}|D]N}|dus.t|dkrHq.|j|}t|tsrtd|t |f| |q.t|dkr|j|}t|tr| | ||j j jfi|S)zZ Builds the environment string to be used when executing the remote task. Nrz2environment must be a dictionary, received %s (%s))rr#r}rVrCrr'templater typerRclearr$rDZ env_prefix)r3Zraw_environment_outrZ environmentsr}Ztemp_environmentr5r5r6r@s$         z&ActionBase._compute_environment_stringcCs t|ddS)z[ Determines if a tmp path should be created before the action is executed. ZTRANSFERS_FILESF)rr3r5r5r6rFasz ActionBase._early_needs_tmp_pathc Csz|jd}Wn tttfy0|jj}Yn0|jj}|jjrL|jjj nddk}|jj |p`||dkt j | pt||g}t |S)zE Determines if we are required and can do pipelining pipeliningrrZsunew)r$r\r^r] ValueErrorr%ralways_pipeline_modulesrdrZhas_pipeliningCDEFAULT_KEEP_REMOTE_FILESall)r3r wrap_asyncZ is_enabledZalways_pipelineZbecome_exceptionZ conditionsr5r5r6_is_pipelining_enabledhs z!ActionBase._is_pipelining_enabledcCs|ddgS)zh Returns a list of admin users that are configured for the current shell plugin admin_usersroot)rhrr5r5r6_get_admin_usersszActionBase._get_admin_usersc Csf|did|d|dd}dD]0}z|j|}WntyRYq(Yn0qbq(|jj}|S)z= consistently get the 'remote_address' for the action plugin Zdelegated_varsZ ansible_hostZinventory_hostnameN) remote_addrhost)rr$r\r^r%r)r3tvarsrZ variationr5r5r6_get_remote_addrs$  zActionBase._get_remote_addrcCsZd}z|jd}Wn@ty<t|jddp6|jj}YntyT|jj}Yn0|S)z: consistently get the 'remote_user' for the action plugin N remote_userZ default_user)r$r\r^rr%rr])r3rr5r5r6_get_remote_users  zActionBase._get_remote_usercCs<|jjs dS|}|}|d}t|o8|||gvS)z} The user is not the same as the connection user and is not part of the shell configured admin users Frz)r$rdrrrfr)r3rrrzr5r5r6_is_become_unprivilegeds  z"ActionBase._is_become_unprivilegedc Cst|jddrtj}n|j|jddddd}|}|jj}|jjj |||d}|j |dd}|dd krN|dd krd }nd|dd kr|jj d vrt j dkrd|d|df}qd}n&d|dvr|d}nd||df}d|vr|ddkr|d|d}t j dkrDd|vrD|ddkrD|d|d7}t|nd|_z8|dd|d}|jj|ddd} Wntyd} Yn0| dkrtd||f| |jj_| S)zE Create and return a temporary path on a remote box. r{F remote_tmp~/.ansible/tmprcrj)basefilesystemrErkrzAuthentication failure.)Zsshz6SSH encountered an unknown error. The output was: %s%sstdoutstderrzSSH encountered an unknown error during the connection. We recommend you re-run the command using -vvvv, which will enable SSH debugging output to help diagnose the issuezNo space left on devicea5Failed to create temporary directory. In some cases, you may have been able to authenticate and did not have permissions on the target directory. Consider changing the remote tmp path in ansible.cfg to a path rooted in "/tmp", for more error information use -vvv. Failed command was: %s, exited with result %drrz, stdout output: %sz, stderr output: %sTz%s=rxry/zPfailed to resolve remote temporary directory from %s: `%s` returned empty string)rr$rDEFAULT_LOCAL_TMP_remote_expand_userrhrrDZ_generate_temp_dir_nameZmkdtemprm transportr0 verbosityr r)stripr join_path splitlinesrTr rE) r3rrEZbecome_unprivilegedrrirJoutputZ stdout_partsrkr5r5r6rGsD      $     zActionBase._make_tmp_pathcCs|o|jotj od|vS)zLDetermine if temporary path should be deleted or kept by user request/configz-tmp-)r)rr)r3tmp_pathr5r5r6_should_remove_tmp_pathsz"ActionBase._should_remove_tmp_pathcCs|dur|jjjr|jjj}|s*||r|jjj|dd}|j|dd}|dddkr|td|d|d d fn d|jj_dS) z$Remove a temporary path we created. NT)ZrecurseFrrkrz;Error deleting remote temporary files (rc: %s, stderr: %s})rzNo error string available.) r$rDrErremovermrr0r8)r3rrZriZ tmp_rm_resr5r5r6rYs zActionBase._remove_tmp_pathcCs|j|||S)a Copy a file from the controller to a remote path :arg local_path: Path on controller to transfer :arg remote_path: Path on the remote system to transfer into .. warning:: * When you use this function you likely want to use use fixup_perms2() on the remote_path to make sure that the remote file is readable when the user becomes a non-privileged user. * If you use fixup_perms2() on the file and copy or move the file into place, you will need to then remove filesystem acls on the file once it has been copied into place by the module. See how the copy module implements this for help. )r$Zput_file)r3Z local_path remote_pathr5r5r6_transfer_fileszActionBase._transfer_filec Cst|trt|}tjtjd\}}t|d}zt |dd}| |Wn4t y~}zt dt |WYd}~n d}~00||z|||Wt|n t|0|S)zJ Copies the module data out to the temporary module path. )dirwbsurrogate_or_strictrSz>failure writing module data to temporary file for transfer: %sN)rVrrtempfileZmkstemprrosfdopenrwrite Exceptionr rflushcloserunlink)r3rdataZafdZafileZafoer5r5r6_transfer_data#s   &zActionBase._transfer_dataTc Cs|dur|}t|jjddr$|S|sh|rd||d}|ddkrdtd|dt|d|S| d }|rd }d }d |}d |} nd}d}d|}d|} | |||}|ddkr|S|r ||d}|ddkr td|dt|d| ||}|ddkr(|S|| vr>tdz||gt |d}Wn&ty~} z WYd} ~ nd} ~ 00|ddkr|S||| }|ddkr|Std} |d} | dur.||| }|ddkr.|drtd| |r d} nd} ||| }|ddkr.|S|drtd| ||d|}|ddkrj|Std|dt|dtd|dt|d| fdS)a% We need the files we upload to be readable (and sometimes executable) by the user being sudo'd to but we want to limit other people's access (because the files could contain passwords or other private information. We achieve this in one of these ways: * If no sudo is performed or the remote_user is sudo'ing to themselves, we don't have to change permissions. * If the remote_user sudo's to a privileged user (for instance, root), we don't have to change permissions * If the remote_user sudo's to an unprivileged user then we attempt to grant the unprivileged user access via file system acls. * If granting file system acls fails we try to change the owner of the file with chown which only works in case the remote_user is privileged or the remote systems allows chown calls by unprivileged users (e.g. HP-UX) * If the above fails, we next try 'chmod +a' which is a macOS way of setting ACLs on files. * If the above fails, we check if ansible_common_remote_group is set. If it is, we attempt to chgrp the file to its value. This is useful if the remote_user has a group in common with the become_user. As the remote_user, we can chgrp the file to that group and allow the become_user to read it. * If (the chown fails AND ansible_common_remote_group is not set) OR (ansible_common_remote_group is set AND the chgrp (or following chmod) returned non-zero), we can set the file to be world readable so that the second unprivileged user can read the file. Since this could allow other users to get access to private information we only do this if ansible is configured with "allow_world_readable_tmpfiles" in the ansible.cfg. Also note that when ansible_common_remote_group is set this final fallback is very unlikely to ever be triggered, so long as chgrp was successful. But just because the chgrp was successful, does not mean Ansible can necessarily access the files (if, for example, the variable was set to a group that remote_user is in, and can chgrp to, but does not have in common with become_user). NZ _IS_WINDOWSFzu+xrkrz=Failed to set execute bit on remote files (rc: {0}, err: {1})rrzrxzr-xz{0} allow read,executezA+user:{0}:rx:allowZrXzr-Xz{0} allow readzA+user:{0}:r:allowzLFailed to set file mode or acl on remote temporary files (rc: {0}, err: {1})zFailed to change ownership of the temporary files Ansible (via chmod nor setfacl) needs to create despite connecting as a privileged user. Unprivileged become user would be unable to read the file.z+azYplaybook_guide/playbooks_privilege_escalation.html#risks-of-becoming-an-unprivileged-userZcommon_remote_groupZworld_readable_tempaBoth common_remote_group and allow_world_readable_tmpfiles are set. chgrp was successful, but there is no guarantee that Ansible will be able to read the files after this operation, particularly if common_remote_group was set to a group of which the unprivileged become user is not a member. In this situation, allow_world_readable_tmpfiles is a no-op. See this URL for more details: %s#risks-of-becoming-an-unprivileged-userzg+rwxzg+rwzUsing world-readable permissions for temporary files Ansible needs to create when becoming an unprivileged user. This may be insecure. For information on securing this, see %s#risks-of-becoming-an-unprivileged-userza+%sz;Failed to set file mode on remote files (rc: {0}, err: {1})zFailed to set permissions on the temporary files Ansible needs to create when becoming an unprivileged user (rc: %s, err: %s}). For information on working around this, see %s#risks-of-becoming-an-unprivileged-user)rrr$rDr _remote_chmodr rrrf_remote_set_user_facl _remote_chownrrCr r!rh _remote_chgrpr0r8)r3Z remote_pathsrZexecuteresrzZ chmod_modeZ setfacl_modeZchmod_acl_modeZposix_acl_moderZ become_linkgroupZ group_moder5r5r6 _fixup_perms2=s&                        zActionBase._fixup_perms2cCs"|jj||}|j||d}|S)z. Issue a remote chmod command r)r$rDchmodrm)r3pathsmoderjrirr5r5r6rszActionBase._remote_chmodcCs"|jj||}|j||d}|S)z. Issue a remote chown command r)r$rDchownrm)r3ruserrjrirr5r5r6r!szActionBase._remote_chowncCs"|jj||}|j||d}|S)z. Issue a remote chgrp command r)r$rDZchgrprm)r3rrrjrirr5r5r6r)szActionBase._remote_chgrpcCs$|jj|||}|j||d}|S)z0 Issue a remote call to setfacl r)r$rDZ set_user_faclrm)r3rrrrjrirr5r5r6r1sz ActionBase._remote_set_user_faclc Cs|durtd~t|||dd}|jd||dd}|drv|d }|sX|d }|sf|d }td ||f|d dsd|d d<d|d vrd|d d<n*t|d dtstdt|d d|d S)z3 Get information from remote file. Nz_execute_remote_stat no longer honors the tmp parameter. Action plugins should set self._connection._shell.tmpdir to share the tmpdirZsha1)rnfollowZ get_checksumZchecksum_algorithmzansible.legacy.statF)rrrIrfailed module_stderr module_stdoutrUz1Failed to get information on remote file (%s): %srsrl1checksumrrzDInvalid checksum returned by stat: expected a string type but got %s) r0r8r_execute_modulerr rVrr) r3rnall_varsrrHrrZmystatrUr5r5r6_execute_remote_stat9s4         zActionBase._execute_remote_statc Cs|jddd}zz2|j|||d}|dr<|drz transferring module to remote %srrrz%s=%s )rrz"done transferring module to remoteTzansible.legacy.async_wrapperjrlJ)z#!_z -preserve_tmp css|]}t|VqdS)N)r.0rr5r5r6 {z-ActionBase._execute_module..zPipelining is enabled.)Zarg_pathcSsg|] }|r|qSr5r5rr5r5r6 r z.ActionBase._execute_module..)rjin_dataZ_ansible_suppress_tmpdir_deleteFresultsZansible_module_resultszSFound internal 'results' key in module return, renamed to 'ansible_module_results'.Zchangedr stdout_linesr stderr_linesrwarningsZ deprecationsz"done with _execute_module (%s, %s))rr:rhrr}appendrZvvvr r2Zget_remote_filenamerdebugrritemsshlexquoterrdumpsrrrandomZrandintreplacerinsertrrBZbuild_module_commandrrrm_parse_returned_datapopr)rVrrr rrr,r-r/extendr.r)&r3rrrHrI persist_filesZdelete_remote_tmprrEZremove_async_dirrrZshebangrrZremote_module_pathZremote_module_filenameZargs_file_pathZ args_datakvZenvironment_stringZ remote_filesrjr riZasync_module_styleZasync_module_dataZasync_module_pathZasync_module_remote_filenameZremote_async_module_pathZ async_limitZ async_jid interpreterZ async_cmdrrZtxtr5r5r6rs                             *     zActionBase._execute_modulecCsLzDt|dddd\}}|D]}t|qt|}d|d<WntyFtddd}|dd|d<d |vr|d |d <|d d r|d |d <d |vr|dd r|d|d <d |d<|j durt |j d}t d|}||d s||drd|d<|dd7<d|vrB|d|d<Yn0|S)NrrrT)Z objects_only_ansible_parsedF)rr"rrrZ Traceback exceptionrrUz!#z+%s: (?:No such file or directory|not found)zQThe module failed to execute correctly, you probably need to set the interpreter.z& See stdout/stderr for the exact errorrk)rrr0r8rloadsrrrr2rescapelstripcompilesearch)r3rZfiltered_outputrwrr!matchr5r5r6rs2         zActionBase._parse_returned_datasurrogate_then_replacecCstd|r0td||jjd||}|r>||jj_|}|d}|r|jjrt |jj dkrt j s||kst ||fstd|jj||jj}|jjr|dur|jj}|jj|d}|r|d t|}td |f|jj d krt|jd d |j_|jj|||d\} } } t| trHt| |d } n(t| tsltd| |d } n| } t| trt| |d } n(t| tstd| |d } n| } | durd} || } td| | | ft| | | | | dS)a7 This is the function which executes the low level shell command, which may be commands to create/remove directories for temporary files, or to run the module code or python directly when pipelining. :kwarg encoding_errors: If the value returned by the command isn't utf-8 then we have to figure out how to transform it to unicode. If the value is just going to be displayed to the user (or discarded) then the default of 'replace' is fine. If the data is used as a key or is going to be written back out to a file verbatim, then this won't work. May have to use some sort of replacement strategy (python3 could use surrogateescape) :kwarg chdir: cd into this directory before executing the command. z&_low_level_execute_command(): startingzA_low_level_execute_command(): changing cwd to %s for this commandzcd %srzZ network_cliz;_low_level_execute_command(): using become for this commandNzsleep 0z -c z+_low_level_execute_command(): executing: %slocalrr)r rjr rz>_low_level_execute_command() done: rc=%d, stdout=%s, stderr=%s)rkrrrr)!r0rr$rDZappend_commandrrrfrdrrrZBECOME_ALLOW_SAME_USERanyZbuild_become_commandZallow_executabler%rrrr&Z get_basedircwdZ exec_commandrVrrrrB readlinesrrr)r3rirjr rZencoding_errorschdirZruserZbuserrkrrouterrr5r5r6rmsX            z%ActionBase._low_level_execute_commandc Csti}td|jdt|dd|dd}|ddr`tdtj||t |d d f|S|d d d krB|d dvrd |d<n|drd|d<n|drt j d kr|dt j krt j |d<nvtd||jdt|d|dd}d|vrB|d}|ddkrt |}ntdt|||d<t ||d<|r(t|} t j d kr|| tjt j kr|t j |d<ntd|z8t|d} | } Wdn1s0YWn:ty} z td |t| fWYd} ~ n d} ~ 00d!| vrd|d"<n||d#<t | |d$<ntd%d&|d#<||d$<|jjrpd|vr^d |d<d$|vrpd'|d$<|S)(Nz4Going to peek to see if file has changed permissionszansible.legacy.fileT)rnZ _diff_peek)rrrIrrFz,Failed to get diff between '%s' and '%s': %srUrrrkrstate)NZabsentbeforeZappears_binaryrxZ dst_binarysizeZ dst_largerzSlurping the file %szansible.legacy.slurp)rnZcontentencodingbase64z.unknown encoding in content option, failed: %sZ before_headerZ src_largerz!Reading local copy of the file %srbz8Unexpected error while reading source (%s) for diff: %s Z src_binaryZ after_headerZafterzsource of file passed inzdynamically generatedzX [[ Diff output has been hidden because 'no_log: true' was specified for this result ]] )r0rrrrr8rrnbasenamerrZMAX_FILE_SIZE_FOR_DIFFr7Z b64decoder rrsST_SIZEopenreadrr#r) r3Z destinationsourcerIZ source_filerZ peek_resultZ dest_resultZ dest_contentsstrvZ src_contentsrr5r5r6_get_diff_dataCsf    (   "        ,*      zActionBase._get_diff_datacCs|j}|j|||S)z find a needle in haystack of paths, optionally using 'dirname' as a subdir. This will build the ordered list of paths to search and pass them to dwim to get back the first existing file found. )r#Zget_search_pathr&Zpath_dwim_relative_stack)r3rZneedleZ path_stackr5r5r6 _find_needles zActionBase._find_needle)NN)NNNNNN)F)N)N)N)N)N)F)N)F)NT)F)F)F)F)NT)F)TN)NNNNFNF)TNNr+N)T),__name__ __module__ __qualname____doc__r=r<r7rrKrXr[rarfrgrhrorrrFrrrrrrGrrYrrrrrrrrrrrrrrrmr@rAr5r5r5r6r"*s` - 2   n !  ?  ]     ' 6: U' P Ir")@Z __future__rrrrZ __metaclass__r7rrrrrrsrabcrrcollections.abcrZansiblerrZansible.errorsr r r r r Zansible.executor.module_commonrZ&ansible.executor.interpreter_discoveryrrZ$ansible.module_utils.common.arg_specrZansible.module_utils.errorsrZansible.module_utils.json_utilsrZansible.module_utils.sixrrrZansible.module_utils._textrrrZansible.parsing.utils.jsonifyrZansible.releaserZansible.utils.collection_loaderrZansible.utils.displayrZansible.utils.unsafe_proxyrrZansible.vars.cleanr Zansible.utils.plugin_docsr!r0r"r5r5r5r6s: