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 )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 kr|  d}|d kr,tdt|d} }t|dkr| }t|tsvt	d|t
||f || }q@| }t|tst	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rt	st
d dt|fS |d
krt	rd
||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
