a )gP@s:ddlmZmZmZeZddlZddlZddlZddl m Z ddl m Z m Z ddlmZddlmZddlmZddlmZdd lmZmZdd lmZdd lmZdd lm Z dd l!m"Z"ddl#m$Z$m%Z%e"Z&ddZdddZ'd ddZ(ddZ)GdddeZ*Gddde*Z+Gddde,Z-Gddde,Z.dS)!)absolute_importdivisionprint_functionN)Mapping) AnsibleErrorAnsibleParserError)to_safe_group_name) parse_address) AnsiblePlugin)CachePluginAdjudicator)to_bytes to_native)boolean) string_types)Templar)Display) combine_varsload_extra_varscCst|dddS)NT)forceZsilent) original_safe)namerF/usr/lib/python3.9/site-packages/ansible/plugins/inventory/__init__.pyr,srcCsd|vS)z A helper function that checks a given host line to see if it contains a range pattern described in the docstring above. Returns True if the given line contains a pattern, else False. [r)linerrr detect_range1srcsg}|r|ddddddd\}}}|d}t|dkrXt|dkrXtd|d }|d}t|dkrzd}n|d}|sd }|std |d d krt|dkrt|t|krtd fd d} nt} zJtj|} tj|} | | krtdttj| | dt |} Wn0t yVt t |t |dt |} Yn0| D]>} d || | |f}t |r|t|n ||q\|SdS)a A helper function that expands a given line that contains a pattern specified in top docstring, and returns a list that consists of the expanded version. The '[' and ']' characters are used to maintain the pseudo-code appearance. They are replaced in this function with '|' to ease string splitting. References: https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#hosts-and-groups r|]:z.host range must be begin:end or begin:end:stepr0z!host range must specify end valuez:host range must specify equal-length begin and end formatscst|SN)strzfill)xZrlenrrfillisz#expand_hostname_range..fillz!host range must have begin <= endN)replacesplitlenrr$string ascii_lettersindexlistint ValueErrorrangejoinrextendexpand_hostname_rangeappend)rZ all_hostsheadZnrangetailZboundsZbegendstepr(Zi_begZi_endseqZrseqZhnamerr'rr6;sF $       " r6c Kszt|fi|}WnBtyV}z*dt|vr>td|n|WYd}~n d}~00|dkr|rt|jddstd||S)NZfact_caching_connectionaerror, '%s' inventory cache plugin requires the one of the following to be set to a writeable directory path: ansible.cfg: [default]: fact_caching_connection, [inventory]: cache_connection; Environment: ANSIBLE_INVENTORY_CACHE_CONNECTION, ANSIBLE_CACHE_PLUGIN_CONNECTION.Zmemory_optionszUnable to use cache plugin {0} for inventory. Cache options were provided but may not reconcile correctly unless set via set_options. Refer to the porting guide if the plugin derives user settings from ansible.constants.) CacheObjectrr getattrZ_pluginformat) plugin_namekwargscacheerrrget_cache_plugins rEcs`eZdZdZdZeeZfddZdddZ dd Z dd d Z d dZ ddZ ddZZS)BaseInventoryPluginz Parses an Inventory Source generatorcs*tt|i|_d|_t|_i|_dSr#)superrF__init__r= inventorydisplay_varsself __class__rrrIs zBaseInventoryPlugin.__init__TcCs&||_||_t|d|_t||_dS)az Populates inventory from the given data. Raises an error on any parse failure :arg inventory: a copy of the previously accumulated inventory data, to be updated with any new data this plugin provides. The inventory can be empty if no other source/plugin ran successfully. :arg loader: a reference to the DataLoader, which can read in YAML and JSON files, it also has Vault support to automatically decrypt files. :arg path: the string that represents the 'inventory source', normally a path to a configuration file for this inventory, but it can also be a raw string for this plugin to consume :arg cache: a boolean that indicates if the plugin should use the cache or not you can ignore if this plugin does not implement caching. )loaderN)rQrJrtemplarrrL)rNrJrQpathrCrrrparses zBaseInventoryPlugin.parsecCs@d}t|dd}tj|r0t|tjr0d}n |jd|S)a Verify if file is usable by this plugin, base does minimal accessibility check :arg path: a string that was passed as an inventory source, it normally is a path to a config file, but this is not a requirement, it can also be parsed itself as the inventory data to process. So only call this base class if you expect it to be a file. Fsurrogate_or_stricterrorsTzWSkipping due to inventory source not existing or not being readable by the current user)r osrSexistsaccessR_OKrKZvvv)rNrSZvalidb_pathrrr verify_files   zBaseInventoryPlugin.verify_fileNcCsXt|tstdt||D]4}|jj|||d|D]}|j||||q8qdS)Nz8Invalid data from file, expected dictionary and got: %s)groupport) isinstancerrr rJadd_host set_variable)rNhosts variablesr^r_hostkrrr_populate_host_varss  z'BaseInventoryPlugin._populate_host_varsc si}zjj|dd}Wn0tyH}ztt|WYd}~n d}~00tdpZjg}|srtdt|n>|d|vrtd|ddnt|t std t |j |j d d j vrd rgd }tfd d|D}tdfi|_|S)z validate config and set options as appropriate :arg path: path to common yaml format config file for this plugin F)rCNZ_redirected_namesz %s is emptyZpluginz!Incorrect plugin name in file: %sz none foundzJinventory source has invalid structure, it should be a dictionary, got: %s)ZdirectZ var_optionsrC)Z_uriZcache_connection)_timeoutZ cache_timeout)_prefixZ cache_prefixc3s6|].}|ddur|d|dfVqdSrNr get_option.0optrMrr z8BaseInventoryPlugin._read_config_data.. cache_plugin)rQZload_from_file Exceptionrr r?NAMEgetr`rtypeZ set_optionsrLr=rmdictrE_cache)rNrSZconfigrDZ valid_namescache_option_keys cache_optionsrrMr_read_config_datas$" z%BaseInventoryPlugin._read_config_datacCs(|jD]}||vr|||j|<qdS)a< update existing options from alternate configuration sources not normally used by Ansible. Many API libraries already have existing configuration sources, this allows plugin author to leverage them. :arg data: key/value pairs that correspond to configuration options for this plugin N)r=pop)rNdatarfrrr_consume_optionss z$BaseInventoryPlugin._consume_optionscCsPzt|dd\}}Wnty.|}d}Yn0t|rBt|}n|g}||fS)z Takes a single host pattern and returns a list of hostnames and an optional port number that applies to all of them. T)Z allow_rangesN)r rtrr6)rNZ hostpatternpatternr_Z hostnamesrrr_expand_hostpatterns   z'BaseInventoryPlugin._expand_hostpattern)T)NN)__name__ __module__ __qualname____doc__TYPE staticmethodr_sanitize_group_namerIrTr]rgr|rr __classcell__rrrOrrFs  " rFcs$eZdZdZdZfddZZS)BaseFileInventoryPluginz% Parses a File based Inventory SourceZstoragecstt|dSr#)rHrrIrMrOrrrI!sz BaseFileInventoryPlugin.__init__)rrrrrrIrrrrOrrsrc@sNeZdZeZeddZddZddZddZ d d Z d d Z d dZ dS) CacheablecCs|jSr#)ryrMrrrrC*szCacheable.cachecs>d}gd}tfdd|D}t|fi|_dS)Nrsrhc3s6|].}|ddur|d|dfVqdSrkrlrnrMrrrq1rrz.Cacheable.load_cache_plugin..)rmrxrEry)rNrArzr{rrMrload_cache_plugin.s zCacheable.load_cache_plugincCsd|j||S)Nz{0}_{1})r@ru_get_cache_prefix)rNrSrrr get_cache_key4szCacheable.get_cache_keycCsdt}|t|jdd|}t}|t|dd|}d|dd|ddgS)z7 create predictable unique prefix for plugin/inventory rUrVZs_N)hashlibZsha1updater ruZ hexdigestr4)rNrSmZd1nZd2rrrr7szCacheable._get_cache_prefixcCs|jdSr#)ryflushrMrrr clear_cacheDszCacheable.clear_cachecCs|jdSr#)ryupdate_cache_if_changedrMrrrrGsz!Cacheable.update_cache_if_changedcCs|jdSr#)ryZ set_cacherMrrrset_cache_pluginJszCacheable.set_cache_pluginN) rrrr>rypropertyrCrrrrrrrrrrr&s  rc@s4eZdZd ddZd ddZdddZdd d Zd S) ConstructableTcCsf|j}z|d}Wnty*d}Yn0|r@t||j|_n||_|jd|jj||jj f|dS)zi helper method for plugins to compose variables for Ansible based on jinja2 expression and inventory varsZuse_extra_varsF%s%s%s)disable_lookups) rRrmrtrrLavailable_variablestemplateZ environmentZvariable_start_stringZvariable_end_string)rNrrdrtZ use_extrarrr_composePs  zConstructable._composeFc Cs|rt|tr|D]t}z||||}WnJtyt}z2|rTtd||t|fWYd}~qWYd}~n d}~00|j|||qdS)z5 loops over compose entries to create vars for hosts z Could not set %s for host %s: %sN)r`rxrrtrr rJrb)rNZcomposerdrestrictZvarnameZ compositerDrrr_set_composite_varsas"z!Constructable._set_composite_varsc Cs|rt|tr|r(t||j|}||j_|D]}d||}||}zt |j |}WnJt y} z2|rt d||t | fWYd} ~ q4WYd} ~ n d} ~ 00|r4|j|}|j||q4dS)z} helper to create complex groups for plugins based on jinja2 conditionals, hosts that meet the conditional are added to groupz3{%% if %s %%} True {%% else %%} False {%% endif %%}z%Could not add host %s to group %s: %sN)r`rxrrJget_hostget_varsrRrrrrrtrr add_group add_child) rNgroupsrdrerfetch_hostvarsZ group_nameZ conditionalresultrDrrr_add_host_to_composed_groupsms   " z*Constructable._add_host_to_composed_groupsc Cs>|r:t|tr:|D] }|r,t|tr,|rHt||j|}z||d|}WnPt y}z8|rt d||dt |fWYd}~qWYd}~n d}~00|dd} |d} | dur| durt d|s|dkr| dur|dd} |d d } |d d} | rz|j | } WnNty~}z4|r^t d | |t |fWYd}~qWYd}~n d}~00g}t|tr|dkr| dur|| n ||nt|tr|D]0}|dkr| dur|| n ||qn|t|trl|D]T\}}d || |f}|dkr\| durNd || | f}n| dur\|}||qnt dt||D]|}| dkr|ddurd} |d | | |f}|j|}|j||| r|| }|j||j||qn*|r8|gifvr8t d|d|fqt d|qdS)zc helper to create groups for plugins based on variable values and add the corresponding hosts to itkeyz6Could not generate group for host %s from %s entry: %sNZ default_valuetrailing_separatorzTparameters are mutually exclusive for keyed groups: default_value|trailing_separatorr)prefix separator_Z parent_groupz3Could not generate parent group %s for group %s: %srFzUInvalid group name format, expected a string or a list of them or dictionary, got: %sZleading_separatorz=No key or key resulted empty for %s in host %s, invalid entryz7Invalid keyed group entry, it must be a dictionary: %s )r`r0rxrrJrrrrvrtrr rRrrrr7ritemsrwrmrrrar)rNkeysrdrerrZkeyedrrDZdefault_value_namerrsepZraw_parent_nameZnew_raw_group_namesrgnameZgvalZ bare_nameZ result_gname parent_namerrr_add_host_to_keyed_groupssv "     "            z'Constructable._add_host_to_keyed_groupsN)T)F)FT)FT)rrrrrrrrrrrrNs  r)N)N)/Z __future__rrrrwZ __metaclass__rrXr-collections.abcrZansible.errorsrrZansible.inventory.grouprrZansible.parsing.utils.addressesr Zansible.pluginsr Zansible.plugins.cacher r>Zansible.module_utils._textr r Z)ansible.module_utils.parsing.convert_boolrZansible.module_utils.sixrZansible.templaterZansible.utils.displayrZansible.utils.varsrrrKrr6rErFrobjectrrrrrrs4          H (