o nnhaP@sddlmZddlZddlZdZejekr7eeeddd e e edd ej d ed ddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl!Z!dd l"m#Z#zddl$Z$dZ%Wn e&yd Z%Ynwzdd l'm(Z(m)Z*e+e(doe*,Z-Wn e&e.fyd Z-Ynwd Z/z ddl0m1Z1dZ/Wn e&yYnwe2dZ3d dl4m5Z5m6Z6m7Z7ddl8m9Z9m:Z;mm?Z?ddl@mAZAmBZBmCZCmDZDddlEZEddZFeFZGddlHmIZImJZJmKZKmLZLmMZMmNZNmOZOddlPmQZQddlRmSZSddlTmUZVmWZXmYZYmZZZm[Z[m\Z\m]Z]m^Z^ddl_m`Z`maZambZbddlcmdZdmeZemfZfmgZgmhZhmiZiddljmkZkmlZlmmZmddlnmoZompZpddlqmrZsddltmuZumvZvmwZwmxZxdd lymzZzm{Z{m|Z|m}Z}e~eIeLfZed!ejZe Zdaeed"d#ed$d#ed$d#ed$d#ed$d#ed$d#ed$d#ed$d%gd&ed'd edd(gfd)d* Zed+Zed,Zed-Zed.Zd/d0Zd1d2Zd3d4ZrdAd5d6Zd7d8ZdBd9d:ZGd;d<dZd?d@ZdS)C) annotationsN)Tz2ansible-core requires a minimum of Python version .z. Current version: )failedmsg)reduceF)journaldaemonsendv)selinux) to_nativeto_bytesto_text)jsonifycontainer_to_bytescontainer_to_text)ModuleArgumentSpecValidator)lenient_lowercasebytes_to_humanhuman_to_bytes SIZE_RANGESc CsJi}tjD]}tt|d}|r"z|Wn tyYqw|||<q|S)zSReturn a dictionary of available hash function names and their associated function.N)hashlibalgorithms_availablegetattr Exception) algorithmsalgorithm_namealgorithm_funcr!E/usr/local/lib/python3.10/dist-packages/ansible/module_utils/basic.py_get_available_hash_algorithms\s    r#)KeysViewMappingMutableMappingSequenceMutableSequenceSet MutableSet)get_best_parsable_locale) get_bin_path) _PERM_BITS _DEFAULT_PERM is_executableformat_attributesget_flags_from_attributesFILE_ATTRIBUTESS_IXANYS_IRWU_RWG_RWO)get_distributionget_distribution_versionget_platform_subclass) env_fallback remove_values sanitize_keysDEFAULT_TYPE_VALIDATORS PASS_VARS PASS_BOOLS)AnsibleFallbackNotFoundAnsibleValidationErrorMultipleUnsupportedError)check_missing_parameters safe_eval)get_all_subclasses)BOOLEANSBOOLEANS_FALSE BOOLEANS_TRUEboolean) deprecateget_deprecation_messagesget_warning_messageswarnzB^(?:.+[-_\s])?pass(?:[-_\s]?(?:word|phrase|wrd|wd)?)(?:[-_\s].+)?$raw)typestrattr)rMaliasesboolANSIBLE_UNSAFE_WRITES)rMdefaultfallback) modeownergroupseuserseroleselevelsetype attributes unsafe_writesz^[-]{0,2}pass[-]?(word|wd)?z[+=-]z^[ugo]+$z^[rwxXstugo]*$cCstS)a+ **Deprecated** Use :py:func:`platform.system` directly. :returns: Name of the platform the module is running on in a native string Returns a native string that labels the platform ("Linux", "Solaris", etc). Currently, this is the result of calling :py:func:`platform.system`. )platformsystemr!r!r!r" get_platforms r`cOst|}t|||S)zV**Deprecated**: Use ansible.module_utils.common.sys_info.get_platform_subclass instead)r7super__new__)clsargskwargs platform_clsr!r!r"load_platform_subclasssrgcCs tt|S)zQ**Deprecated**: Use ansible.module_utils.common._utils.get_all_subclasses instead)list_get_all_subclasses)rcr!r!r"rC rCc CsBt|}g}t|}|}d}|rz |dd|}Wnty,|d|d|Yngwd}|}|sqz |dd|}Wn tyGd}Ynwz |d|d|}Wntyn|dkrj|d|d|Yn|}Yq1w|r3|r|d||||dd|d|||d|}|sd |}|rt||}|S) z; Remove strings that look like passwords from log messages r @rNz://:r********r)rlenrindex ValueErrorinsertindexjoinr9)data no_log_valuesoutputbegin prev_beginsependsep_search_endr!r!r"heuristic_log_sanitizesP      ( r|cCstdurt}n4ttjdkr3tjtjdr(ttjdd}|}| ntjdj ddd}ntj j }|az t |d}WntyWtdtdYnwz|dWStyptd tdYdSw) a1 read the modules parameters and store them globally. This function may be needed for certain very dynamic custom modules which want to process the parameters that are being handed the module. Since this is so closely tied to the implementation of modules we cannot guarantee API stability for it (it may change between versions) however we will try not to break it gratuitously. It is certainly more future-proof to call this function and consume its outputs than to implement the logic inside it as a copy in your own code. Nr rbutf-8surrogateescapeerrorsz {"msg": "Error: Module unable to decode stdin/parameters as valid JSON. Unable to parse what parameters were passed", "failed": true}ANSIBLE_MODULE_ARGSz {"msg": "Error: Module unable to locate ANSIBLE_MODULE_ARGS in JSON data from stdin. Unable to figure out what parameters were passed", "failed": true}) _ANSIBLE_ARGSrnsysargvospathisfileopenreadcloseencodestdinbufferjsonloadsdecoderpprintexitKeyError)rfdparamsr!r!r" _load_params*s,      rcCsDt}d||tjf}|r|d|7}|r|d|7}|d7}|S)NzDFailed to import the required Python library (%s) on %s's Python %s.z This is required %s.z See %s for more info.z Please read the module documentation and install it in the appropriate location. If the required library is installed, but Ansible is using the wrong Python interpreter, please consult the documentation on ansible_python_interpreter)r^noder executable)libraryreasonurlhostnamerr!r!r"missing_required_libZs  rc@sTeZdZ    dddZeddZddZdd d Zdd d Zd dZ ddZ ddZ dddZ ddZ dddZddZddZdd Zdd!d"Zdd#d$Zdd%d&Zdd'd(Zdd)d*Zdd+d,Zed-d.Zed/d0Zedd1d2Zdd3d4Zd5d6Zdd7d8Zdd9d:Z d;d<Z!d=d>Z"dd?d@Z#ddAdBZ$dCdDZ%dEdFZ&dGdHZ'ddIdJZ(dKdLZ)dMdNZ*ddOdPZ+dQdRZ,dSdTZ-dUdVZ.dWdXZ/dYdZZ0d[d\Z1d]d^Z2d_d`Z3ddadbZ4dcddZ5dedfZ6dgdhZ7didjZ8dkdlZ9dmdnZ:dodpZ;ddqdrZ  x ddydzZ?d{d|Z@d}d~ZAeAZBdddZCeDZDeddZEdS) AnsibleModuleFNc Cstjt|_||_||_d|_||_||_ ||_ ||_ ||_ | |_ | |_g|_d|_d|_d|_d|_d|_d|_i|_i|_d|_i|_g|_t|_d|_|retD]\} } | |jvrd| |j| <qVt |_!|"|#|$t%|j|j |j |j |j |j|_&|j&'|j(|_)|j(*|j)j+|j!*|j)j,|j*|j)j-z|j)j.d} t/| t0r|j1rd} Wn t2yd} Ynw| r|j)j.j3}t/| t0rdj4|jd|d}|j5|d |jr|js|j6d d |jd t7|_8|j s|9d|_:d|_;d|_<|=dS) a7 Common code for quickly building an ansible module in Python (although you can write modules with anything that can return JSON). See :ref:`developing_modules_general` for a general introduction and :ref:`developing_program_flow_modules` for more detailed explanation. FNLOG_USERrrz1Unsupported parameters for ({name}) {kind}: {msg}module)namekindrrTz.remote module (%s) does not support check mode)skippedr)>rrbasename__file___name argument_specsupports_check_mode check_mode bypass_checksno_logmutually_exclusiverequired_togetherrequired_one_of required_if required_by cleanup_files_debug_diff _socket_path_shell_syslog_facility _verbosityrun_command_environ_update_clean_string_conversion_actionrP _legal_inputsrh_options_context_tmpdirFILE_COMMON_ARGUMENTSitemssetru _check_localer_set_internal_propertiesr validatorvalidatervalidation_resultupdatevalidated_parameters_no_log_values_aliasesr isinstancer@_ignore_unknown_opts IndexErrorrformat fail_json exit_jsonr; _CHECK_ARGUMENT_TYPES_DISPATCHER_log_invocation_selinux_enabled_selinux_mls_enabled_selinux_initial_context_set_cwd)selfrrrrrradd_file_common_argsrrrkverrorrr!r!r"__init__is          zAnsibleModule.__init__c Cs(|jdurd}|jdurtjtj|j}|durStj|sSz tj|ddWn!tt fyK}z| d|t |fd}WYd}~n d}~ww| d|dt }z t j||d}Wn!tt fy}z|jd||t |fdWYd}~nd}~ww|jsttj|||_|jS) Ni)rUzCUnable to use %s as temporary directory, failing back to system: %szModule remote_tmp %s did not exist and was created with a mode of 0700, this may cause issues when running as another user. To avoid this, create the remote_tmp dir with the correct permissions manuallyzansible-moduletmp-%s-)prefixdirzDFailed to create remote module tmp path at dir %s with prefix %s: %sr)r _remote_tmprr expanduser expandvarsexistsmakedirsOSErrorIOErrorrKrtimetempfilemkdtempr_keep_remote_filesatexitregistershutilrmtree)rbasedirebasefiletmpdirr!r!r"rs@     zAnsibleModule.tmpdircCst||d|dS)Nz [WARNING] %s)rKlog)rwarningr!r!r"rKszAnsibleModule.warncCs\|dur |dur tdt||||d|dur#|d||fdS|d||fdS)Nz=implementation error -- version and date must not both be setversiondatecollection_namezEPRECATION WARNING] %s %s)AssertionErrorrHr)rrrrrr!r!r"rHs zAnsibleModule.deprecatec CsH|dur|d|dd}|duriStjtj|}t|dd}|ddr:tj|r:tj|}t|}|dd}|d d}|d d}|d d}|d d}|d d} |dd} ||| g} | rr| | | |} t t | D]} | dur| | dkr| | | | <q}|dd}t||||||| | | |d S)a many modules deal with files, this encapsulates common options that the file module accepts such that it is directly available to all modules and they can share code. Allows to overwrite the path/dest module argument by providing path. Nrdestsurrogate_or_strictrfollowFrUrVrWrXrYr[rZ_defaultr\) rrUrVrWrXrYr[rZ secontextr\)getrrrrrislinkrealpathrselinux_mls_enabledappendselinux_default_contextrangerndict)rrrb_pathrUrVrWrXrYr[rZrdefault_secontextir\r!r!r"load_file_common_argumentss<               z(AnsibleModule.load_file_common_argumentscC"|jdurto tdk|_|jSNr )r HAVE_SELINUXris_selinux_mls_enabledrr!r!r"r= z!AnsibleModule.selinux_mls_enabledcCr r )rr ris_selinux_enabledrr!r!r"selinux_enabledCrzAnsibleModule.selinux_enabledcCs.|jdurgd|_|r|jd|jS)NNNN)rrrrr!r!r"selinux_initial_contextJs   z%AnsibleModule.selinux_initial_contextrcCsh|}|s |Sz tt|dd|}Wn ty!|YSw|ddkr*|S|ddd}|S)Nrrrr rlr)rrr matchpathconrrsplit)rrrUcontextretr!r!r"rSs  z%AnsibleModule.selinux_default_contextc Cs|}|s |Sz tt|dd}Wn)ty>}z|jtjkr-|j|d|dn|j|ddWYd}~nd}~ww|ddkrG|S|d d d }|S) Nrrzpath %s does not existrrz"failed to retrieve selinux contextrrr rlr) rrrlgetfilecon_rawrrerrnoENOENTrr)rrrrrr!r!r"selinux_contextbs  zAnsibleModule.selinux_contextTcCsBt|dd}|rtjtj|}t|}|j}|j}||fSNrr)rrrrrlstatst_uidst_gid)rrexpandrstuidgidr!r!r"user_and_groupts  zAnsibleModule.user_and_groupcCsTtjttjtj|dd}tj|s$tj|}tj|rt|ddS)z Takes a path and returns its mount point :param path: a string type with a filesystem path :returns: the path to the mount point as a text type rr) rrrrrrismountdirnamer)rrrr!r!r"find_mount_point}s $   zAnsibleModule.find_mount_pointc Csztdd}|}|Wn tyYdSw||}|D],}|dd\}}}} } t|t|krM|jD]} | |vrL||} d| fSq9q!dS)z Returns a tuple containing (True, selinux_context) if the given path is on a NFS or other 'special' fs mount point, otherwise the return will be (False, None). z /proc/mountsrFN T) r readlinesrrr*rr_selinux_special_fsr) rrf mount_datapath_mount_pointlinedevice mount_pointfstypeoptionsrestfsspecial_contextr!r!r"is_special_selinux_paths$      z%AnsibleModule.is_special_selinux_pathcCs$|s|S||}|||dSNF)rrset_context_if_different)rrchangedrr!r!r"set_default_selinux_contexts z)AnsibleModule.set_default_selinux_contextc Csr|s|S||r dS||}t|}||\}}|r"|}n0tt|D])} t|| krQ|| durE|| || krE|| || <q(|| durQ|| || <q(||kr|durvd|vrbi|d<||dd<d|vrpi|d<||dd<z|jr}WdSt t |d |} Wn t y} z|j |dt | |||dWYd} ~ nd} ~ ww| dkr|j |d d d}|S) NTbeforerafterrlzinvalid selinux context: %s)rr new_context cur_context input_wasrzset selinux context failedr)rcheck_file_absent_if_check_moderrhr<rrnrr lsetfileconrrsrr) rrrr?diffrDrC is_special_se sp_contextr rcrr!r!r"r>sL       z&AnsibleModule.set_context_if_differentc Cs`|dur|St|dd}|rtjtj|}||rdS|||\}}zt|} Wn(tyUzt |j } Wnt yRt |}|j|d|dYnwYnw|| kr|durzd|vrfi|d<||dd<d|vrti|d<| |dd<|jrdSz t|| d Wn#ttfy} zt |}|j|d t | dWYd} ~ nd} ~ wwd}|S) NrrTz'chown failed: failed to look up user %srrArVrBrzchown failed: %s)rrrrrrFr'intrppwdgetpwnampw_uidrrrrlchownrr) rrrVr?rHr#rorig_uidorig_gidr%rr!r!r"set_owner_if_differentsL       "z$AnsibleModule.set_owner_if_differentc CsB|dur|St|dd}|rtjtj|}||rdS|||\}}zt|} Wn(tyUzt |j } Wnt yRt |}|j|d|dYnwYnw|| kr|durzd|vrfi|d<||dd<d|vrti|d<| |dd<|jrdSz t|d | Wntyt |}|j|d dYnwd}|S) NrrTz(chgrp failed: failed to look up group %srrArWrBrz chgrp failed)rrrrrrFr'rLrpgrpgetgrnamgr_gidrrrrrPr) rrrWr?rHr#rrQrRr&r!r!r"set_group_if_differentsJ        z$AnsibleModule.set_group_if_differentc Cs|dur|St|dd}|rtjtj|}||rdSt|}t|tsvzt|d}WnEt yuz| ||}Wn t y_}zt |}|j |dt |dWYd}~nd}~ww|t|krst |}|j |d|dYnwt|j} | |krN|durd|vri|d<d | |dd <d |vri|d <d ||d d <|jrdSz;ttd rt||n-tj|st||n t|} t||t|} | j| jkrt|t| jWnVty}z&tj|r|jtjtjtjfvrn |jtjtjfvr nWYd}~n(d}~wt y;}zt |}|j |d t |tdWYd}~nd}~wwt|}t|j} | | krNd}|S)NrrTz&mode must be in octal or symbolic form)rrdetailsz6Invalid mode supplied, only permission info is allowedrA0%03orUrBlchmodz chmod failedrrrY exception)rrrrrrFr rrLr_symbolic_mode_to_octalrrrstatS_IMODEst_moderhasattrr[rchmodrrEACCESEPERMEROFSrELOOP traceback format_exc) rrrUr?rHr#r path_statr prev_modeunderlying_statnew_underlying_statnew_moder!r!r"set_mode_if_different(s                z#AnsibleModule.set_mode_if_differentc Cs~|dur|St|dd}|rtjtj|}||rdS|j|dd}d}|dr7|d}|d d}|r|d d |ksE|d kr| d } | r| d||f|g} d}|dur~d|vrci|d<|d |dd<d|vrti|d<d||f|dd<|j sz| | \} } } | dks| rt d| | W|St y} z|j t|dt| tdWYd} ~ |Sd} ~ ww|S)NrrTFinclude_version=)-+rr attr_flagsrrschattrz%s%srAr\rBz"Error while setting attributes: %sz chattr failedr\)rrrrrrFget_file_attributes startswithrr,r run_commandrrrrrhri)rrr\r?rHr#rexistingattr_modattrcmdrKouterrrr!r!r"set_attributes_if_different}sN        z)AnsibleModule.set_attributes_if_differentc Csi}|dd}|rX|rdnd}|||g}z8||\}}}|dkrK|} d} |r4d} | d|d<| | dd |d <t|d |d <W|SW|StyWY|Sw|S) NlsattrFz-vdz-drr rrsrrur\)r,ryrstripreplacer0r) rrrqrvr|flagsrKr}r~resattr_flags_idxr!r!r"rws.    z!AnsibleModule.get_file_attributesc Cst|j}|dD]V}t|}t|}|d}|dk}|dks(|dkr*d}t|s5t d|t |D]'\} } t | sHt d||D]} | || | ||} | | || | |}qJq9q |S)z This enables symbolic chmod string parsing as stated in the chmod man-page This includes things like: "u=rw-x+X,g=r-x+X,o=r-x+X" ,rraugoz$bad symbolic permission for mode: %s)r_r`rarMODE_OPERATOR_REfindallpopUSERS_REmatchrp enumeratePERMS_RE#_get_octal_mode_from_symbolic_perms_apply_operation_to_mode) rcrj symbolic_modernrUpermlistopersusers use_umaskidxpermsuser mode_to_applyr!r!r"r^s&         z%AnsibleModule._symbolic_mode_to_octalcCs|dkr0|dkrtjtjB}n|dkrtjtjB}n |dkr$tjtjB}|tA}||@|B}|S|dkr:||B}|S|dkrD|||@}|S)Nrrugortrs)r_S_IRWXUS_ISUIDS_IRWXGS_ISGIDS_IRWXOS_ISVTX PERM_BITS)roperatorr current_modemask inverse_maskrnr!r!r"rs    z&AnsibleModule._apply_operation_to_modec s|dur t|j}t|j}|t@dk}|p|}td}t||tA} |r:dtjidtj idtj id} n ddiddiddid} |rM| tj @ntj |rV| tj @ntj |r_| tj@ntjtj d|tj@|tj@d>|tj@d>d|r}| tj@ntj|r| tj@ntj|r| tj @ntj tjd|tj@d?|tj@|tj@d>d|r| tj@ntj|r| tj@ntj|r| tj @ntj dtj|tj@d?|tj@d?|tj@dd| D] \} } | | q݇fdd} t| |dS) NrX)rrrr)r+wxstrrrcs||BSNr!)rUpermruser_perms_to_modesr!r" or_reduce<zDAnsibleModule._get_octal_mode_from_symbolic_perms..or_reduce)r_r`raS_ISDIRr3rumaskrS_IXUSRS_IXGRPS_IXOTHS_IRUSRS_IWUSRrrrrS_IRGRPS_IWGRPrS_IROTHS_IWOTHrrrr )rjrrrrk is_directoryhas_x_permissionsapply_X_permissionr rev_umaskX_permskeyvaluerr!rr"rsb              z1AnsibleModule._get_octal_mode_from_symbolic_permscCs||d|d||}||d|d|||}||d|d|||}||d|d|||}||d|d|||}|S)NrrrVrWrUr\)r>rSrWrorr file_argsr?rHr#r!r!r"set_fs_attributes_if_differentAs z,AnsibleModule.set_fs_attributes_if_differentcCs|jo tj| Sr)rrrr)r file_pathr!r!r"rFTz-AnsibleModule.check_file_absent_if_check_modecC|||||Srrrr!r!r"%set_directory_attributes_if_differentWrz3AnsibleModule.set_directory_attributes_if_differentcCrrrrr!r!r" set_file_attributes_if_differentZrz.AnsibleModule.set_file_attributes_if_differentc Cs`|d|dd}|dur|St|dd}tj|r||\}}||d<||d<z t|d}Wn tyAt |}Ynwz t |d}Wn tyXt |}Ynw||d <||d <t |}d t |t j|d <tj|r}d |d<ntj|rd|d<nt |jdkrd|d<nd|d<|rd|||d<|t j|d<|S)z for results that are files, supplement the info about the file in the return path with stats about the file path. rrNrrr%r&rrVrWrZrUlinkstate directoryr hardfilerlrsize)rrrrrr'rMgetpwuidrrNrTgetgrgidr r_r`ST_MODErisdirst_nlinkrrsrST_SIZE) rrerrr%r&rrWr$r!r!r" add_path_info]sB            zAnsibleModule.add_path_infoc Csz ttjdWdStjy/t|}ttj||tjd<|tjd<|tjd<YdStyN}z|jdt |t dWYd}~dSd}~ww)z Uses the locale module to test the currently set locale (per the LANG and LC_CTYPE environment settings) rLANGLC_ALL LC_MESSAGESzLAn unknown error was encountered while attempting to validate the locale: %srr]N) locale setlocalerErrorr+renvironrrrrhri)r best_localerr!r!r"rs   zAnsibleModule._check_localecCs|dur|j}|dur|j}tD]K}d|}||vrD|tvr.t|t|d|||n t|t|d||||jvrC|j|=qt|t|ds[t|t|dt|dqdS)Nz _ansible_%srr )rrr<r=setattrrGrb)rrmodule_parametersr param_keyr!r!r"rs"  z&AnsibleModule._set_internal_propertiescCs t|||Sr)rB)rrlocalsinclude_exceptionsr!r!r"rBs zAnsibleModule.safe_evalcCs t|_dS)z read the input and set the params attribute. This method is for backwards compatibility. The guts of the function were moved out in 2.1 so that custom modules could read the parameters. N)rrrr!r!r"rs zAnsibleModule._load_paramsc CstrFz d|j}tt|jtj}tt|d|ttj|WdSt t fyE}z|j dt |t |dWYd}~dSd}~wwdS)N ansible-%srzFailed to log to syslog (%s). To proceed anyway, disable syslog logging by setting no_target_syslog to True in your Ansible config.)rr] msg_to_log) HAS_SYSLOGrrsyslogrropenlogrNLOG_INFO TypeErrorrprrrhri)rrrfacilityrr!r!r"_log_to_syslogs" zAnsibleModule._log_to_syslogcCs|jr |d|dSdS)Nz [debug] %s)rr)rrr!r!r"debugszAnsibleModule.debugc Cs~|js|dur t}d|j}t|tr|dd}t|ttfs)tdt|t|tr5|dd}n|}|j rBd |j |g}t ||j }t rdtjtfg}|D]}|t||}}|dvrjd|}|||fqUz4trtt|jtjd ?} tjd d ||f| d t|ntjd d d ||fit|WdSWdSty||YdSw||dSdS)Nrr~rzmsg should be a string (got %s)r-MODULE) PRIORITYMESSAGE MESSAGE_ID CODE_FILE CODE_LINE CODE_FUNCSYSLOG_FACILITYSYSLOG_IDENTIFIER SYSLOG_PIDz_%srz%s %s)rrrr!)rrrrbytesrrNrrM_target_log_inforsr9ru has_journalrrrrupperrrrrrrr sendrr) rrlog_argsr journal_msg journal_argsargrrrr!r!r"rsV       zAnsibleModule.logcCst}|jD]X}|j||}|j|i}|dd}|dur1t|r1d||<|d|q||r;d||<q|j|}t |t t fsLt |}n t |t rV| d}t ||j||<qdd|D}|rrd d |}nd }|j||d dS) z! log that ansible ran the module rNNOT_LOGGING_PASSWORDz Module did not set no_log for %sNOT_LOGGING_PARAMETERr~cSs$g|]\}}dt|t|fqS)z%s=%sr).0rvalr!r!r" +s$z1AnsibleModule._log_invocation..zInvoked with %sr-Invoked)r)rrrPrrPASSWORD_MATCHsearchrKrGrrNrrr|rurrsr)rrparamcanonarg_optsr param_valrr!r!r"rs*        zAnsibleModule._log_invocationc Cszt}t|tjtjBst|WStyN|jtjdt fD]#}zt|tjtjBr@t ||WYSWq'tyJYq'wYdSw)Nz$HOME) rgetcwdaccessF_OKR_OKrrrrr gettempdirchdir)rcwdr!r!r"r3s$    zAnsibleModule._set_cwdc Csdd}z t||d}W|Sty1}z|r|jt|dn|WYd}~SWYd}~|Sd}~ww)aQ Find system executable in PATH. :param arg: The executable to find. :param required: if executable is not found and required is ``True``, fail_json :param opt_dirs: optional list of directories to search in addition to ``PATH`` :returns: if found return full path; otherwise return None N)ropt_dirsr)r,rprr)rrrequiredrbin_pathrr!r!r"r,Gs  zAnsibleModule.get_bin_pathc CsN|dur|Szt|WSty&}z|jt|dWYd}~dSd}~ww)z!Convert the argument to a booleanNr)rGrrr)rrrr!r!r"rG\s zAnsibleModule.booleanc CsBzt|WSty }z|jt|dWYd}~dSd}~wwNr)r UnicodeErrorrr)rrtrr!r!r"rfs  zAnsibleModule.jsonifycCs t|Sr)rr)rrtr!r!r" from_jsonl zAnsibleModule.from_jsoncCs||jvr |j|dSdSr)rrrrr!r!r"add_cleanup_fileos zAnsibleModule.add_cleanup_filecCs|jD]}||qdSr)rcleanupr#r!r!r"do_cleanup_filesss  zAnsibleModule.do_cleanup_filesc Cs~||d|vrd|ji|d<d|vr/t|dtr(|dD]}||qn||dt}|r8||d<d|vrt|dtr|dD]8}t|tr`t|dkr`|j|d|ddqGt|t rz|j|d | d | d | d d qG||qGn||dt }|r||d<i}| D]\}}|dust|t r|||<qt||j}||td||dS)N invocation module_argswarnings deprecationsrr )rrrrrrz %s)rrrrhrKrJ SEQUENCETYPErnrHr%rrIrrQr9rurrr) rrerr)dr* preservedrrr!r!r"_return_formattedwsF         zAnsibleModule._return_formattedcKs |||tddS)z' return from the module, without error rN)r&r/rr)rrer!r!r"rs zAnsibleModule.exit_jsoncKspd|d<||d<d|vr(tdr(|js|jdkr(dttd|d<|||t dd S) z/ return from the module, with an error message Trrr]r+rrr N) rexc_inforrrsrh format_tbr&r/r)rrrer!r!r"rs$ zAnsibleModule.fail_jsonc CsR|sdSz t|j|WdSty(}z|jt|dWYd}~dSd}~wwr)rArrrr)rrequired_paramsrr!r!r"fail_on_missing_paramssz$AnsibleModule.fail_on_missing_paramsc Cst|dd}tj|sdStj|r|jd|dt|dr$|}nzt|}WntyB|jd||d tfdYnwd }t tj |d }| |}|ra| || |}|sU||S) zh Return hex digest of local file for a digest_method specified by name, or None if file is not present. rrNz+attempted to take checksum of directory: %sr hexdigestzFCould not hash file '%s' with algorithm '%s'. Available algorithms: %sz, ir})rrrrrrrbAVAILABLE_HASH_ALGORITHMSrrsrrrrrr4)rfilename algorithm b_filename digest_method blocksizeinfileblockr!r!r"digest_from_files.         zAnsibleModule.digest_from_filecCsdtvrtd||dS)a Return MD5 hex digest of local file using digest_from_file(). Do not use this function unless you have no other choice for: 1) Optional backwards compatibility 2) Compatibility with a third party protocol This function will not work on systems complying with FIPS-140-2. Most uses of this function can use the module.sha1 function instead. md5z1MD5 not available. Possibly running in FIPS mode)r5rpr=rr6r!r!r"r>s  zAnsibleModule.md5cC ||dS)z@ Return SHA1 hex digest of local file using digest_from_file(). sha1r=r?r!r!r"rArjzAnsibleModule.sha1cCr@)zC Return SHA-256 hex digest of local file using digest_from_file(). sha256rBr?r!r!r"rCrjzAnsibleModule.sha256c Csd}tj|rItdtt}d|t|f}z |||W|Stj t fyH}z|j d||t |fdWYd}~|Sd}~ww|S)z[make a date-marked backup of the specified file, return True or False on success or failurerz%Y-%m-%d@%H:%M:%S~z%s.%s.%sz%Could not make backup of %s to %s: %srN) rrrrstrftime localtimegetpidpreserved_copyrrrrr)rfn backupdestextrr!r!r" backup_locals $zAnsibleModule.backup_localc Cs`tj|r.zt|WdSty-}ztjd|t|fWYd}~dSd}~wwdS)Nzcould not cleanup %s: %s) rrrunlinkrrstderrwriter)rtmpfilerr!r!r"r% s &zAnsibleModule.cleanupc Cst|||r||}|||dz#t|}t|}|r8|j|jks/|j|jkr8t ||j|jWnt yR}z |j t j krHWYd}~nd}~ww|j |dd}|dd}|||ddS)z=Copy a file with preserved ownership, permissions and contextFNrprurT)rcopy2rrr>rr_r!r"chownrrrerwrr)rsrcrr dest_stattmp_statrcurrent_attribsr!r!r"rGs&       zAnsibleModule.preserved_copyc Csd}d}t|dd}t|dd}tj|r_|r_z#t|}t||j|jt ||tj |t t fdWnt yT} z | j t jkrJWYd} ~ nd} ~ ww|r^||}n |rh||}tj| } z t||Wntt fy3} z| j t jt jt jt jt jfvr|jd||t| ftdntj|} tj|} d} d}zCz tjd| | d\}}Wn t tfy} zd tj|t| f} WYd} ~ nd} ~ wwW| r|r| ||n"|j| tdn| r|r| ||w|j| tdww|r)t|dd}zzt!|ztj"|||r-tj#ntj$d Wnt yM|rEt#||nt$||Ynw|rZ|%||d z1t|}|r|r}|j|jkst|j|jkr}t||j|jtj |t t fdWnt y} z| j t jkrWYd} ~ nd} ~ wwzt||Wn9tj&t tfy} z(|r| j t jkr| ||n|jd |||t| ftdWYd} ~ nd} ~ wwWn1tj&t tfy} z |r| ||n|jd ||t| ftdWYd} ~ nd} ~ wwW|'|n|'|wWYd} ~ nd} ~ ww| r}t(d}t(|t)|t*|@ttj|}z|j+tj,@rft|t-|jn t|t-t.Wn t y|Ynw|r|%||d dSdS)aatomically move src to dest, copying attributes from dest, returns true on success it uses os.rename to ensure this as it is an atomic operation, rest of the function is to work around limitations, corner cases and ensure selinux context is saved if possibleNrr)timesz$Could not replace file: %s to %s: %srs .ansible_tmp)rrsuffixzQThe destination directory (%s) is not writable by the current user. Error was: %s) copy_functionFz=Unable to make %s into to %s, failed final rename from %s: %sz$Failed to replace file: %s to %s: %sr)/rrrrr_rQr!r"rcopystatutimerrrrerrrrenamerEXDEVrdETXTBSYEBUSYrrrhrir)rrmkstemp_unsafe_writesrmovecopyrPr>rr%rrcr4rargeteuidgetegid)rrRrr]keep_dest_attrsrrSb_srcb_destrcreating b_dest_dirb_suffix error_msg tmp_dest_name tmp_dest_fdb_tmp_dest_namerTr dest_dir_statr!r!r" atomic_move4s        $  $  "   "  F   zAnsibleModule.atomic_movec Csz6d}}z#t|d}t|d}t||W|r||r&|WdSWdS|r/||r6|wwtjttfy]}z|jd||t|ft dWYd}~dSd}~ww)Nwbr}z/Could not write data to file (%s) from (%s): %sr) rr copyfileobjrrrrrrrhri)rrRrout_destin_srcrr!r!r"r`s,   zAnsibleModule._unsafe_writescCs|jsd|}t|trt|}t|ttfrt|}g}d}dd|DD]3}|r1d}|dq%t |rM| d}|dkrK|d|d|q%d}t ||j }||q%d d d|D|_|jS) NFcss|]}t|VqdSrr )r rr!r!r" sz,AnsibleModule._clean_args..rmrrrz %s=********Tr-css|]}t|VqdSr)shlexquote)r rr!r!r"rus)rrrrrNrvrr PASSWD_ARG_RErfindr|rurs)rrd to_clean_args clean_args is_passwdrsep_idxr!r!r" _clean_argss.       zAnsibleModule._clean_argsr~rc( sd|_t|tttfsd}|jd||dd}| rPt|tr)ddd|D}nt|d d }|r=t|d d }|d |g}n4|jd vrMt|jd d d |g}n$d }n!t|ttfr`t t |dd }|rjdd|D}ndd|D}d}| rt| trt| dd } z t | t j}Wnt jy|jddYnwd}d}d}tj}||jpi|| pi|r|dd}|rd||f|d<n||d<d|vrdd|d dD}|rt|rd||d<|rtj}fdd}t||||tjtj||d}|r||d<|r0ttjtj|d d }tj|r%||d<n |s0|jd|dz%|jr@|d | |tj!|fi|}|rP||d!}d!} t"t#d"r_t#$}!nt#%}!|rw|sm|d#7}t|trwt|}|!&|j't#j(|!&|j)t#j(tj*d$krt++|j',t+j-t++|j',t+j.tj/Bt++|j),t+j-t++|j),t+j.tj/B|r|j01||j02 |!3d%}"d}#|"D]0\}$}%|$j45d&}&|&s|!6|$j4q|$j4|j'kr||&7}d }#q|$j4|j)kr| |&7} q|r!|#r!|7|r!|s!| rt8|| |d'}d|d(fWS|"r)|!9s1|:dur1n|!9sB|:durB|;nq|j'2|j)2|!2|j<}Wnst=t>fy}'z*|d)| |t8|'f|r|j|'j?d!d!t8|'| |d*n|'WYd}'~'n?d}'~'wt@y}'z.|d)| |t8tABf|r|jdd!d!t8|'tAB| |d+n|'WYd}'~'nd}'~'ww|dkr|rtC| D|jE}|j| |||| |d,| dur|t8|| |d't8| | |d'fS||| fS)-a$ Execute a command, returns rc, stdout, and stderr. The mechanism of this method for reading stdout and stderr differs from that of CPython subprocess.Popen.communicate, in that this method will stop reading once the spawned command has exited and stdout and stderr have been consumed, as opposed to waiting until stdout/stderr are closed. This can be an important distinction, when taken into account that a forked or backgrounded process may hold stdout or stderr open for longer than the spawned command. :arg args: is the command to run * If args is a list, the command will be run with shell=False. * If args is a string and use_unsafe_shell=False it will split args to a list and run with shell=False * If args is a string and use_unsafe_shell=True it runs with shell=True. :kw check_rc: Whether to call fail_json in case of non zero RC. Default False :kw close_fds: See documentation for subprocess.Popen(). Default True :kw executable: See documentation for subprocess.Popen(). Default None :kw data: If given, information to write to the stdin of the command :kw binary_data: If False, append a newline to the data. Default False :kw path_prefix: If given, additional path to find the command in. This adds to the PATH environment variable so helper commands in the same directory can also be found :kw cwd: If given, working directory to run the command inside :kw use_unsafe_shell: See `args` parameter. Default False :kw prompt_regex: Regex string (not a compiled regex) which can be used to detect prompts in the stdout which would otherwise cause the execution to hang (especially if no input data is specified) :kw environ_update: dictionary to *update* environ variables with :kw umask: Umask to be used when running the command. Default None :kw encoding: Since we return native strings, on python3 we need to know the encoding to use to transform from bytes to text. If you want to always get bytes back, use encoding=None. The default is "utf-8". This does not affect transformation of strings given as args. :kw errors: Since we return native strings, on python3 we need to transform stdout and stderr from bytes to text. If the bytes are undecodable in the ``encoding`` specified, then use this error handler to deal with them. The default is ``surrogate_or_strict`` which means that the bytes will be decoded using the surrogateescape error handler if available (available on all python3 versions we support) otherwise a UnicodeError traceback will be raised. This does not affect transformations of strings given as args. :kw expand_user_and_vars: When ``use_unsafe_shell=False`` this argument dictates whether ``~`` is expanded in paths and environment variables are expanded before running the command. When ``True`` a string such as ``$SHELL`` will be expanded regardless of escaping. When ``False`` and ``use_unsafe_shell=False`` no path or variable expansion will be done. :kw pass_fds: When running on Python 3 this argument dictates which file descriptors should be passed to an underlying ``Popen`` constructor. On Python 2, this will set ``close_fds`` to False. :kw before_communicate_callback: This function will be called after ``Popen`` object will be created but before communicating to the process. (``Popen`` object will be passed to callback as a first argument) :kw ignore_invalid_cwd: This flag indicates whether an invalid ``cwd`` (non-existent or not a directory) should be ignored or should raise an exception. :kw handle_exceptions: This flag indicates whether an exception will be handled inline and issue a failed_json or if the caller should handle it. :returns: A 3-tuple of return code (integer), stdout (native string), and stderr (native string). On python2, stdout and stderr are both byte strings. On python3, stdout and stderr are text strings converted according to the encoding and errors parameters. If you want byte strings on python3, use encoding=None to turn decoding to text off. Nz5Argument 'args' to run_command must be list or stringi)rKcmdrF cSsg|] }tt|ddqS)rr)rrvrwr rr!r!r"r 1sz-AnsibleModule.run_command..rrs-c)Nz/bin/shTrcSs0g|]}|durttjtj|ddqSr)rrrrrrr!r!r"r Ds0cSs g|] }|durt|ddqSr)rrr!r!r"r Fs z6invalid prompt regular expression given to run_commandrrPATHrz%s:%s PYTHONPATHcSs(g|]}|r|ds|ds|qS)z/ansible_modlib.zipz /debug_dir)endswithrr!r!r"r gs rlcsr tdSdSr)rrr!rr!r"preexecqsz*AnsibleModule.run_command..preexec)rshell close_fdsrstdoutrM preexec_fnenvpass_fdsrz)Provided cwd is not a valid directory: %sz Executing: PollSelector posixr i)encodingrzQA prompt was encountered while running a command, but no input data was specifiedz#Error Executing CMD:%s Exception:%s)rKrrMrr)rKrrMrr]r)rrKrrMr)FrrrhrrNrrsrrrvrrrecompile MULTILINErrrrbrrrany subprocessPIPErrabspathrrrrr~Popenrb selectorsrSelectSelectorrr EVENT_READrMrfcntlfilenoF_SETFLF_GETFL O_NONBLOCKrrNrselectfileobjr unregisterrrget_mappollwait returncoderrrrrhrir|rstripru)(rrdcheck_rcrrrt binary_data path_prefixruse_unsafe_shell prompt_regexenviron_updaterrrexpand_user_and_varsrbefore_communicate_callbackignore_invalid_cwdhandle_exceptionsrr prompt_rerKst_inrrpypathsrrerrrMselectoreventsstdout_changedreventb_chunkrr!rr"rysJ                 ,,       &  "  &    zAnsibleModule.run_commandcCs4tjtj|}t|d}|||dS)Nr)rrrrrrNr)rr6rNfhr!r!r"append_to_files   zAnsibleModule.append_to_filecCst|Sr)r)rrr!r!r"rszAnsibleModule.bytes_to_humancCs t||Sr)r)rnumberisbitsr!r!r"rr"zAnsibleModule.human_to_bytesc CsLz t|d}W|Sty%ztj}WY|Sty$d}YY|Sww)Nii(#)rrrPIPE_BUF)r buffer_sizer!r!r"get_buffer_sizes   zAnsibleModule.get_buffer_size) FFNNNFFNNrr)r)T)NTNNr=r,)FT)FTNNFNNFNNNr~rTNNTT)F)F__name__ __module__ __qualname__rpropertyrrKrHr rrrrrr'r*r<r@r>rSrWrorrw classmethodr^ staticmethodrrrrFrrrrrrBrrrrrrr,rGrr!r$r&r/rrr3r=r>rArCrKr%rGrpr`r~ryrr pretty_bytesrr/rr!r!r!r"rhs g &  7     - ) ) U + ,   D  (    >!  2  #w  rcCstjtjtSr)rrr)rrr!r!r!r"get_module_pathrrc Cs$|dkr ddlm}|}nv|dvrddlm}|}ni|dkr%ddl}|}n^|dkr0ddl}|}nS|d kr;ddl}|}nH|d krHdd lm}|}n;|d krUdd lm }|}n.|dvrfddl } t | d|}n|dkrmt }n|dkrutj}ntd|dtdtdtd|dtddd|S)z(Inject import-time deprecation warnings. get_exceptionr)r> literal_eval _literal_eval)rdatetimeNsignaltypeschain)rrepeat)r>bPY2PY3 iteritems test_type binary_type string_types integer_typeszansible.module_utils.sixmap shlex_quotezcannot import name z from 'z' ()z Importing 'z' from 'z' is deprecated.z2.21)rr)ansible.module_utils.pycompat24rastrrrr itertoolsrr importlibr import_modulerrvrwAttributeErrorrrrH) importable_namer importablerrrrrrrr!r!r" __getattr__sV    rrr) __future__rrr_PY_MIN version_infordumpsrrsrrNr splitlinesr__main__rrrTrrrrMr^rrrrvrr_rrrrh functoolsr rr ImportErrorsystemdr r systemd_daemonrbbootedrrr ansible.module_utils.compatrrMNoneType_textrrr+ansible.module_utils.common.text.convertersrrjson_dict_unicode_to_bytesrjson_dict_bytes_to_unicode$ansible.module_utils.common.arg_specr+ansible.module_utils.common.text.formattersrrrrrr#r5.ansible.module_utils.six.moves.collections_abcr$r%r&r'r(r)r*"ansible.module_utils.common.localer+#ansible.module_utils.common.processr, ansible.module_utils.common.filer-rr. DEFAULT_PERMr/r0r1r2r3r4$ansible.module_utils.common.sys_infor5r6r7&ansible.module_utils.common.parametersr8r9r:r;r<r=ansible.module_utils.errorsr>r?r@&ansible.module_utils.common.validationrArB"ansible.module_utils.common._utilsrCri)ansible.module_utils.parsing.convert_boolrDrErFrG$ansible.module_utils.common.warningsrHrIrJrK frozensetr,rIrimaprrrxrrrr`rgr|rrobjectrrrr!r!r!r"s  &      $  (          A 0: