o
    x[hú  ã                	   @   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 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yZ   dZeZY nw e e¡ZdZG dd„ deƒZG dd„ deƒZe	 d¡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)Úperformance)Ú
type_utils)Úutil)Ú
write_fileÚ
JUndefined)ÚDebugUndefined)ÚTemplateTFz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   /   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    C   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'   r0   )r   r2   r   r   r   Ú__sub___   s   þÿzUndefinedJinjaVariable.__sub__N)r(   r)   r*   Ú__doc__r$   r5   r   r   r   r   r.   Y   s    r.   zRendering basic templatec                    s   ‡ fdd„}t  d|| ¡S )zìThis 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Údictr4   ÚtuÚobj_namer,   )Úmatchr   ÚpathÚselected_paramsÚkey©Úparamsr   r   Úreplacerr   s2   


ýÿ÷

ÿÿzbasic_render.<locals>.replacerz)\$\{([A-Za-z0-9_.]+)\}|\$([A-Za-z0-9_.]+))ÚreÚsub)ÚcontentrI   rJ   r   rH   r   Úbasic_renderi   s   	ÿrN   c                 C   s´   dd„ }|   d¡dkr|  dd¡\}}n| }d}t d|tj¡}|s'dt| fS | d¡ ¡  ¡ }|d	vr:t	d
| ƒ‚|dkrJt
sJt d¡ dt|fS |dkrUt
rUd||fS dt|fS )Nc              
   S   s¸   |   d¡rdnd}z+t d¡� t| tddgd�jd	i |¤Ž| 	 W  d   ƒ W S 1 s-w   Y  W d S  tyM } z| jd7  _t|d�|‚d }~w t	y[ } z||‚d }~ww )
NÚ
r%   zRendering jinja2 templateTzjinja2.ext.do)Ú	undefinedÚtrim_blocksÚ
extensionsr7   )r   r   )
Úendswithr   ÚTimedÚ	JTemplater.   Úrenderr   r   r   Ú	Exception)rM   rI   ÚaddÚtemplate_syntax_errorÚunknown_errorr   r   r   Újinja_render“   s:   üûûúÿ(ÿ
ÿþ€€ÿz%detect_template.<locals>.jinja_renderrO   éÿÿÿÿr7   r%   z##\s*template:(.*)Ú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=   rK   rD   ÚIrN   r9   Úlowerr"   Ú
ValueErrorÚJINJA_AVAILABLEÚLOGÚwarning)Útextr[   ÚidentÚrestÚ
type_matchÚtemplate_typer   r   r   Údetect_template’   s.   
ÿÿÿ


rk   c                 C   s4   |si }t t | ¡ƒ\}}}t d| |¡ |||ƒS )Nz+Rendering content of '%s' using renderer %s)rk   r   Úload_text_filerd   Údebug)ÚfnrI   rj   ÚrendererrM   r   r   r   Úrender_from_fileÄ   s
   
rp   é¤  c                 C   s   t | |ƒ}tj|||d� d S )N)Úmode)rp   r   r   )rn   ÚoutfnrI   rr   Úcontentsr   r   r   Úrender_to_fileÌ   s   
ru   c                 C   s    |si }t | ƒ\}}} || |ƒS )zRender string)rk   )rM   rI   Ú_template_typero   r   r   r   Úrender_stringÑ   s   
rw   c                 C   sr   t  |¡}| |dœ}t||ƒ ¡ d }|r$t j|dd�}|s$td| ƒ‚|dkr0tj |¡ d S t	||dd� d S )	N)ÚvariantÚprefixrO   T)Údefaultz.Cannot render template file %s - invalid yaml.ú-Úw)Úomode)
r   rl   rw   ÚrstripÚ	load_yamlr:   ÚsysÚstdoutÚwriter   )rx   ÚtemplateÚoutputÚis_yamlry   rt   Ú
tpl_paramsÚoutr   r   r   Úrender_templateÙ   s   

ÿrˆ   )rq   )N)&r;   ÚloggingrK   r€   Útypingr   Újinja2r   Ú	cloudinitr   r   rB   r   Úcloudinit.atomic_helperr   Ú__annotations__r	   Ú_DebugUndefinedr
   rU   rc   r   ÚImportErrorÚAttributeErrorÚobjectÚ	getLoggerr(   rd   r/   r   r.   ÚtimedrN   rk   rp   ru   rw   rˆ   r   r   r   r   Ú<module>   s>   
þ
+
(2
