a ì)g5Dã@sˆddlmZmZmZeZdZdZddlZddl Z ddl m Z ddl m Z ddlmZmZddlmZmZdd lmZGd d „d e ƒZdS) é)Úabsolute_importÚdivisionÚprint_functionae name: ini version_added: "2.4" short_description: Uses an Ansible INI file as inventory source. description: - INI file based inventory, sections are groups or group related with special C(:modifiers). - Entries in sections C([group_1]) are hosts, members of the group. - Hosts can have variables defined inline as key/value pairs separated by C(=). - The C(children) modifier indicates that the section contains groups. - The C(vars) modifier indicates that the section contains variables assigned to members of the group. - Anything found outside a section is considered an 'ungrouped' host. - Values passed in the INI format using the C(key=value) syntax are interpreted differently depending on where they are declared within your inventory. - When declared inline with the host, INI values are processed by Python's ast.literal_eval function (U(https://docs.python.org/3/library/ast.html#ast.literal_eval)) and interpreted as Python literal structures (strings, numbers, tuples, lists, dicts, booleans, None). If you want a number to be treated as a string, you must quote it. Host lines accept multiple C(key=value) parameters per line. Therefore they need a way to indicate that a space is part of a value rather than a separator. - When declared in a C(:vars) section, INI values are interpreted as strings. For example C(var=FALSE) would create a string equal to C(FALSE). Unlike host lines, C(:vars) sections accept only a single entry per line, so everything after the C(=) must be the value for the entry. - Do not rely on types set during definition, always make sure you specify type with a filter when needed when consuming the variable. - See the Examples for proper quoting to prevent changes to variable type. notes: - Enabled in configuration by default. - Consider switching to YAML format for inventory sources to avoid confusion on the actual type of a variable. The YAML inventory plugin processes variable values consistently and correctly. a¼# fmt: ini # Example 1 [web] host1 host2 ansible_port=222 # defined inline, interpreted as an integer [web:vars] http_port=8080 # all members of 'web' will inherit these myvar=23 # defined in a :vars section, interpreted as a string [web:children] # child groups will automatically add their hosts to parent group apache nginx [apache] tomcat1 tomcat2 myvar=34 # host specific vars override group vars tomcat3 mysecret="'03#pa33w0rd'" # proper quoting to prevent value changes [nginx] jenkins1 [nginx:vars] has_java = True # vars in child groups override same in parent [all:vars] has_java = False # 'all' is 'top' parent # Example 2 host1 # this is 'ungrouped' # both hosts have same IP but diff ports, also 'ungrouped' host2 ansible_host=127.0.0.1 ansible_port=44 host3 ansible_host=127.0.0.1 ansible_port=45 [g1] host4 [g2] host4 # same host as above, but member of 2 groups, will inherit vars from both # inventory hostnames are unique N)Úto_safe_group_name)ÚBaseFileInventoryPlugin)Ú AnsibleErrorÚAnsibleParserError)Úto_bytesÚto_text)Ú shlex_splitcs’eZdZdZdZedƒZedƒZ‡fdd„Zd‡fdd „ Z d d „Z d d „Z dd„Z dd„Z dd„Zdd„Z‡fdd„Zedd„ƒZdd„Z‡ZS)ÚInventoryModulez Takes an INI-format inventory file and builds a list of groups and subgroups with their associated hosts and variable settings. Zini)ú;ú#)ó;ó#cstt|ƒ ¡i|_d|_dS)N)Úsuperr Ú__init__ÚpatternsÚ _filename©Úself©Ú __class__©úA/usr/lib/python3.9/site-packages/ansible/plugins/inventory/ini.pyr`szInventoryModule.__init__Tc stt|ƒ |||¡||_zÐ|jr4|j |¡\}}n>t|dd}t|dƒ}| ¡}Wdƒn1sh0Yzt |dd  ¡} WnTt yÚg} |  ¡D]4} | rÂ| d|j vrÂ|   d¡q |   t | dd¡q Yn0| || ¡Wn.ty} zt| ƒ‚WYd} ~ n d} ~ 00dS)NÚsurrogate_or_strict©ÚerrorsÚrbrÚ)rr ÚparserÚloaderZ_get_file_contentsr ÚopenÚreadr Ú splitlinesÚ UnicodeErrorÚb_COMMENT_MARKERSÚappendÚ_parseÚ Exceptionr) rÚ inventoryr!ÚpathÚcacheZb_dataZprivateÚb_pathZfhÚdataÚlineÚerrrr gs&  &   zInventoryModule.parsecCstd|j|jf|ƒ‚dS)Nz%s:%d: )rrÚlineno)rÚmessagerrrÚ _raise_error‹szInventoryModule._raise_errorcCs¦| ¡i}d}d}d|_|D] }|jd7_| ¡}|r|d|jvrNq|jd |¡}|r.| ¡\}}t|ƒ}|p~d}|dvr¨d | ¡¡}|  d||f¡||j jvrä|d krØ||vrØt |j||d ||<|j   |¡||vr|d kr||d d kr|  ||¡q||d d kr||=qn.| d ¡r\| d¡r\|  d|dd¡|dkrˆ| |¡\} } } | | | || ¡q|d kr²| |¡\} } |j  || | ¡q|d kr| |¡}||j jvr ||vrøt |j|||gd||<n||d |¡n|j  ||¡q|  d|¡q|D]p}||}|d d krltd||d|d|dfƒ‚n2|d d kr0td||d|d ¡|dfƒ‚q0dS)zt Populates self.groups from the given array of lines. Raises an error on any parse failure. Z ungroupedÚhostsréÚsection)r4ÚchildrenÚvarsú:z!Section [%s] has unknown type: %sr8)r/ÚstateÚnamer:r7ú[ú]zFInvalid section entry: '%s'. Please make sure that there are no spacesú zDin the section entry, and that there are no other invalid characters)r/r:r;Úparentsr?zEntered unhandled state: %sz:%s:%d: Section [%s:vars] not valid for undefined group: %sr/r;z9%s:%d: Section [%s:children] includes undefined group: %sN)Ú_compile_patternsr1ÚstripÚ_COMMENT_MARKERSrÚmatchÚgroupsrÚjoinr3r*ÚdictÚ add_groupÚ_add_pending_childrenÚ startswithÚendswithÚ_parse_host_definitionZ_populate_host_varsÚ_parse_variable_definitionZ set_variableÚ_parse_group_namer'Ú add_childrÚpop)rr+ÚlinesZpending_declarationsÚ groupnamer:r/ÚmÚtitler4ÚportÚ variablesÚkÚvÚchildÚgZdeclrrrr(Žsh    ÿ     "zInventoryModule._parsecCsN||dD]6}|j ||¡||vr ||ddkr | ||¡q ||=dS)Nr?r:r7)r*rNrH)rÚgroupÚpendingÚparentrrrrHús z%InventoryModule._add_pending_childrencCs0|jd |¡}|r| d¡S| d|¡dS)zŽ Takes a single line and tries to parse it as a group name. Returns the group name if successful, or raises an error. rQr5zExpected group name, got: %sN)rrCrZr3)rr/rRrrrrMs z!InventoryModule._parse_group_namecCsBd|vr0dd„| dd¡Dƒ\}}|| |¡fS| d|¡dS)z• Takes a string and tries to parse it as a variable definition. Returns the key and value if successful, or raises an error. ú=cSsg|] }| ¡‘qSr)rA)Ú.0r0rrrÚ óz>InventoryModule._parse_variable_definition..r5zExpected key=value, got: %sN)ÚsplitÚ _parse_valuer3)rr/rVrWrrrrL s z*InventoryModule._parse_variable_definitionc Cs®zt|dd}Wn6tyF}z| d||f¡WYd}~n d}~00| |d¡\}}i}|dd…D]8}d|vr„| d|¡| dd¡\}} | | ¡||<qj|||fS) z” Takes a single line and tries to parse it as a host definition. Returns a list of Hosts if successful, or raises an error. T)Zcommentsz&Error parsing host definition '%s': %sNrr5r]z4Expected key=value host variable assignment, got: %s)r Ú ValueErrorr3Ú_expand_hostpatternrarb) rr/Útokensr0Ú hostnamesrTrUÚtrVrWrrrrKs(z&InventoryModule._parse_host_definitioncs`tt|ƒ |¡\}}| ¡ d¡r6|dur6td|ƒ‚|D]}| ¡dkr:td|ƒ‚q:||fS)z= do some extra checks over normal processing r9NzoInvalid host pattern '%s' supplied, ending in ':' is not allowed, this character is reserved to provide a port.z---zQInvalid host pattern '%s' supplied, '---' is normally a sign this is a YAML file.)rr rdrArJr)rZ hostpatternrfrTÚpatternrrrrd?sÿ z#InventoryModule._expand_hostpatterncCs@zt |¡}Wn"ty Ynty0Yn0t|dddS)z“ Attempt to transform the string value from an ini file into a basic python object (int, dict, list, unicode string, etc). Zpassthrur)Z nonstringr)ÚastZ literal_evalrcÚ SyntaxErrorr )rWrrrrbQs  zInventoryModule._parse_valuecCs<t tdddtj¡|jd<t tdddtj¡|jd<dS)z| Compiles the regular expressions required to parse the inventory and stores them in self.patterns. a‡^\[ ([^:\]\s]+) # group name (see groupname below) (?::(\w+))? # optional : and tag name \] \s* # ignore trailing whitespace (?:\#.*)? # and/or a comment till the $ # end of the line rrr6zù^ ([^:\]\s]+) \s* # ignore trailing whitespace (?:\#.*)? # and/or a comment till the $ # end of the line rQN)ÚreÚcompiler ÚXrrrrrr@csùø ûúz!InventoryModule._compile_patterns)T)Ú__name__Ú __module__Ú __qualname__Ú__doc__ÚNAMEÚ frozensetrBr&rr r3r(rHrMrLrKrdÚ staticmethodrbr@Ú __classcell__rrrrr Ws  $l !  r )Z __future__rrrÚtypeZ __metaclass__Z DOCUMENTATIONZEXAMPLESrirkZansible.inventory.grouprZansible.plugins.inventoryrZansible.errorsrrZansible.module_utils._textr r Zansible.utils.shlexr r rrrrÚs+