o
    f                  	   @   s(  U d dl Z d dlZd dlZd dlZd dlmZ d dlmZ d dlm	Z
 d dlmZ d dlmZ eed< zd dlmZ d d	lmZ d
ZeZW n eefyT   dZeZY nw eeZedejZedZdZG dd deZ G dd deZ!dd Z"dd Z#dd Z$d ddZ%dd Z&d!ddZ'dS )"    N)Any)TemplateSyntaxError)
type_utils)util)
write_file
JUndefined)DebugUndefined)TemplateTFz##\s*template:(.*)z)\$\{([A-Za-z0-9_.]+)\}|\$([A-Za-z0-9_.]+)zCI_MISSING_JINJA_VAR/c                
       sT   e Zd Zdeddf fddZdd Ze	dd	ed
ededefddZdZ	  Z
S )JinjaSyntaxParsingExceptionerrorreturnNc                    s*   t  |jpd|j|j|j |j| _d S )Nzunknown syntax error)super__init__messagelinenonamefilenamesource)selfr   	__class__ 5/usr/lib/python3/dist-packages/cloudinit/templater.pyr   0   s   z$JinjaSyntaxParsingException.__init__c                 C   s(   | j | j| j| j | jd   dS );Avoid jinja2.TemplateSyntaxError multi-line __str__ format.   syntax_errorline_numberline_content)format_error_messager   r   r   
splitlinesstripr   r   r   r   __str__<   s
   z#JinjaSyntaxParsingException.__str__ r   r   r   c                 C   s$   |rd| nd}t jj| ||dS )r   z: r$   r   )r
   message_templateformatr   r   r   r   r   D   s   z0JinjaSyntaxParsingException.format_error_messagezfUnable to parse Jinja template due to syntax error: {syntax_error} on line {line_number}{line_content})r$   )__name__
__module____qualname__r   r   r#   staticmethodstrr   r%   __classcell__r   r   r   r   r
   /   s(    
r
   c                   @   s    e Zd ZdZdd Zdd ZdS )UndefinedJinjaVariablez>Class used to represent any undefined jinja template variable.c                 C   s   dt | jf S )Nz%s%s)MISSING_JINJA_PREFIX_undefined_namer"   r   r   r   r#   ]   s   zUndefinedJinjaVariable.__str__c                 C   s$   t |td}tdj| j|d)Nr$   zhUndefined jinja variable: "{this}-{other}". Jinja tried subtraction. Perhaps you meant "{this}_{other}"?)thisother)r+   replacer.   	TypeErrorr&   r/   )r   r1   r   r   r   __sub__`   s   zUndefinedJinjaVariable.__sub__N)r'   r(   r)   __doc__r#   r4   r   r   r   r   r-   Z   s    r-   c                    s    fdd}t || S )zThis does simple replacement of bash variable like templates.

    It identifies patterns like ${a} or $a and can also identify patterns like
    ${a.b} or $a.b which will look for a key 'b' in the dictionary rooted
    by key 'a'.
    c                    s   |  d}|d u r|  d}|d u rtdt|d} }t|dkrE| }t|ts;t	d|t
||f || }t|dks&| }t|tsZt	d||t
|f t|| S )N   r   z,Match encountered but no valid group present.zRCan not traverse into non-dictionary '%s' of type %s while looking for subkey '%s'z<Can not extract key '%s' from non-dictionary '%s' of type %s)groupRuntimeErrorcollectionsdequesplitlenpopleft
isinstancedictr3   tuobj_namer+   )matchr   pathselected_paramskeyparamsr   r   replacerr   s2   




zbasic_render.<locals>.replacer)BASIC_MATCHERsub)contentrH   rI   r   rG   r   basic_renderj   s   rM   c                 C   s   dd }|  ddkr| dd\}}n| }d}t|}|s$dt| fS |d  }|dvr7td	| |d
krGt	sGt
d dt|fS |d
krRt	rRd
||fS dt|fS )Nc              
   S   s   |  drdnd}zt| tddgdjdi || W S  ty4 } z| jd7  _t|d|d }~w tyB } z||d }~ww )	N
r$   Tzjinja2.ext.do)	undefinedtrim_blocks
extensionsr6   )r   r   )endswith	JTemplater-   renderr   r   r
   	Exception)rL   rH   addtemplate_syntax_errorunknown_errorr   r   r   jinja_render   s6   	z%detect_template.<locals>.jinja_renderrN   r6   r$   basic)jinjar[   z.Unknown template rendering type '%s' requestedr\   zcJinja not available as the selected renderer for desired template, reverting to the basic renderer.)findr<   TYPE_MATCHERrC   rM   r8   lowerr!   
ValueErrorJINJA_AVAILABLELOGwarning)textrY   identrest
type_matchtemplate_typer   r   r   detect_template   s.   




ri   c                 C   s4   |si }t t| \}}}td| | |||S )Nz+Rendering content of '%s' using renderer %s)ri   r   load_text_filerb   debug)fnrH   rh   rendererrL   r   r   r   render_from_file   s
   
rn     c                 C   s   t | |}tj|||d d S )N)mode)rn   r   r   )rl   outfnrH   rp   contentsr   r   r   render_to_file   s   
rs   c                 C   s    |si }t | \}}} || |S )zRender string)ri   )rL   rH   _template_typerm   r   r   r   render_string   s   
ru   c           	      C   s   t |d}| }W d    n1 sw   Y  | |d}t|| d }|r8tj|dd}|s8td| |dkrDtj	| d S t
||dd	 d S )
Nr)variantprefixrN   T)defaultz.Cannot render template file %s - invalid yaml.-w)omode)openreadru   rstripr   	load_yamlr9   sysstdoutwriter   )	rw   templateoutputis_yamlrx   fhrr   
tpl_paramsoutr   r   r   render_template   s   

r   )ro   )N)(r:   loggingrer   typingr   jinja2r   	cloudinitr   rA   r   cloudinit.atomic_helperr   __annotations__r   _DebugUndefinedr	   rS   ra   r   ImportErrorAttributeErrorobject	getLoggerr'   rb   compileIr^   rJ   r.   r
   r-   rM   ri   rn   rs   ru   r   r   r   r   r   <module>   s>   


+&1
