o
    im&                     @   s   d Z 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mZ ddlmZ dZdZd	ZeeZG d
d deZedZG dd dZG dd deZdddZejdfddZdd ZG dd dZdd ZdS )z
events for reporting.

The events here are designed to be used with reporting.
They can be published to registered handlers with report_event.
    N)List)performance)available_handlersinstantiated_handler_registry)ReportingHandlerfinishstart	cloudinitc                   @   s   e Zd Zdd ZdS )_namesetc                 C   s   || v r|S t d| )Nz%s not a valid value)AttributeError)selfname r   </usr/lib/python3/dist-packages/cloudinit/reporting/events.py__getattr__    s   z_nameset.__getattr__N)__name__
__module____qualname__r   r   r   r   r   r
      s    r
   )SUCCESSWARNFAILc                   @   s.   e Zd ZdZedfddZdd Zdd ZdS )	ReportingEventz"Encapsulation of event formatting.Nc                 C   s2   || _ || _|| _|| _|d u rt }|| _d S N)
event_typer   descriptionorigintime	timestamp)r   r   r   r   r   r   r   r   r   __init__,   s   
zReportingEvent.__init__c                 C   s   d | j| j| jS )z"The event represented as a string.z{0}: {1}: {2})formatr   r   r   r   r   r   r   	as_string<   s   zReportingEvent.as_stringc                 C   s   | j | j| j| j| jdS )z&The event represented as a dictionary.r   r   r   r   r   r"   r    r   r   r   as_dictB   s   zReportingEvent.as_dict)r   r   r   __doc__DEFAULT_EVENT_ORIGINr   r!   r#   r   r   r   r   r   )   s    
r   c                       s8   e Zd Zejdf fdd	Zdd Z fddZ  ZS )FinishReportingEventNc                    sJ   t t| t|| || _|d u rg }|| _|| _|tvr#td| d S )NzInvalid result: %s)	superr&   r   FINISH_EVENT_TYPEresult
post_filesdurationstatus
ValueError)r   r   r   r+   r)   r*   	__class__r   r   r   N   s   
zFinishReportingEvent.__init__c                 C   s   d | j| j| j| j| jS )Nz'{0}: {1}: {2}: {3} (duration: {4:.3f}s))r   r   r   r)   r   r+   r    r   r   r   r!   a   s   zFinishReportingEvent.as_stringc                    s@   t t|  }| j|d< t| jd|d< | jrt| j|d< |S )z'The event represented as json friendly.r)      r+   files)r'   r&   r#   r)   roundr+   r*   _collect_file_info)r   datar.   r   r   r#   j   s   
zFinishReportingEvent.as_dict)	r   r   r   r,   r   r   r!   r#   __classcell__r   r   r.   r   r&   M   s    	r&   c                    sT    si   fddt j D }ttj }|D ]}t||v r"q||  qdS )a  Report an event to all registered event handlers
    except those whose type is in excluded_handler_types.

    This should generally be called via one of the other functions in
    the reporting module.

    :param excluded_handler_types:
         List of handlers types to exclude from reporting the event to.
    :param event_type:
        The type of the event; this should be a constant from the
        reporting module.
    c                    s   h | ]
\}}| v r|qS r   r   ).0	hndl_typehndl_clsexcluded_handler_typesr   r   	<setcomp>   s
    zreport_event.<locals>.<setcomp>N)r   registered_itemsitemslistr   valuestypepublish_event)eventr:   excluded_handler_classeshandlershandlerr   r9   r   report_eventt   s   
rF   c                 C   s   t | ||||d}t|S )zVReport a "finish" event.

    See :py:func:`.report_event` for parameter details.
    )r*   )r&   rF   )
event_nameevent_descriptionr+   r)   r*   rB   r   r   r   report_finish_event   s   
rI   c                 C   s   t t| |}t|S )a'  Report a "start" event.

    :param event_name:
        The name of the event; this should be a topic which events would
        share (e.g. it will be the same for start and finish events).

    :param event_description:
        A human-readable description of the event that has occurred.
    )r   START_EVENT_TYPErF   )rG   rH   rB   r   r   r   report_start_event   s   
rK   c                   @   s   e Zd ZdZdddejdfddZdd Zdd Zd	d
 Z	e
dd Zejdd Ze
dd Zejdd Zdd Zdd ZdS )ReportEventStackaK  Context Manager for using :py:func:`report_event`

    This enables calling :py:func:`report_start_event` and
    :py:func:`report_finish_event` through a context manager.

    :param name:
        the name of the event

    :param description:
        the event's description, passed on to :py:func:`report_start_event`

    :param message:
        the description to use for the finish event. defaults to
        :param:description.

    :param parent:
    :type parent: :py:class:ReportEventStack or None
        The parent of this event.  The parent is populated with
        results of all its children.  The name used in reporting
        is <parent.name>/<name>

    :param reporting_enabled:
        Indicates if reporting events should be generated.
        If not provided, defaults to the parent's value, or True if no parent
        is provided.

    :param result_on_exception:
        The result value to set if an exception is caught. default
        value is FAIL.

    :param post_files:
        Can hold filepaths of files that are to get posted/created
        regarding a given event. Something like success or failure information
        in a given log file. For each filepath, if it's a valid regular file
        it will get: read & encoded as base64 at the close of the event.
        Default value, if None, is an empty list.
    Nc                 C   s   || _ || _|| _|| _|| _tj| _d | _|d u rg }|| _	|d u r+|r)|j
}nd}|| _
|r:d|j|f| _n| j| _i | _d S )NT/)parentr   r   messageresult_on_exceptionr,   r   r)   start_timestampr*   reporting_enabledjoinfullnamechildren)r   r   r   rO   rN   rR   rP   r*   r   r   r   r      s.   

zReportEventStack.__init__c                 C   s   d| j | j| jf S )Nz.ReportEventStack(%s, %s, reporting_enabled=%s))r   r   rR   r    r   r   r   __repr__  s
   zReportEventStack.__repr__c                 C   s>   t j| _t | _| jrt| j| j	 | j
rd| j
j| j< | S )N)NN)r,   r   r)   r   	monotonicrQ   rR   rK   rT   r   rN   rU   r   r    r   r   r   	__enter__  s   
zReportEventStack.__enter__c                 C   sP   t jt jfD ]}| j D ]\}\}}||kr || jf    S qq| j| jfS r   )r,   r   r   rU   r=   rO   r)   )r   cand_result_namevalue_msgr   r   r   _childrens_finish_info  s   z'ReportEventStack._childrens_finish_infoc                 C   s   | j S r   )_resultr    r   r   r   r)     s   zReportEventStack.resultc                 C   s   |t vr
td| || _d S )Nz'%s' not a valid result)r,   r-   r^   r   r[   r   r   r   r)     s   
c                 C   s   | j d ur| j S | jS r   )_messager   r    r   r   r   rO   "  s   
zReportEventStack.messagec                 C   s
   || _ d S r   )r`   r_   r   r   r   rO   (  s   
c                 C   s   |r| j | jfS |  S r   )rP   rO   r]   )r   excr   r   r   _finish_info,  s   zReportEventStack._finish_infoc                 C   sh   |  |\}}| jr||f| jj| j< | jr2| jd ur#t | j }nd}t| j	|||| j
d d S d S )Ng        )r+   r)   r*   )rb   rN   rU   r   rR   rQ   r   rW   rI   rT   r*   )r   exc_type	exc_value	tracebackr)   msgr+   r   r   r   __exit__2  s   

zReportEventStack.__exit__)r   r   r   r$   r,   r   r   rV   rX   r]   propertyr)   setterrO   rb   rg   r   r   r   r   rL      s*    *
(	



rL   c              
   C   s   | sd S g }| D ]J}t j|sd }n6td| & t|d}t| 	 }W d    n1 s5w   Y  W d    n1 sDw   Y  |
||dd q|S )NzReading rbbase64)pathcontentencoding)osrl   isfiler   Timedopenrk   	b64encodereaddecodeappend)r1   retfnamerm   fpr   r   r   r3   D  s     r3   r   ) r$   rk   loggingos.pathro   r   typingr   r	   r   cloudinit.reportingr   r   cloudinit.reporting.handlersr   r(   rJ   r%   	getLoggerr   LOGsetr
   r,   r   r&   rF   r   rI   rK   rL   r3   r   r   r   r   <module>   s2   
$
'#
 