ó
½-'Nc           @   sÞ   d  Z  d d l 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 d d l m Z d d l m Z m Z d e f d	 „  ƒ  YZ d
 e f d „  ƒ  YZ d e f d „  ƒ  YZ d S(   s   Low-level server communication.iÿÿÿÿN(   t   fetch(   t   create_file(   t   bpickle(   t   format_delta(   t
   SERVER_APIt   VERSIONt   HTTPTransportc           B   sG   e  Z d  Z d d d „ Z d „  Z d „  Z d „  Z d e d „ Z	 RS(   s=   Transport makes a request to exchange message data over HTTP.c         C   s   | |  _  | |  _ | |  _ d S(   s-  
        @param url: URL of the remote Landscape server message system.
        @param pubkey: SSH public key used for secure communication.
        @param payload_recorder: PayloadRecorder used for recording exchanges
            with the server.  If C{None}, exchanges will not be recorded.
        N(   t   _urlt   _pubkeyt   _payload_recorder(   t   selft   urlt   pubkeyt   payload_recorder(    (    s>   /usr/lib/python2.7/dist-packages/landscape/broker/transport.pyt   __init__   s    		c         C   s   |  j  S(   s)   Get the URL of the remote message system.(   R   (   R
   (    (    s>   /usr/lib/python2.7/dist-packages/landscape/broker/transport.pyt   get_url   s    c         C   s   | |  _  d S(   s)   Set the URL of the remote message system.N(   R   (   R
   R   (    (    s>   /usr/lib/python2.7/dist-packages/landscape/broker/transport.pyt   set_url"   s    c         C   sr   i | d 6d t  d 6d d 6} | r2 | | d <n  t j ƒ  } | t |  j d t d | d	 | d
 |  j d | ƒf S(   Ns   X-Message-APIs   landscape-client/%ss
   User-Agents   application/octet-streams   Content-Types   X-Computer-IDt   postt   datat   headerst   cainfot   curl(   R   t   pycurlt   CurlR    R   t   TrueR   (   R
   t   payloadt   computer_idt   message_apiR   R   (    (    s>   /usr/lib/python2.7/dist-packages/landscape/broker/transport.pyt   _curl&   s    

c   
      C   s„  t  j | ƒ } |  j d k	 r1 |  j j | ƒ n  y” t j ƒ  } t j ƒ  j ƒ  t j	 k rw t j
 d t j | ƒ ƒ n  |  j | | | ƒ \ } } t j d t | ƒ t | ƒ t t j ƒ  | ƒ ƒ Wn t j d |  j ƒ d SX| j t j ƒ } | d k rt j d | f ƒ d SyJ t  j | ƒ }	 t j ƒ  j ƒ  t j	 k rct j
 d t j |	 ƒ ƒ n  Wn t j d | ƒ d SX|	 S(	   s”  Exchange message data with the server.

        @param payload: The object to send, it must be L{bpickle}-compatible.
        @param computer_id: The computer ID to send the message as (see
            also L{Identity}).

        @type: C{dict}
        @return: The server's response to sent message or C{None} in case
            of error.

        @note: This code is thread safe (HOPEFULLY).

        s   Sending payload:
%ss*   Sent %d bytes and received %d bytes in %s.s"   Error contacting the server at %s.iÈ   s'   Server returned non-expected result: %ds   Received payload:
%ss    Server returned invalid data: %rN(   R   t   dumpsR	   t   Nonet   savet   timet   loggingt	   getLoggert   getEffectiveLevelt   DEBUGt   debugt   pprintt   pformatR   t   infot   lenR   t	   exceptionR   t   getinfoR   t   RESPONSE_CODEt   errort   loads(
   R
   R   R   R   t   spayloadt
   start_timet   curlyR   t   codet   response(    (    s>   /usr/lib/python2.7/dist-packages/landscape/broker/transport.pyt   exchange0   s6    		N(
   t   __name__t
   __module__t   __doc__R   R   R   R   R   R   R4   (    (    (    s>   /usr/lib/python2.7/dist-packages/landscape/broker/transport.pyR      s   			
t   PayloadRecorderc           B   s;   e  Z d  Z d „  Z d „  Z d „  Z d „  Z d „  Z RS(   sã   
    L{PayloadRecorder} records client exchanges with the server to disk for
    later playback.

    Exchange payloads will be stored one per file, where the file name is
    the elapsed time since the client was started.
    c         C   sQ   t  j  ƒ  |  _ | |  _ d |  _ |  j d k	 rM |  j |  j ƒ |  j ƒ  n  d S(   sP   
        @param destination_dir - The directory to record exchanges in.
        iÿÿÿÿN(   R    t   _time_offsett   _destination_dirt   _last_payload_timeR   t   _create_destination_dirt   _delete_old_payloads(   R
   t   destination_dir(    (    s>   /usr/lib/python2.7/dist-packages/landscape/broker/transport.pyR   h   s    		c         C   s&   t  j j | ƒ s" t  j | ƒ n  d S(   s}   Create the destination directory if it does not exist.

        @param destination_dir: The directory to be created.
        N(   t   ost   patht   existst   mkdir(   R
   R>   (    (    s>   /usr/lib/python2.7/dist-packages/landscape/broker/transport.pyR<   s   s    c         C   s[   xT t  j |  j ƒ D]@ } t  j j |  j | ƒ } t  j j | ƒ r t  j | ƒ q q Wd S(   s5   Delete payloads lying around from a previous session.N(   R?   t   listdirR:   R@   t   joint   isfilet   unlink(   R
   t   filenamet	   file_path(    (    s>   /usr/lib/python2.7/dist-packages/landscape/broker/transport.pyR=   {   s    c         C   s/   |  j  ƒ  } t t j j |  j | ƒ | ƒ d S(   sa   Persist the given payload to disk.

        @param payload: The payload to be persisted.
        N(   t   get_payload_filenameR   R?   R@   RD   R:   (   R
   R   t   payload_name(    (    s>   /usr/lib/python2.7/dist-packages/landscape/broker/transport.pyR   ‚   s    c         C   sT   t  j  ƒ  |  j } d |  j } d | } | | k rC | d } n  | |  _ d | S(   sr   
        Generate a payload filename.  This method ensures that payloads
        will have a unique name.
        s   %.3fgü©ñÒMbP?(   R    R9   R;   (   R
   t   payload_timet   last_payload_timet   this_payload_time(    (    s>   /usr/lib/python2.7/dist-packages/landscape/broker/transport.pyRI   ‹   s    
	(   R5   R6   R7   R   R<   R=   R   RI   (    (    (    s>   /usr/lib/python2.7/dist-packages/landscape/broker/transport.pyR8   _   s   					t   FakeTransportc           B   sA   e  Z d  Z d d d d „ Z d „  Z d „  Z d e d „ Z RS(   s$   Fake transport for testing purposes.c         C   s^   | |  _  | |  _ g  |  _ g  |  _ d |  _ d |  _ d  |  _ d  |  _ i  |  _	 | |  _
 d  S(   Ni    (   R   R	   t   payloadst	   responsest   _current_responset   next_expected_sequenceR   R   R   t   extraR   (   R
   R   R   R   (    (    s>   /usr/lib/python2.7/dist-packages/landscape/broker/transport.pyR   œ   s    									c         C   s   |  j  S(   N(   R   (   R
   (    (    s>   /usr/lib/python2.7/dist-packages/landscape/broker/transport.pyR   ¨   s    c         C   s   | |  _  d  S(   N(   R   (   R
   R   (    (    s>   /usr/lib/python2.7/dist-packages/landscape/broker/transport.pyR   «   s    c         C   s®   |  j  j | ƒ | |  _ | |  _ |  j t | j d g  ƒ ƒ 7_ |  j t |  j ƒ k  r} |  j |  j } |  j d 7_ n g  } i |  j d 6| d 6} | j	 |  j
 ƒ | S(   Nt   messagesi   s   next-expected-sequence(   RO   t   appendR   R   RR   R)   t   getRQ   RP   t   updateRS   (   R
   R   R   R   R3   t   result(    (    s>   /usr/lib/python2.7/dist-packages/landscape/broker/transport.pyR4   ®   s    		!
N(	   R5   R6   R7   R   R   R   R   R   R4   (    (    (    s>   /usr/lib/python2.7/dist-packages/landscape/broker/transport.pyRN   ™   s
   		(   R7   R?   R    R!   R&   R   t   landscape.lib.fetchR    t   landscape.lib.fsR   t   landscape.libR   t   landscape.logR   t	   landscapeR   R   t   objectR   R8   RN   (    (    (    s>   /usr/lib/python2.7/dist-packages/landscape/broker/transport.pyt   <module>   s   O: