o
    쑛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 )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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
