
    !                         S SK Jr  S SKrS SKrS SKrS SKrS SKJrJrJ	r	  S SK
r
S SKrS SKJrJrJrJr  S rSrSrSrSr " S	 S
5      r\R.                  " SS/5      rS rS rg)    )ApiExceptionN)	WebSocketABNFenableTrace)	urlencode
quote_plusurlparse
urlunparse            c                       \ rS rSrS rSS jrSS jrSS jrS rSS jr	SS	 jr
SS
 jrSS jrSS jrSS jrS rS rS rSS jrSS jrS rSrg)WSClient#   c                    [        S5        / nSU l        0 U l        SU l        U(       a  SU;   a  UR	                  SUS   -  5        U(       a  SU;   a  UR	                  SUS   -  5        OUR	                  S5        UR                  S5      (       ag  UR                  (       aV  [        R                  UR                  =(       d    [        R                  " 5       S	.nUR                  b  UR                  US'   OS[        R                  0nUR                  (       a  UR                  US'   UR                  (       a  UR                  US'   [!        USS9U l        U R"                  R%                  X$S9  SU l        g
)a
  A websocket client with support for channels.

    Exec command uses different channels for different streams. for
example, 0 is stdin, 1 is stdout and 2 is stderr. Some other API calls
like port forwarding can forward different pods' streams to different
channels.
F authorizationzauthorization: %szsec-websocket-protocolzsec-websocket-protocol: %sz)sec-websocket-protocol: v4.channel.k8s.iozwss://)	cert_reqsca_certsNcheck_hostnamer   certfilekeyfile)ssloptskip_utf8_validation)headerT)r   
_connected	_channels_allappend
startswith
verify_sslsslCERT_REQUIREDssl_ca_certcertifiwhereassert_hostname	CERT_NONE	cert_filekey_filer   sockconnect)selfconfigurationurlheadersr   ssl_optss         .lib/third_party/kubernetes/stream/ws_client.py__init__WSClient.__init__%   sE    FDODNDI ?g-mm''/*BBC+w6mm0456 7 mm?@
~~hM$<$<((#//B7==?h 
	&	&	2%2%B%B!"s}}-h*44hz)22hyFDIIIc)DO    c                 ^    U R                  US9  XR                  ;   a  U R                  U   $ g)zFPeek a channel and return part of the input,

empty string otherwise.
timeoutr   )updater   )r.   channelr9   s      r3   peek_channelWSClient.peek_channelQ   s.    
 	KKK .. ^^G$$r6   c                     XR                   ;  a  U R                  X5      nOU R                   U   nXR                   ;   a  U R                   U	 U$ )zRead data from a channel.)r   r<   )r.   r;   r9   rets       r3   read_channelWSClient.read_channel[   sE    nn$g/cNN7#c.. 
..
!Jr6   Nc                 6   Uc  [        S5      n[        R                  " 5       nU R                  5       (       a  [        R                  " 5       U-
  U:  a  XR                  ;   aX  U R                  U   nSU;   aC  UR	                  S5      nUSU nXES-   S nU(       a  X@R                  U'   U$ U R                  U	 U$ U R                  U[        R                  " 5       -
  U-   S9  U R                  5       (       a  [        R                  " 5       U-
  U:  a  M  gggg)zRead a line from a channel.Ninf
r   r8   )floattimeis_openr   findr:   )r.   r;   r9   startdataindexr?   s          r3   readline_channelWSClient.readline_channele   s    egIIKE
,,..TYY[507:	NN	"~~g&4<))D/%Ve#aij!$&*NN7# * w'*
kk7TYY[058k: ,,..TYY[507:.:.r6   c                 R    U R                   R                  [        U5      U-   5        g)zWrite data to a channel.N)r,   sendchr)r.   r;   rJ   s      r3   write_channelWSClient.write_channelx   s    IINN3w<$&'r6   c                 *    U R                  [        US9$ )z$Same as peek_channel with channel=1.r8   )r<   STDOUT_CHANNELr.   r9   s     r3   peek_stdoutWSClient.peek_stdout|       ^W==r6   c                 *    U R                  [        US9$ )z$Same as read_channel with channel=1.r8   )r@   rT   rU   s     r3   read_stdoutWSClient.read_stdout   rX   r6   c                 *    U R                  [        US9$ )z(Same as readline_channel with channel=1.r8   )rL   rT   rU   s     r3   readline_stdoutWSClient.readline_stdout          AAr6   c                 *    U R                  [        US9$ )z$Same as peek_channel with channel=2.r8   )r<   STDERR_CHANNELrU   s     r3   peek_stderrWSClient.peek_stderr   rX   r6   c                 *    U R                  [        US9$ )z$Same as read_channel with channel=2.r8   )r@   ra   rU   s     r3   read_stderrWSClient.read_stderr   rX   r6   c                 *    U R                  [        US9$ )z(Same as readline_channel with channel=2.r8   )rL   ra   rU   s     r3   readline_stderrWSClient.readline_stderr   r_   r6   c                 :    U R                   nSU l         0 U l        U$ )ad  Return buffered data received on stdout and stderr channels.

This is useful for non-interactive call where a set of command passed
to the API call and their result is needed after the call is concluded.
Should be called after run_forever() or update()

TODO: Maybe we can process this and return a more meaningful map with
channels mapped for each input.
r   )r   r   )r.   outs     r3   read_allWSClient.read_all   s      ))CDIDNJr6   c                     U R                   $ )z&True if the connection is still alive.)r   )r.   s    r3   rG   WSClient.is_open   s    ??r6   c                 0    U R                  [        U5        g)z)The same as write_channel with channel=0.N)rQ   STDIN_CHANNEL)r.   rJ   s     r3   write_stdinWSClient.write_stdin   s    }d+r6   c                     U R                  5       (       d  gU R                  R                  (       d  SU l        g[        R                  " U R                  R                  4SSU5      u  n  nU(       Ga  U R                  R                  S5      u  pEU[        R                  :X  a  SU l        gU[        R                  :X  d  U[        R                  :X  a  UR                  n[        R                  (       a  UR                  SS5      n[        U5      S:  av  [        US   5      nUSS nU(       a[  U[         ["        4;   a  U =R$                  U-  sl        XpR&                  ;  a  X`R&                  U'   gU R&                  U==   U-  ss'   ggggg)	z@Update channel buffers with at most one complete frame of input.NF Tzutf-8replacer   r   )rG   r,   	connectedr   selectrecv_data_framer   OPCODE_CLOSEOPCODE_BINARYOPCODE_TEXTrJ   sixPY3decodelenordrT   ra   r   r   )r.   r9   r_op_codeframerJ   r;   s           r3   r:   WSClient.update   s:   <<>>99dommTYY^^-r2w?GAq!yy006ng	D%%	%d(((Gt7G7G,Gzz77Wi0$t9q=QL'ab$>>:: ii4inn,(,nnW%nnW%-%  	 -H 	r6   c                    U(       a  [         R                   " 5       nU R                  5       (       az  [         R                   " 5       U-
  U:  a]  U R                  U[         R                   " 5       -
  U-   S9  U R                  5       (       a  [         R                   " 5       U-
  U:  a  M[  ggggU R                  5       (       a'  U R                  SS9  U R                  5       (       a  M&  gg)zdWait till connection is closed or timeout reached.

Buffer any input
    received during this time.
r8   N)rF   rG   r:   )r.   r9   rI   s      r3   run_foreverWSClient.run_forever   s     iikeLLNNtyy{U2W<Wtyy{2U:< LLNNtyy{U2W<N<N LLNND! LLNNr6   c                 n    SU l         U R                  (       a  U R                  R                  " S0 UD6  gg)z
close websocket connection.
FNru   )r   r,   close)r.   kwargss     r3   r   WSClient.close   s*     DOyy
iioo r6   )r   r   r   r,   )r   )N)__name__
__module____qualname____firstlineno__r4   r<   r@   rL   rQ   rV   rZ   r]   rb   re   rh   rl   rG   rr   r:   r   r   __static_attributes__ru   r6   r3   r   r   #   sZ    *X;&(>>B>>B,.<" r6   r   
WSResponserJ   c                     [        U 5      n[        U5      nUR                  S:X  a  SUS'   OUR                  S:X  a  SUS'   [        U5      $ )Nhttpwsr   httpswss)r	   listschemer
   )r0   
parsed_urlpartss      r3   get_websocket_urlr      sN    }*
z
%& E!HG#E!H	E	r6   c                    US   nUR                  SS5      nUR                  SS5      nUR                  S5      n/ nUR                  S0 5       HO  u  pUS:X  a2  [        U	[        5      (       a  U	 H  n
UR                  X45        M     M=  UR                  X45        MQ     U(       a  US	[	        U5      -   -  n [        U [        U5      U5      nU(       d  U$ UR                  US
9  [        SSR                  UR                  5       5      -  5      $ ! [        [        [        4 a  n[        S[        U5      S9eSnAff = f)zAn internal function to be called in api-client when a websocket

connection is required. args and kwargs are the parameters of
apiClient.request method.
r   _request_timeout<   _preload_contentTr1   query_paramscommand?r8   z%sr   r   )statusreasonN)get
isinstancer   r    r   r   r   r   r   joinrl   	ExceptionKeyboardInterrupt
SystemExitr   str)r/   argsr   r0   r   r   r1   r   keyvaluer   clientes                r3   websocket_callr      s2    	Q#ZZ 2B7ZZ 2D9JJy!' ,JJ~r2jc
iJud33'SN+  3,' 3 3<(((C0m%6s%;WEFm
/0dRWWV__%67788
&
	3 0
aA
//0s   ;D 9D E)D<<E)kubernetes.client.restr   rx   r&   rF   collections	websocketr   r   r   r}   r#   six.moves.urllib.parser   r   r	   r
   rq   rT   ra   ERROR_CHANNELRESIZE_CHANNELr   
namedtupler   r   r   ru   r6   r3   <module>r      sn   " 0     2 2 
 
 N Nz  z z ##L6(;
0r6   