
    Vh                        d dl mZ dZdZd dlZd dlmZ d dlm	Z	m
Z
 d dlmZ d dlmZmZ d d	lmZ d d
lmZ d dlmZ d dlmZ  G d dee      Zy)    )annotationsa1  
    name: constructed
    version_added: "2.4"
    short_description: Uses Jinja2 to construct vars and groups based on existing inventory.
    description:
        - Uses a YAML configuration file with a valid YAML or C(.config) extension to define var expressions and group conditionals
        - The Jinja2 conditionals that qualify a host for membership.
        - The Jinja2 expressions are calculated and assigned to the variables
        - Only variables already available from previous inventories or the fact cache can be used for templating.
        - When O(strict) is False, failed expressions will be ignored (assumes vars were missing).
    options:
        plugin:
            description: token that ensures this is a source file for the 'constructed' plugin.
            required: True
            choices: ['ansible.builtin.constructed', 'constructed']
        use_vars_plugins:
            description:
                - Normally, for performance reasons, vars plugins get executed after the inventory sources complete the base inventory,
                  this option allows for getting vars related to hosts/groups from those plugins.
                - The host_group_vars (enabled by default) 'vars plugin' is the one responsible for reading host_vars/ and group_vars/ directories.
                - This will execute all vars plugins, even those that are not supposed to execute at the 'inventory' stage.
                  See vars plugins docs for details on 'stage'.
                - Implicit groups, such as 'all' or 'ungrouped', need to be explicitly defined in any previous inventory to apply the
                  corresponding group_vars
            required: false
            default: false
            type: boolean
            version_added: '2.11'
    extends_documentation_fragment:
      - constructed
a  
    # inventory.config file in YAML format
    plugin: ansible.builtin.constructed
    strict: False
    compose:
        var_sum: var1 + var2

        # this variable will only be set if I have a persistent fact cache enabled (and have non expired facts)
        # `strict: False` will skip this instead of producing an error if it is missing facts.
        server_type: "ansible_hostname | regex_replace ('(.{6})(.{2}).*', '\\2')"
    groups:
        # simple name matching
        webservers: inventory_hostname.startswith('web')

        # using ec2 'tags' (assumes aws inventory)
        development: "'devel' in (ec2_tags|list)"

        # using other host properties populated in inventory
        private_only: not (public_dns_name is defined or ip_address is defined)

        # complex group membership
        multi_group: (group_names | intersect(['alpha', 'beta', 'omega'])) | length >= 2

    keyed_groups:
        # this creates a group per distro (distro_CentOS, distro_Debian) and assigns the hosts that have matching values to it,
        # using the default separator "_"
        - prefix: distro
          key: ansible_distribution

        # the following examples assume the first inventory is from the `aws_ec2` plugin
        # this creates a group per ec2 architecture and assign hosts to the matching ones (arch_x86_64, arch_sparc, etc)
        - prefix: arch
          key: architecture

        # this creates a group per ec2 region like "us_west_1"
        - prefix: ""
          separator: ""
          key: placement.region

        # this creates a common parent group for all ec2 availability zones
        - key: placement.availability_zone
          parent_group: all_ec2_zones
N)	constants)AnsibleParserErrorAnsibleOptionsError)get_group_vars)BaseInventoryPluginConstructable)	to_native)combine_vars)	FactCache)get_vars_from_inventory_sourcesc                  N     e Zd ZdZdZ fdZ fdZd Zd Zd Z	d	 fd	Z
 xZS )
InventoryModulez> constructs groups and vars using Jinja2 template expressions constructedc                H    t         t        |           t               | _        y )N)superr   __init__r   _cache)self	__class__s    U/home/dcms/DCMS/lib/python3.12/site-packages/ansible/plugins/inventory/constructed.pyr   zInventoryModule.__init__c   s    ot-/k    c                    d}t         t        |   |      r<t        j                  j                  |      \  }}|r|dgt        j                  z   v rd}|S )NFz.configT)r   r   verify_fileospathsplitextCYAML_FILENAME_EXTENSIONS)r   r   valid	file_nameextr   s        r   r   zInventoryModule.verify_filei   sP    $3D9WW--d3NIs#)q/I/I!IIr   c                ^    t        | j                  |||      | j                  |||            S ) requires host object )r   host_groupvars	host_vars)r   hostloadersourcess       r   get_all_host_varsz!InventoryModule.get_all_host_varst   s.    D//fgFW[]celHmnnr   c           	         t        |j                               }| j                  d      r&t        |t	        |||j                         d            }|S r$   use_vars_pluginsall)r   
get_groups
get_optionr   r   )r   r'   r(   r)   gvarss        r   r%   zInventoryModule.host_groupvarsx   sI    t01??-. (GPWY]YhYhYjlq(rsEr   c           	     z    |j                         }| j                  d      rt        |t        |||gd            }|S r,   )get_varsr0   r   r   )r   r'   r(   r)   hvarss        r   r&   zInventoryModule.host_vars   s=    ??-. (GPWZ^Y_af(ghEr   c           	     d   t         t        |   ||||       | j                  |       g }	 |j                  }| j                  d      }t               }	 |j                  D ]  }| j                  |j                  |   ||      }	||v rt        |	||         }	| j                  | j                  d      |	||       | j                  |j                  |   ||      }	|| j                  v rt        |	| j                  |         }	| j                  | j                  d      |	||d	       | j                  | j                  d
      |	||d	        y# t
        $ r  | j                  d      rt        d      Y >w xY w# t         $ r+}
t#        dt%        |      dt%        |
      d|
      d}
~
ww xY w)z parses the inventory file )cacher-   z5The option use_vars_plugins requires ansible >= 2.11.strictcompose)r7   groupsF)r7   fetch_hostvarskeyed_groupszfailed to parse z:  )orig_excN)r   r   parse_read_config_dataprocessed_sourcesAttributeErrorr0   r   r   hostsr*   r   _set_composite_varsr   _add_host_to_composed_groups_add_host_to_keyed_groups	Exceptionr   r
   )r   	inventoryr(   r   r6   r)   r7   
fact_cacher'   hostvarser   s              r   r>   zInventoryModule.parse   s    	ot*9fd%*Pt$	c11G
 *[
	n! E  11)//$2GQXY:%+Hj6FGH (()CXt\b(c  11)//$2GQXY4;;&+Hdkk$6GHH 11$//(2KXW[dj  |A1  B ..t~/NPXZ^gm  D.  E'E  	c12)*abb 3	c:  	n$)D/S\]^S_%`klmm	ns*   E C9E; %E87E8;	F/&F**F/)F)__name__
__module____qualname____doc__NAMEr   r   r*   r%   r&   r>   __classcell__)r   s   @r   r   r   ^   s1    HD"	o(n (nr   r   )
__future__r   DOCUMENTATIONEXAMPLESr   ansibler   r   ansible.errorsr   r   ansible.inventory.helpersr   ansible.plugins.inventoryr   r	   +ansible.module_utils.common.text.convertersr
   ansible.utils.varsr   ansible.vars.fact_cacher   ansible.vars.pluginsr   r    r   r   <module>r]      sJ    #@*X 
 " B 4 H A + - @Tn)= Tnr   