o nnhD@sddlmZdZdZddlZddlZddlZddlmZddl m Z ddl m Z m Z ddlmZmZdd lmZGd d d e ZdS) ) annotationsae 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) AnsibleErrorAnsibleParserError)to_bytesto_text) shlex_splitcseZdZdZdZedZedZfddZdfdd Z d d Z d d Z ddZ ddZ ddZddZfddZeddZddZZS)InventoryModulez Takes an INI-format inventory file and builds a list of groups and subgroups with their associated hosts and variable settings. ini);#);#cstt|i|_d|_dS)N)superr __init__patterns _filenameself __class__H/usr/local/lib/python3.10/dist-packages/ansible/plugins/inventory/ini.pyr`s zInventoryModule.__init__Tc stt||||||_zi|jr|j|\}}nt|dd}t|d }|}Wdn1s4wYz t |dd } Wn*t ymg} | D]} | ra| d|j vra| dqP| t | ddqPYnw||| WdSty} zt| d} ~ ww)Nsurrogate_or_stricterrorsrbr)rr parserloader_get_file_contentsropenreadr splitlines UnicodeErrorb_COMMENT_MARKERSappend_parse Exceptionr) r inventoryr pathcacheb_dataprivateb_pathfhdatalineerrrrgs0       zInventoryModule.parsecCstd|j|jf|)Nz%s:%d: )rrlineno)rmessagerrr _raise_errorszInventoryModule._raise_errorcCs|i}d}d}d|_|D]}|jd7_|}|r%|d|jvr&q|jd|}|r|\}}t|}|p=d}|dvrRd|}| d||f||j jvrp|d krj||vrjt |j||d ||<|j |||vr|d kr||d d kr| ||n ||d d kr||=q|d r|dr| d|dd|dkr||\} } } || | || q|d kr||\} } |j || | q|d kr||}||j jvr||vrt |j|||gd||<q||d|q|j ||q| d|q|D]7}||}|d d kr+td||d|d|df|d d krDtd||d|d|dfqdS)zt Populates self.groups from the given array of lines. Raises an error on any parse failure. ungroupedhostsrsection)r8childrenvars:z!Section [%s] has unknown type: %sr<)r2statenamer>r;[]zFInvalid section entry: '%s'. Please make sure that there are no spaces zDin the section entry, and that there are no other invalid characters)r2r>r?parentsrCzEntered unhandled state: %sz:%s:%d: Section [%s:vars] not valid for undefined group: %sr2r?z9%s:%d: Section [%s:children] includes undefined group: %sN)_compile_patternsr4strip_COMMENT_MARKERSrmatchgroupsrjoinr6r*dict add_group_add_pending_children startswithendswith_parse_host_definition_populate_host_vars_parse_variable_definition set_variable_parse_group_namer' add_childrpop)rr+linespending_declarations groupnamer>r2mtitler8port variableskvchildgdeclrrrr(sl         $zInventoryModule._parsecCsN||dD]}|j||||vr!||ddkr!|||q||=dS)NrCr>r;)r*rTrL)rgrouppendingparentrrrrLs   z%InventoryModule._add_pending_childrencCs0|jd|}|r|dS|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. rXr9zExpected group name, got: %sN)rrGrbr6)rr2rYrrrrSs z!InventoryModule._parse_group_namecCsBd|vrdd|ddD\}}|||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)rE).0r3rrr sz>InventoryModule._parse_variable_definition..r9zExpected key=value, got: %sN)split _parse_valuer6)rr2r]r^rrrrQ s z*InventoryModule._parse_variable_definitionc Cszt|dd}Wnty#}z|d||fWYd}~nd}~ww||d\}}i}|ddD]}d|vrB|d||dd\}} || ||<q5|||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)commentsz&Error parsing host definition '%s': %sNrr9rez4Expected key=value host variable assignment, got: %s)r ValueErrorr6_expand_hostpatternrhri) rr2tokensr3 hostnamesr[r\tr]r^rrrrOs z&InventoryModule._parse_host_definitioncs`tt||\}}|dr|durtd||D]}|dkr+td|q||fS)z= do some extra checks over normal processing r=NzoInvalid 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 rlrErNr)r hostpatternrnr[patternrrrrl?s  z#InventoryModule._expand_hostpatterncCstz!ttdtt|}Wdn1swYWnty*Yn ty2Ynwt|dddS)z Attempt to transform the string value from an ini file into a basic python object (int, dict, list, unicode string, etc). ignoreNpassthrur) nonstringr) warningscatch_warnings simplefilter SyntaxWarningast literal_evalrk SyntaxErrorr)r^rrrriQs     zInventoryModule._parse_valuecCs<ttdddtj|jd<ttdddtj|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 rrr:z^ ([^:\]\s]+) \s* # ignore trailing whitespace (?:\#.*)? # and/or a comment till the $ # end of the line rXN)recompilerXrrrrrrDes z!InventoryModule._compile_patterns)T)__name__ __module__ __qualname____doc__NAME frozensetrFr&rrr6r(rLrSrQrOrl staticmethodrirD __classcell__rrrrr Ws" $l  ! r ) __future__r DOCUMENTATIONEXAMPLESryr|ruansible.inventory.groupransible.plugins.inventoryransible.errorsrr+ansible.module_utils.common.text.convertersrransible.utils.shlexr r rrrrs +