o nnh`@srddlmZddlZddlZddlZddlZddlZddlZddlZddl Z ddl m Z m Z ddl mZddlmZddlmZmZmZmZmZddlmZddlmZmZdd lmZdd lm Z dd l!m"Z"dd l#m$Z$m%Z%m&Z&dd l'm(Z(m)Z)m*Z*ddl+m,Z,ddl-m.Z.ddl/m0Z0ddl1m2Z2ddl3m4Z4m5Z5ddl6m7Z7ddl8m9Z9e2Z:ddZ;Gddde ZZ(d?d@Z)dRdVdCdDZ*  dWdVdEdFZ+dGdHZ,dXdJdKZ-dTdLdMZ.dNdOZ/dS)Y 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. FTcCsR||_||_||_||_||_||_d|_d|_d|_g|_ g|_ d|_ t |_ dS)NF)_task _connection _play_context_loader_templar_shared_loader_obj_cleanup_remote_tmp_discovered_interpreter_key_discovered_interpreter_discovery_deprecation_warnings_discovery_warnings_used_interpreterdisplay_display)selftask connection play_contextloadertemplarshared_loader_objr,r,r-__init__Gs zActionBase.__init__NcCsi}|dur dg|d<~|jjr|jstd|jj|jjr*|js*td|jj|jrLt |jj }| |j}|rLtd|jjd 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 Implementers 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(This action (%s) does not support async.z-This action (%s) does not support check mode.zInvalid options for %s: %s,)r/ async_val_supports_asyncr action check_mode_supports_check_moder _VALID_ARGS frozensetargskeys differencejoinr(r0_shelltmpdir_early_needs_tmp_path_make_tmp_path)r=tmp task_varsresult task_optsbad_optsr,r,r-runZs   zActionBase.runc Cs|jj}t||||||d}||} || jz| jd} Wn ty-d} Ynw| rF| jj } t | t rBd|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/rNcopyrvalidateupdatevalidated_parametersr" IndexErrormsgr#r _load_namer ) r= argument_specr\r]r^r_r`new_module_args validatorvalidation_resulterrorrfr,r,r-validate_argument_specs,     z!ActionBase.validate_argument_speccCs$|s|jjs||jjjdSdS)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/rG_remove_tmp_pathr0rRrS)r=forcer,r,r-cleanups zActionBase.cleanupc Cs(z||WSttfy|YSw)z}Helper to get an option from a plugin without having to use the try/except dance everywhere to set a default ) get_optionAttributeErrorKeyError)r=pluginoptiondefaultr,r,r-get_plugin_options  zActionBase.get_plugin_optioncC|j|jj||dSNrv)rwr0becomer=rurvr,r,r-get_become_optionzActionBase.get_become_optioncCs|j|j||dSry)rwr0r|r,r,r-get_connection_optionsz ActionBase.get_connection_optioncCrxry)rwr0rRr|r,r,r-get_shell_optionr~zActionBase.get_shell_optioncCs0|jj|}|j|dd}|ddkrdSdS)NT)cmdsudoablercrF)r0rRexists_low_level_execute_command)r=pathrrXr,r,r-_remote_file_existss  zActionBase._remote_file_existsc Cs|jjr|d|jj}n|}|d}t|dkr$d|ddnd}t|}|jjD]}}|dkr~d} gd} |d vrO|| vrO|jj |krOd | |f}n|d kr]|| vr]d | |f}|d vr~|r~t |jj dr~dD]} | |vr}|jj || || <ql|j jj|||jjd} | js| jrt| jdkr| jd} td|| | j}|rnq.td|t}||i}|jjrd|d<|jjj|d<|jjjd|jd|d<|jjjd|jd|d<|jjjd|jd|d<dD]w}z't||||jf|tjj d|d|jj!|t"t#|jd d!d"|\}}}WnNt$yh}zAt%t&||j'|j(|d#|_)d$|j'}|j)|d%|<|jjrF|jj*rQ|j)|d%|<||_+n |j)|d|jjd%|<WYd&}~qd&}~ww||||fS)'zu Handles the loading and templating of the module code through the modify_module() function. ansible_delegated_vars.rz.ps1zansible.windows)zansible.builtinzansible.legacyr)statfilerapingz %s.win_%s async_statusz%s.%s)win_statwin_filewin_copyslurp_unquote)srcdestr)collection_listz@The module {0} was redirected to {1}, which could not be loaded.z6The module %s was not found in configured module pathsTr{ become_method become_user) playcontext become_passbecome_password become_flags)rrDEFAULT_MODULE_COMPRESSION variables_remote_is_localF)rWmodule_compression async_timeout environmentremote_is_local)rIinterpreter_namediscovery_moderWzdiscovered_interpreter_%s ansible_factsN),r/ delegate_togetsplitlenrQrr0!module_implementation_preferencesrIhasattrrRrr4 module_loaderfind_plugin_with_context collectionsresolved redirect_listrformatplugin_resolved_pathr%_compute_environment_stringr{namerqr1r r3Cconfigget_config_valuerGboolgetattrrrr rrr7delegate_factsr6)r= module_name module_argsrWuse_varssplit_module_namecollection_nameleaf_module_namemod_typewin_collectionrewrite_collection_nameskeyrXtarget_module_name module_pathfinal_environment become_kwargsdummy module_data module_stylemodule_shebangidrediscovered_keyr,r,r-_configure_modules "              zActionBase._configure_modulecCst}|jjdur?|jj}t|ts|g}|D]'}|dus#t|dkr$q|j|}t|ts9td|t |f| |qt|dkrK|j|}t|trY| | ||j j jdi|S)zZ Builds the environment string to be used when executing the remote task. Nrz2environment must be a dictionary, received %s (%s)r,)r%r/rr#r(rr3templatertypercclearr0rR env_prefix)r=raw_environment_outr environmentsrtemp_environmentr,r,r-rLs$         z&ActionBase._compute_environment_stringcCs t|ddS)z[ Determines if a tmp path should be created before the action is executed. TRANSFERS_FILESF)rr=r,r,r-rTms z ActionBase._early_needs_tmp_pathc Csz|jd}Wntttfy|jj}Ynw|jj}|jjr&|jjj nddk}|jj |p0||dkt j | p:||g}t |S)zE Determines if we are required and can do pipelining pipeliningrsunew)r0rqrsrr ValueErrorr1ralways_pipeline_modulesr{rhas_pipeliningrDEFAULT_KEEP_REMOTE_FILESall)r=r wrap_async is_enabledalways_pipelinebecome_exception conditionsr,r,r-_is_pipelining_enabledts  z!ActionBase._is_pipelining_enabledcCs|ddgS)zh Returns a list of admin users that are configured for the current shell plugin admin_usersroot)rrr,r,r-_get_admin_usersszActionBase._get_admin_usersc Cs`|did|d|dd}dD]}z |j|}W|Sty)Yqw|jj}|S)z= consistently get the 'remote_address' for the action plugin delegated_vars ansible_hostinventory_hostnameN) remote_addrhost)rr0rqrsr1r)r=tvarsr variationr,r,r-_get_remote_addrs$ zActionBase._get_remote_addrcCs\d}z |jd}W|Sty t|jddp|jj}Y|Sty-|jj}Y|Sw)z: consistently get the 'remote_user' for the action plugin N remote_user default_user)r0rqrsrr1rrr)r=rr,r,r-_get_remote_users  zActionBase._get_remote_usercCs<|jjsdS|}|}|d}t|o|||gvS)z} The user is not the same as the connection user and is not part of the shell configured admin users Fr)r0r{rrr}r)r=rrrr,r,r-_is_become_unprivilegeds  z"ActionBase._is_become_unprivilegedc Cst|jddr tj}n |j|jddddd}|}|jj}|jjj |||d}|j |dd}|dd kr|dd krAd }n2|dd kr`|jj d vr`t j dkr]d|d|df}nd}nd|dvrk|d}nd||df}d|vr|ddkr|d|d}t j dkrd|vr|ddkr|d|d7}t|d|_z|dd|d}|jj|ddd} Wn tyd} Ynw| dkrtd||f| |jj_| S)zE Create and return a temporary path on a remote box. rF remote_tmp~/.ansible/tmprzr)basefilesystemrSrrzAuthentication failure.)sshz6SSH 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 %drz, stdout output: %sz, stderr output: %sTz%s=rr/zPfailed to resolve remote temporary directory from %s: `%s` returned empty string)rr0rDEFAULT_LOCAL_TMP_remote_expand_userrrrR_generate_temp_dir_namemkdtempr transportr; verbosityrr5stripr join_path splitlinesrerrS) r=rrSbecome_unprivilegedrrrXoutput stdout_partsrr,r,r-rUsF          zActionBase._make_tmp_pathcCs|o |jo tj o d|vS)zLDetermine if temporary path should be deleted or kept by user request/configz-tmp-)r5rr)r=tmp_pathr,r,r-_should_remove_tmp_pathsz"ActionBase._should_remove_tmp_pathcCs|dur|jjjr|jjj}|s||rF|jjj|dd}|j|dd}|dddkr?td|d|d d fdSd|jj_dSdS) z$Remove a temporary path we created. NT)recurseFrrrz;Error deleting remote temporary files (rc: %s, stderr: %s})rzNo error string available.) r0rRrSrremoverrr;rE)r=rror tmp_rm_resr,r,r-rn s  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. )r0put_file)r= local_path remote_pathr,r,r-_transfer_fileszActionBase._transfer_filec Cst|tr t|}tjtjd\}}t|d}z t |dd}| |Wnt y9}zt dt |d}~ww||z|||Wt||St|w)zJ Copies the module data out to the temporary module path. )dirwbsurrogate_or_strictr"z>failure writing module data to temporary file for transfer: %sN)r#r%rtempfilemkstemprrosfdopenrwrite Exceptionrrflushcloserunlink)r=rdataafdafileafoer,r,r-_transfer_data/s$     zActionBase._transfer_datac Cs|dur|}t|jjddr|S|s4|r2||d}|ddkr2td|dt|d|S| d }|rJd }d }d |}d |} nd}d}d|}d|} | |||}|ddkrg|S|r||d}|ddkrtd|dt|d| ||}|ddkr|S|| vrtdz ||gt |d}Wnty} zWYd} ~ n d} ~ ww|ddkr|S||| }|ddkr|Std} |d} | dur||| }|ddkr|drtd| |rd} nd} ||| }|ddkr|S|dr:td| ||d|}|ddkr,|Std|dt|dtd|dt|d| f)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). N _IS_WINDOWSFzu+rwxrrz=Failed to set permissions on remote files (rc: {0}, err: {1})rrrxzr-xz{0} allow read,executezA+user:{0}:rx:allowrXzr-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+az2playbook_guide/playbooks_privilege_escalation.htmlcommon_remote_groupworld_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)rrr0rRr _remote_chmodrrrr}_remote_set_user_facl _remote_chownrr(r rr _remote_chgrpr;rE)r= remote_pathsrexecuteresr chmod_mode setfacl_modechmod_acl_modeposix_acl_moder- become_linkgroup group_moder,r,r- _fixup_perms2Is&                              zActionBase._fixup_perms2cC"|jj||}|j||d}|S)z. Issue a remote chmod command r)r0rRchmodr)r=pathsmoderrr:r,r,r-r4$zActionBase._remote_chmodcCrC)z. Issue a remote chown command r)r0rRchownr)r=rEuserrrr:r,r,r-r6,rGzActionBase._remote_chowncCrC)z. Issue a remote chgrp command r)r0rRchgrpr)r=rEr@rrr:r,r,r-r74rGzActionBase._remote_chgrpcCs$|jj|||}|j||d}|S)z0 Issue a remote call to setfacl r)r0rR set_user_faclr)r=rErIrFrrr:r,r,r-r5<sz ActionBase._remote_set_user_faclc Cs|dur td~t|||ddd}|jd||ddd}|d r=|d }|s.|d }|s5|d }td ||f|ddsId|dd<d|dvrYd|dd<|dSt|ddtsntdt|dd|dS)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 tmpdirFsha1)rfollow get_checksumget_sizechecksum_algorithmzansible.legacy.statT)rrrWrignore_unknown_optsfailed module_stderr module_stdoutrfz1Failed to get information on remote file (%s): %srr1checksumrzDInvalid checksum returned by stat: expected a string type but got %s) r;rEr%_execute_modulerrr#rr) r=rall_varsrMrVrVrmystatrfr,r,r-_execute_remote_statDs8          zActionBase._execute_remote_statc CsT|ds|S|tjjd}|d}|dkr9|d}t|jddr$n|r1|jjr1|r1d|}nd| p7d}|jj |}|j |dd }z |d  d } Wn ty^d } Ynw| s||jj }|j |dd d d } | ry| } n|} nt|dkr|jj j| g|dd R} n| } d tj| dvrtd|i| S)zK takes a remote path and performs tilde/$HOME expansion on the remote host ~rrrrFz~%srrrrNz..rzE'%s' returned an invalid relative home directory path containing '..') startswithrr"rsepr}rr0r{rrR expand_userrr rrepwdrrrdirnamerr) r=rrpathsep split_path expand_pathrrr)initial_fragmentr_expandedr,r,r-rns<       zActionBase._remote_expand_usercCs |drtdd|}|S)zC Removes the BECOME-SUCCESS message from the data. zBECOME-SUCCESS-z"^((\r)?\n)?BECOME-SUCCESS.*(\r)?\nr)r r\resub)r=r)r,r,r-_strip_success_messagesz!ActionBase._strip_success_messagerQrcCs,|jjr|js tdd|d<nd|d<tjjd|d}|jjp!||d<tj|d<|jj |d <t j |d <t |d <||d <| d tj|d<tj|d<tj|d<t|jd|d<|dsb| d|d<|jj|d<tj|d<|rvd|d<n|jjj|d<|jddd|d<||d<tjjd|d|d<dS)Nz.check mode is not supported for this operationT_ansible_check_modeFDEFAULT_NO_TARGET_SYSLOGr_ansible_no_log_ansible_debug _ansible_diff_ansible_verbosity_ansible_version_ansible_module_nameansible_syslog_facility_ansible_syslog_facility_ansible_selinux_special_fs!_ansible_string_conversion_action socket_path_ansible_socketansible_socket_ansible_shell_executable_ansible_keep_remote_files_ansible_tmpdirrrrz_ansible_remote_tmp_ansible_ignore_unknown_optsTARGET_LOG_INFO_ansible_target_log_info)r/rJrKrrrrno_log DEFAULT_DEBUGdiffr;r rrDEFAULT_SYSLOG_FACILITYDEFAULT_SELINUX_SPECIAL_FSSTRING_CONVERSION_ACTIONrr0r1 executablerrrRrSr)r=rrrWrQno_target_syslogr,r,r-_update_module_argss4         zActionBase._update_module_argsc 'Csp|dur td~|durtd~|jjj} |d|s,| dur,||jjj} |dur3t}|dur;|jj }|durC|jj }|j ||||dd} |sT|jj rj|j ddd} t|jj} |jjd | i|j|||d \} } }}td || s| d krtd || |_d}|| |s| dur||jjj} |jj|}|jj| d|}d}| dvr|jj| d}|s| dkrtd|| d kr|||n|||| dkrd}|D]\}}|d|tt|f7}q|||n| dvr||t|td| }| dur$|jj| =g}| r0|r0| |g}|r8||d}d}d}|r|jj!s|jdt|d \}} }}|jj|}|jj| |}||||||jj } dt"#dd}!| $dd%}"|"||!| |g}#|r|#&d||r|#|n|#d|'| s|#dd(d d!|#D}n|| r|}td"n|}|jjj)|| ||d#%}|rd$d%|D}|*||+|j,|||d&}$|-|$}%|%.d'd(rd(|_/d)|%vrt0|%d)t1rt0|%d)t2r|%d)|%d*<|%d)=td+t3|%|r/d|jj_d|%d,<d-|%vrHd.|%vrH|%4d-dpAd}&|&5|%d.<d/|%vrad0|%vra|%4d/dpZd}&|&5|%d0<|j6ry|%4d1durqi|%d1<|j7|%d1|j6<|j8r|%4d2durg|%d2<|%d29|j8|j:r|%4d3durg|%d3<|%d39|j:t;|%}%td4||f|%S)5zE Transfer and run a module along with its arguments. Nz_execute_module no longer honors the tmp parameter. Action plugins should set self._connection._shell.tmpdir to share the tmpdirz_execute_module no longer honors the delete_remote_tmp parameter. Action plugins should check self._connection._shell.tmpdir to see if a tmpdir existed before they were called to determine if they are responsible for removing it.r)rQ async_dirz~/.ansible_asyncrzANSIBLE_ASYNC_DIR)rrrWzUsing module file %sbinaryz'module (%s) is missing interpreter linez AnsiballZ_%s)oldnon_native_want_jsonrrNz transferring module to remote %srrz%s=%s )rrz"done transferring module to remoteTzansible.legacy.async_wrapperjrlJ)z#!_z -preserve_tmp css|]}t|VqdSN)r.0xr,r,r- psz-ActionBase._execute_module..zPipelining is enabled.)arg_pathcSsg|]}|r|qSr,r,rr,r,r- sz.ActionBase._execute_module..)rin_data_ansible_suppress_tmpdir_deleteFresultsansible_module_resultszSFound internal 'results' key in module return, renamed to 'ansible_module_results'.changedr stdout_linesr stderr_linesrwarnings deprecationsz"done with _execute_module (%s, %s))_low_level_execute_command() done: rc=%d, stdout=%s, stderr=%s)rrrrr)!r;rr0rRappend_commandrrr}r{rr rBECOME_ALLOW_SAME_USERanybuild_become_commandallow_executabler1rrrr2 get_basedircwd exec_commandr#rrrrQ readlinesrhr%r)r=rrrrencoding_errorschdirruserbuserrrrouterrr,r,r-rsP           z%ActionBase._low_level_execute_commandc Csji}td|jdt|dd|dd}|ddr0tdtj||t |d d f|S|d d d kr|d dvrEd |d<nZ|drOd|d<nP|drft j d krf|dt j krft j |d<n9td||jdt|d|dd}d|vr|d} |ddkrt | } ntdt|||d<t | |d<|rt|} t j d kr| tjt j krt j |d<nbtd|zt|d } | } Wdn1swYWnty} z td |t| fd} ~ wwd!| vrd|d"<n |r||d#<n||d#<t | |d$<n td%d&|d#<||d$<|jjr3d|vr*d |d<d$|vr3d'|d$<|S)(Nz4Going to peek to see if file has changed permissionszansible.legacy.fileT)r _diff_peek)rrrWrrRFz,Failed to get diff between '%s' and '%s': %srfrrrstate)Nabsentbeforeappears_binaryr dst_binarysize dst_largerzSlurping the file %szansible.legacy.slurp)rcontentr!base64z.unknown encoding in content option, failed: %s before_header src_largerz!Reading local copy of the file %srbz8Unexpected error while reading source (%s) for diff: %s  src_binary after_headerafterzsource of file passed inzdynamically generatedzX [[ Diff output has been hidden because 'no_log: true' was specified for this result ]] )r;rrWr%rrEr"rbasenamerrMAX_FILE_SIZE_FOR_DIFFr b64decoderrrST_SIZEopenreadr%r/r)r= destinationsourcerWr source_filer peek_result dest_result dest_contentsstr src_contentsr-r,r,r-_get_diff_dataDsr   (   "               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/get_search_pathr2path_dwim_relative_stack)r=r`needle path_stackr,r,r- _find_needles zActionBase._find_needle)NN)NNNNNN)Fr)NT)TN)rQr)NNNNFNFF)TNNrN)0__name__ __module__ __qualname____doc__rMrLBYPASS_HOST_LOOPr_requires_connectionrKrHrDrr[rmrprwr}rrrrrrTrrrrrrUrrnrr.rBr4r6r7r5rZrrhrrWrrr rr,r,r,r-r.4sn + 2   o!  ?   \     *6 @ V 3 P Lr.)= __future__rrrr"rrfrrr abcrrcollections.abcransiblerransible.errorsrrr r r ansible.executor.module_commonr &ansible.executor.interpreter_discoveryr r$ansible.module_utils.common.arg_specransible.module_utils.errorsransible.module_utils.json_utilsransible.module_utils.sixrrr+ansible.module_utils.common.text.convertersrrransible.parsing.utils.jsonifyransible.releaseransible.utils.collection_loaderransible.utils.displayransible.utils.unsafe_proxyrransible.vars.cleanransible.utils.plugin_docsrr;r'r.r,r,r,r-s<