U
    Ó‡g6  ã                	   @   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k
r¶   dZeZY nX 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"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##\s*template:(.*)z)\$\{([A-Za-z0-9_.]+)\}|\$([A-Za-z0-9_.]+)zCI_MISSING_JINJA_VAR/c                       sJ   e Zd Zeddœ‡ fdd„Zdd„ Zedeeeedœd	d
„ƒZdZ	‡  Z
S )ÚJinjaSyntaxParsingExceptionN)ÚerrorÚreturnc                    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   1   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   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    E   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   0   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�ƒ‚d S )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__a   s     þÿzUndefinedJinjaVariable.__sub__N)r(   r)   r*   Ú__doc__r$   r5   r   r   r   r   r.   [   s   r.   zRendering basic templatec                    s   ‡ fdd„}t  || ¡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 kr|   d¡}|d kr,tdƒ‚t | d¡¡}ˆ }t|ƒdkr€| ¡ }t|tƒsvt	d|t
 |¡|f ƒ‚|| }q@| ¡ }t|tƒsªt	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   ÚtuZobj_namer,   )Úmatchr   ÚpathZselected_paramsÚkey©Úparamsr   r   Úreplacert   s0    


ýÿ

ÿÿzbasic_render.<locals>.replacer)ÚBASIC_MATCHERÚsub)ÚcontentrG   rH   r   rF   r   Úbasic_renderk   s    	rL   c                 C   s²   dd„ }|   d¡dkr(|  dd¡\}}n| }d}t |¡}|sHdt| fS | d¡ ¡  ¡ }|dkrntd	| ƒ‚|d
krŽt	sŽt
 d¡ dt|fS |d
kr¤t	r¤d
||fS dt|fS d S )Nc              
   S   s¼   |   d¡rdnd}zBt d¡�. t| tddgd�jf |Ž| W  5 Q R £ W S Q R X W nb tk
r� } z| jd7  _t|d�|‚W 5 d }~X Y n( t	k
r¶ } z
||‚W 5 d }~X Y nX d S )	NÚ
r%   zRendering jinja2 templateTzjinja2.ext.do)Z	undefinedZtrim_blocksÚ
extensionsr7   )r   )
Úendswithr   ZTimedÚ	JTemplater.   Zrenderr   r   r   Ú	Exception)rK   rG   ÚaddZtemplate_syntax_errorZunknown_errorr   r   r   Újinja_render“   s.    üûúÿ	ÿþz%detect_template.<locals>.jinja_renderrM   éÿÿÿÿr7   r%   Úbasic)ÚjinjarU   z.Unknown template rendering type '%s' requestedrV   zcJinja not available as the selected renderer for desired template, reverting to the basic renderer.)Úfindr=   ÚTYPE_MATCHERrC   rL   r9   Úlowerr"   Ú
ValueErrorÚJINJA_AVAILABLEÚLOGZwarning)ÚtextrS   ZidentÚrestZ
type_matchÚtemplate_typer   r   r   Údetect_template’   s.    

ÿÿÿ

r`   c                 C   s4   |si }t t | ¡ƒ\}}}t d| |¡ |||ƒS )Nz+Rendering content of '%s' using renderer %s)r`   r   Úload_text_filer\   Údebug)ÚfnrG   r_   ÚrendererrK   r   r   r   Úrender_from_fileÄ   s
    re   é¤  c                 C   s   t | |ƒ}tj|||d� d S )N)Úmode)re   r   r   )rc   ZoutfnrG   rg   Úcontentsr   r   r   Úrender_to_fileÌ   s    
ri   c                 C   s    |si }t | ƒ\}}} || |ƒS )zRender string)r`   )rK   rG   Z_template_typerd   r   r   r   Úrender_stringÑ   s    rj   c                 C   sp   t  |¡}| |dœ}t||ƒ ¡ d }|rHt j|dd�}|sHtd| ƒ‚|dkr^tj |¡ nt	||dd� d S )	N)ÚvariantÚprefixrM   T)Údefaultz.Cannot render template file %s - invalid yaml.ú-Úw)Zomode)
r   ra   rj   ÚrstripZ	load_yamlr:   ÚsysÚstdoutÚwriter   )rk   ÚtemplateÚoutputZis_yamlrl   rh   Z
tpl_paramsÚoutr   r   r   Úrender_templateÙ   s    

ÿrw   )rf   )N)*r;   ZloggingÚrerq   Útypingr   Zjinja2r   Z	cloudinitr   r   rB   r   Zcloudinit.atomic_helperr   Ú__annotations__r	   Z_DebugUndefinedr
   rP   r[   r   ÚImportErrorÚAttributeErrorÚobjectZ	getLoggerr(   r\   ÚcompileÚIrX   rI   r/   r   r.   ZtimedrL   r`   re   ri   rj   rw   r   r   r   r   Ú<module>   s@    


+
&2
