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mZ d dl	m
Z
 d dlmZmZ d dlmZ d dlmZ d dlmZmZmZmZ d d	lmZmZ ee ed
< zd dlmZ d dlm Z  W n e!yq   eZe"dZ Y nw e#e$Z%G dd deZ&G dd deZ'G dd de
j(Z)	d"ddZ*d"ddZ+de,dee, fddZ-	d#d d!Z.dS )$    N)EACCES)OptionalType)handlers)b64d
json_dumps)Paths)
PER_ALWAYS)MISSING_JINJA_PREFIXJinjaSyntaxParsingExceptiondetect_templaterender_string)	load_jsonload_text_fileJUndefinedError)UndefinedError)operator_rez[-.]c                   @      e Zd ZdS )JinjaLoadErrorN__name__
__module____qualname__ r   r   C/usr/lib/python3/dist-packages/cloudinit/handlers/jinja_template.pyr   "       r   c                   @   r   )NotJinjaErrorNr   r   r   r   r   r   &   r   r   c                   @   s(   e Zd ZdgZdefddZdd ZdS )JinjaTemplatePartHandlerz## template: jinjapathsc                 K   sL   t jj| tdd || _i | _|dg D ]}| D ]}|| j|< qqd S )N   )versionsub_handlers)r   Handler__init__r	   r   r!   get
list_types)selfr   _kwargshandlerctyper   r   r   r#   .   s   z!JinjaTemplatePartHandler.__init__c              
   C   s   |t jv rd S | jd}zt|||}W n ty1 }	 ztd|t|	 W Y d }	~	d S d }	~	ww |s6d S t 	|}
| j
|
}|sLtd||
 d S |jdkr]||||||| d S |jdkrm|||||| d S d S )Ninstance_data_sensitivez=Ignoring jinja template for %s. Failed to render template. %szPIgnoring jinja template for %s. Could not find supported sub-handler for type %sr      )r   CONTENT_SIGNALSr   get_runpathrender_jinja_payload_from_filer   LOGwarningstrtype_from_starts_withr!   r$   handler_versionhandle_part)r&   datar)   filenamepayload	frequencyheadersjinja_json_filerendered_payloadesubtypesub_handlerr   r   r   r4   6   sH   
	



z$JinjaTemplatePartHandler.handle_partN)r   r   r   prefixesr   r#   r4   r   r   r   r   r   *   s    r   Fc              
   C   s   t | d dkrtdi }d}tj|std| ztt|}W n# tyG } zd}t	|t
tfr>|jtkr>d| }t||d}~ww t| |||}|sSdS |S )aK  Render a jinja template sourcing variables from jinja_vars_path.

    @param payload: String of jinja template content. Should begin with
        ## template: jinja\n.
    @param payload_fn: String representing the filename from which the payload
        was read used in error reporting. Generally in part-handling this is
        'part-##'.
    @param instance_data_file: A path to a json file containing variables that
        will be used as jinja template variables.

    @return: A string of jinja-rendered content with the jinja header removed.
        Returns None on error.
    r   jinjazPayload is not a jinja templateNzFCannot render jinja template vars. Instance data not yet present at %sz"Loading Jinja instance data failedzGCannot render jinja template vars. No read permission on '%s'. Try sudo)r   r   ospathexistsr   r   r   	Exception
isinstanceIOErrorOSErrorerrnor   render_jinja_payload)r7   
payload_fninstance_data_filedebuginstance_datar;   r<   msgr   r   r   r.   ]   s:   


r.   c              
   C   s   t ||dg dd}|rtdt| zt| |}W n ttfy: } ztd|t	| W Y d }~d S d }~ww dd t
dt |D }|rTtd	|d
| |S )Nzbase64-encoded-keysT)decode_pathsinclude_key_aliaseszConverted jinja variables
%sz"Ignoring jinja template for %s: %sc                 S   s   g | ]
}d | td qS )z'%s' )replacer
   ).0varr   r   r   
<listcomp>   s    z(render_jinja_payload.<locals>.<listcomp>z%s[^\s]+z:Could not render jinja template variables in file '%s': %sz, )convert_jinja_instance_datar$   r/   rL   r   r   	TypeErrorr   r0   r1   refindallr
   join)r7   rJ   rM   rL   instance_jinja_varsr;   r<   warningsr   r   r   rI      s8   
rI   	orig_namereturnc                 C   s   t td| }|| kr|S dS )a  Return a jinja variable alias, replacing any operators with underscores.

    Provide underscore-delimited key aliases to simplify dot-notation
    attribute references for keys which contain operators "." or "-".
    This provides for simpler short-hand jinja attribute notation
    allowing one to avoid quoting keys which contain operators.
    {{ ds.v1_0.config.user_network_config }} instead of
    {{ ds['v1.0'].config["user.network-config"] }}.

    :param orig_name: String representing a jinja variable name to scrub/alias.

    :return: A string with any jinja operators replaced if needed. Otherwise,
        none if no alias required.
    _N)rX   subr   )r]   
alias_namer   r   r   get_jinja_variable_alias   s   rb   rQ   /r   c                 C   s   i }dd |D }t |  D ]U\}}|rd|||n|}||v r&t|}t|trOt|||||d||< td|rN||  D ]\}	}
t	
|
||	< qBn|||< |rdt|}|rdt	
|| ||< q|S )zProcess instance-data.json dict for use in jinja templates.

    Replace hyphens with underscores for jinja templates and decode any
    base64_encoded_keys.
    c                 S   s   g | ]}| d dqS )-r_   )rR   )rS   rB   r   r   r   rU      s    z/convert_jinja_instance_data.<locals>.<listcomp>z	{0}{1}{2})seprO   rP   zv\d+$)sorteditemsformatr   rE   dictrV   rX   matchcopydeepcopyrb   )r5   prefixre   rO   rP   resultkeyvaluekey_pathsubkeysubvaluera   r   r   r   rV      s2   

rV   )F)rQ   rc   r   F)/rk   loggingrA   rX   rH   r   typingr   r   	cloudinitr   cloudinit.atomic_helperr   r   cloudinit.helpersr   cloudinit.settingsr	   cloudinit.templaterr
   r   r   r   cloudinit.utilr   r   rD   __annotations__jinja2.exceptionsr   r   jinja2.lexerr   ImportErrorcompile	getLoggerr   r/   r   r   r"   r   r.   rI   r1   rb   rV   r   r   r   r   <module>   s<   

4

-