
    ?g+\                     R   d dl Z d dlmZmZ d dlZd dlZd dlZd dl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mZmZ d dlmZmZ d dlmZmZmZmZ d dlmZ d dlmZ d ZdZd	Zd
ZdZ  G d d      Z! G d d      Z" ejF                  ddg      Z$ G d d      Z%ddZ&ddZ'd Z(d Z)d Z*y)    N)ApiExceptionApiValueError)	urlencodeurlparse
urlunparse)StringIOBytesIO)	WebSocketABNFenableTrace"WebSocketConnectionClosedException)urlsafe_b64decode)should_bypass_proxies            c                       e Zd Zd Zd Zy)
_IgnoredIOc                      y N )self_xs     P/var/www/openai/venv/lib/python3.12/site-packages/kubernetes/stream/ws_client.pywritez_IgnoredIO.write,   s        c                     t        d      )Nz_Tried to read_all() from a WSClient configured to not capture. Did you mean `capture_all=True`?)	TypeErrorr   s    r   getvaluez_IgnoredIO.getvalue/   s    yzzr   N)__name__
__module____qualname__r   r!   r   r   r   r   r   +   s    {r   r   c                       e Zd ZddZddZddZddZd ZddZddZ	dd	Z
dd
ZddZddZd Zd Zd ZddZddZed        Zd Zy)WSClientc                    d| _         i | _        || _        | j                  sdnd| _        |r&| j                  s
t	               n	t               | _        nt               | _        t        |||      | _	        d| _         d| _
        y)a2  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
   
TN)
_connected	_channelsbinarynewliner   r	   _allr   create_websocketsock_returncode)r   configurationurlheaderscapture_allr,   s         r   __init__zWSClient.__init__4   sf      #';;tE*.++
79DI"DI$]CA	r   c                 b    | j                  |       || j                  v r| j                  |   S y)zLPeek a channel and return part of the input,
        empty string otherwise.timeout )updater+   )r   channelr9   s      r   peek_channelzWSClient.peek_channelH   s0     	G$dnn$>>'**r   c                     || j                   vr| j                  ||      }n| j                   |   }|| j                   v r| j                   |= |S )zRead data from a channel.)r+   r=   )r   r<   r9   rets       r   read_channelzWSClient.read_channelP   sK    $..(##GW5C..)Cdnn$w'
r   Nc                 4   |t        d      }t        j                         }| j                         rt        j                         |z
  |k  r|| j                  v rg| j                  |   }| j                  |v rJ|j                  | j                        }|d| }||dz   d }|r|| j                  |<   |S | j                  |= |S | j                  |t        j                         z
  |z          | j                         rt        j                         |z
  |k  ryyyy)zRead a line from a channel.Ninfr   r8   )floattimeis_openr+   r-   findr;   )r   r<   r9   startdataindexr?   s          r   readline_channelzWSClient.readline_channelZ   s    ?ElG		llnu!4w!>$..(~~g.<<4' IIdll3Ev,Ca>D26w/ J !NN73JKK499;!6!>K@ llnu!4w!>n!>nr   c                 .   t         j                  xr t        |      t         j                  k(  }|rt        j
                  nt        j                  }t        |      }|rt        j                  |d      }||z   }| j                  j                  ||       y)zWrite data to a channel.ascii)opcodeN)
sixPY3typebinary_typer   OPCODE_BINARYOPCODE_TEXTchrr0   send)r   r<   rH   r,   rM   channel_prefixpayloads          r   write_channelzWSClient.write_channelm   sn     :T$Z3??:'-##43C3CW __^WEN 4'		wv.r   c                 0    | j                  t        |      S )z$Same as peek_channel with channel=1.r8   )r=   STDOUT_CHANNELr   r9   s     r   peek_stdoutzWSClient.peek_stdoutz          AAr   c                 0    | j                  t        |      S )z$Same as read_channel with channel=1.r8   )r@   rZ   r[   s     r   read_stdoutzWSClient.read_stdout~   r]   r   c                 0    | j                  t        |      S )z(Same as readline_channel with channel=1.r8   )rJ   rZ   r[   s     r   readline_stdoutzWSClient.readline_stdout       $$^W$EEr   c                 0    | j                  t        |      S )z$Same as peek_channel with channel=2.r8   )r=   STDERR_CHANNELr[   s     r   peek_stderrzWSClient.peek_stderr   r]   r   c                 0    | j                  t        |      S )z$Same as read_channel with channel=2.r8   )r@   rd   r[   s     r   read_stderrzWSClient.read_stderr   r]   r   c                 0    | j                  t        |      S )z(Same as readline_channel with channel=2.r8   )rJ   rd   r[   s     r   readline_stderrzWSClient.readline_stderr   rb   r   c                     | j                   j                         }| j                   j                         | _         i | _        |S )a  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!   	__class__r+   )r   outs     r   read_allzWSClient.read_all   s6     ii  "II'')	
r   c                     | j                   S )z&True if the connection is still alive.)r*   r    s    r   rE   zWSClient.is_open   s    r   c                 0    | j                  t        |       y)z)The same as write_channel with channel=0.N)rX   STDIN_CHANNEL)r   rH   s     r   write_stdinzWSClient.write_stdin   s    =$/r   c                 n   | j                         sy| j                  j                  sd| _        yt	        t
        d      rt        j                         }|j                  | j                  j                  t
        j                         ||dz  }|j                  |      }|j                  | j                  j                         n1t        j
                  | j                  j                  fdd|      \  }}}|r<| j                  j                  d      \  }}|t        j                  k(  rd| _        y|t        j                  k(  s|t        j                  k(  r|j                  }t         j"                  r| j$                  s|j'                  dd      }t)        |      d	kD  r|d
   }t         j"                  r| j$                  st+        |      }|d	d }|r_|t,        t.        fv r| j0                  j3                  |       || j4                  vr|| j4                  |<   y| j4                  |xx   |z  cc<   yyyyy)z@Update channel buffers with at most one complete frame of input.NFpolli  r   Tzutf-8replacer   r   )rE   r0   	connectedr*   hasattrselectrs   registerPOLLIN
unregisterrecv_data_framer   OPCODE_CLOSErR   rS   rH   rN   rO   r,   decodelenordrZ   rd   r.   r   r+   )	r   r9   rs   r_op_codeframerH   r<   s	            r   r;   zWSClient.update   s   ||~yy""#DO 66";;=DMM$))..&--8"5 		'"AOODIINN+mm"BG5GAq! !YY66t<NGU$+++"'D...'T=M=M2Mzz774;;;;w	:Dt9q="1gGwwt{{"%g,8D"~~&FF !IIOOD1"$..86:DNN73 NN73t;3  !	 3N r   c                    |rt        j                          }| j                         rrt        j                          |z
  |k  rW| j                  |t        j                          z
  |z          | j                         rt        j                          |z
  |k  rUyyyy| j                         r$| j                  d       | j                         r#yy)zfWait till connection is closed or timeout reached. Buffer any input
        received during this time.r8   N)rD   rE   r;   )r   r9   rG   s      r   run_foreverzWSClient.run_forever   s     IIKE,,.TYY[5%87%BWtyy{%:U%BD ,,.TYY[5%87%B.%B. ,,.D) ,,.r   c                    | j                         ry| j                  a| j                  t              }t	        j
                  |      }|d   dk(  rd| _        | j                  S t        |d   d   d   d         | _        | j                  S )zi
        The return code, A None value indicates that the process hasn't
        terminated yet.
        NstatusSuccessr   detailscausesmessage)rE   r1   r@   ERROR_CHANNELyaml	safe_loadint)r   errs     r   
returncodezWSClient.returncode   s     <<>'''6nnS)x=I-'(D$ ### (+3y>(+CA+Fy+Q'RD$###r   c                 d    d| _         | j                  r | j                  j                  di | yy)z-
        close websocket connection.
        FNr   )r*   r0   close)r   kwargss     r   r   zWSClient.close   s,      99DIIOO%f% r   )F)r   r   )r"   r#   r$   r6   r=   r@   rJ   rX   r\   r_   ra   re   rg   ri   rm   rE   rq   r;   r   propertyr   r   r   r   r   r&   r&   3   ss     (A&/BBFBBF02<h	* $ $"&r   r&   
WSResponserH   c                   N    e Zd Zd Zed        Zd Zd Zd Z G d d      Z	d Z
y	)
PortForwardc                 P   || _         i | _        t        |      D ]$  \  }}| j                  ||      | j                  |<   & t	        j
                  ddj                  |D cg c]  }t        |       c}      z  | j                        }d|_	        |j                          yc c}w )a&  A websocket client with support for port forwarding.

        Port Forward command sends on 2 channels per port, a read/write
        data channel and a read only error channel. Both channels are sent an
        initial frame containing the port number that channel is associated with.
        z!Kubernetes port forward proxy: %sz, )nametargetTN)	websocketlocal_ports	enumerate_Port	threadingThreadjoinstr_proxydaemonrG   )r   r   portsixport_numberportproxys          r   r6   zPortForward.__init__  s     #(/OB,0JJr;,GD[)  0
   4tyyX]A^X]PT#d)X]A^7__;;
 	 B_s    B#c                 .    | j                   j                  S r   )r   ru   r    s    r   ru   zPortForward.connected  s    ~~'''r   c                 f    || j                   vrt        d      | j                   |   j                  S NzInvalid port number)r   
ValueErrorsocketr   r   s     r   r   zPortForward.socket  s3    d...233,333r   c                 f    || j                   vrt        d      | j                   |   j                  S r   )r   r   errorr   s     r   r   zPortForward.error$  s3    d...233,222r   c                 v    | j                   j                         D ]  }|j                  j                           y r   )r   valuesr   r   )r   r   s     r   r   zPortForward.close)  s+    $$++-DKK .r   c                   &    e Zd Zd Z G d d      Zy)PortForward._Portc                     || _         t        j                  |dz        | _        t	        j
                         \  }| _        | j                  |      | _        d| _        d | _	        y )Nr   r   )
r   rN   int2byter<   r   
socketpairpython_SocketrH   r   )r   r   r   ss       r   r6   zPortForward._Port.__init__.  sS    *D<<Q/DL
 $..0NAt{ ,,q/DKDIDJr   c                       e Zd Zd Zd Zd Zy)PortForward._Port._Socketc                     || _         y r   )_socket)r   r   s     r   r6   z"PortForward._Port._Socket.__init__D  s	    %r   c                 .    t        | j                  |      S r   )getattrr   )r   r   s     r   __getattr__z%PortForward._Port._Socket.__getattr__G  s    t||T22r   c                     |t         j                  k(  r|t         j                  k(  ry | j                  j	                  |||       y r   )r   IPPROTO_TCPTCP_NODELAYr   
setsockopt)r   leveloptnamevalues       r   r   z$PortForward._Port._Socket.setsockoptJ  s8     F...7f>P>P3P''w>r   N)r"   r#   r$   r6   r   r   r   r   r   r   r   C  s    &3?r   r   N)r"   r#   r$   r6   r   r   r   r   r   r   -  s    	*	? 	?r   r   c                    g }g }i }| j                   j                         D ]p  }|j                  |       |j                  d       |j                  |       |j                  d       |j                  j	                  d       |||j                  <   r d}	 g }g }| j
                  j                  r8|j                  | j
                         |r|j                  | j
                         d}| j                   j                         D ]  }|j                  j                         dk7  s!| j
                  j                  rE|j                  |j                         |j                  r|j                  |j                         d}||j                  r|j                  |j                         d}|j                  j                           |r3| j
                  j                  r|s| j
                  j                          y t        j                  ||g       \  }	}
}|	D ]  }|| j
                  k(  rAd}|s	 | j
                  j                  d      \  }}|t        j                  k(  rp|j                  st        d      t!        j"                  |j                        }|t%        |      k\  rt        d|z        ||   }||   r|dz  r^|j&                  d|_        |xj&                  |j                  d	d  j)                         z  c_        |j                  j                          n|xj                  |j                  d	d  z  c_        nt%        |j                        d
k7  rt        d      t!        j"                  |j                  d	d       t!        j"                  |j                  dd
       dz  z   }||j*                  k7  rt        d|z        d||<   n?|t        j,                  t        j.                  t        j0                  fvrt        d|z        t3        | j
                  j4                  t6        j8                        r$| j
                  j4                  j;                         sd}|r:U||   }|j                  j                         dk7  sy|j                  j=                  d      }|rD|t        j>                  |j@                  |z   t        j                        jC                         z  }|j                  j                           |
D ]  }|| j
                  k(  r+| j
                  j4                  jE                  |      }||d  }=||   }|j                  j                         dk7  s`|j                  jE                  |j                        }|j                  |d  |_         # t        $ r= | j                   j                         D ]  }|j                  j                           Y  y w xY w)NFTr   zUnexpected frame data sizezUnexpected channel number: %sr   r:   r   r   z*Unexpected initial channel frame data size   z3Unexpected port number in initial channel frame: %szUnexpected websocket opcode: %si   )#r   r   appendr   setblockingr   ru   filenorH   r   rw   r{   r   r   rR   RuntimeErrorrN   byte2intr~   r   r}   r   OPCODE_PINGOPCODE_PONGr|   
isinstancer0   ssl	SSLSocketpendingrecvcreate_framer<   formatrU   )r   channel_portschannel_initializedr   r   kubernetes_datarlistwlistlocal_all_closedr   wr   r0   r   rM   r   r<   r   rH   sents                       r   r   zPortForward._proxyR  s    $$++-D  &&&u-  &&&u-KK##D)'+K$ . EE~~''T^^,"LL0#((//1;;%%'2-~~//T[[199!LL5+0(99!LL5/4, KK--/ 2  )A)Ao$$&mmE5"5GAq!4>>)"G!#,0NN,J,J4,PMFE
 "T%7%77#(::&23O&P P&)ll5::&>G&#m*<<&23RU\3\&] ]#0#9D27;#*Q;'+zz'957
$(JJ%**QR.2G2G2I$IJ$(KK$5$5$7$(IIAB$?I#&uzz?a#7*6(T+& %& /2ll5::a?.Ks||\a\f\fghij\kOlorOr.s#.$2B2B#B*6(]`k(k+& %& @D 3G <#D,<,<d>N>NPTPaPa+bb"./PSY/Y"ZZ *4>>+>+> NSWSaSaSfSfSnSnSp&+GI "L 't,D{{))+r1#{{//<+t/@/@ $t 3 $ 2 20 %fh'O
 !KK--/e f 4>>)>>..33ODD&5de&<O&t,D{{))+r1#{{//		:$(IIde$4	 Y >  B #(,(8(8(?(?(A $ 1 1 3 )B"#s   3V//AW54W5N)r"   r#   r$   r6   r   ru   r   r   r   r   r   r   r   r   r   r     s;    , ( (4
3
 "? "?Jc5r   r   c                 X   t        |       }t        |      }|j                  dk(  rd|d<   n|j                  dk(  rd|d<   |r_g }|D ]H  \  }}|dk(  r+t        |t              r|D ]  }|j	                  ||f        6|j	                  ||f       J |rt        |      |d<   t        |      S )Nhttpwsr   httpswsscommandr   )r   listschemer   r   r   r   )r3   query_params
parsed_urlpartsquerykeyr   r   s           r   get_websocket_urlr     s    #JEF"a			g	%a&JCiJud$;$GLL#w0  % c5\* '  'E!Her   c                    t        d       g }|rd|v r|j                  d|d   z         |rd|v r|j                  d|d   z         n|j                  d       |j                  d      r[| j                  rOt        j
                  | j                  xs t        j                         d}| j                  "| j                  |d	<   nd
t        j                  i}| j                  r| j                  |d<   | j                  r| j                  |d<   | j                  r| j                  |d<   t        |d      }d|i}| j                  s| j                   rt#        || ||      } |j$                  |fi | |S )NFauthorizationzauthorization: %szsec-websocket-protocolzsec-websocket-protocol: %sz)sec-websocket-protocol: v4.channel.k8s.iozwss://)	cert_reqsca_certscheck_hostnamer   certfilekeyfileserver_hostname)ssloptskip_utf8_validationheader)r   r   
startswith
verify_sslr   CERT_REQUIREDssl_ca_certcertifiwhereassert_hostname	CERT_NONE	cert_filekey_filetls_server_namer
   r   proxy_headerswebsocket_proxycareconnect)r2   r3   r4   r   ssl_optsr   connect_opts          r   r/   r/     sp    F?g-MM-0HHI+w62678 	9 	AB
~~hM$<$<**%11DW]]_
 ((4)6)F)FH%&/,66+44$$&3&C&C"#FI	6K m99)+}c7SIc)[)r   c                 @   |j                   r,| j                  d|j                   j                  d      i       |j                  r=t	        |j                        }| j                  |j
                  |j                  d       |j                  r|j                  j                         D ]s  \  }}|dk(  s|j                  d      s|j                         d   }t        |      j                         j                  d      }| j                  d|d	   |d   fi       u | S )
zc An internal function to be called in api-client when a websocket
        create is requested.
    http_no_proxy,)http_proxy_hosthttp_proxy_portzproxy-authorizationBasicr   :http_proxy_authr   )no_proxyr;   splitr   r   hostnamer   r  itemsr   r   r}   )	r  r2   r3   r4   	proxy_urlr   r   b64valueauths	            r   r	  r	    s     _m.D.D.J.J3.OQR]001	y/A/AV_VdVdef""&44::<IC++0@0@0I ;;=+(299;AA#F""$5Qa7I#KL	 =
 r   c                    t        ||j                  d            }|j                  d      }|j                  dd      }|j                  dd      }|j                  dd      }|j                  dd	      }	 t        | ||||
      }	|s|	S |	j                  |       |	j	                         }
|rt        |
      S t        ddj                  |
      z        S # t        t        t        f$ r}t        dt        |            d}~ww xY w)zAn internal function to be called in api-client when a websocket
    connection is required. method, url, and kwargs are the parameters of
    apiClient.request method.r   r4   _request_timeout<   _preload_contentTr5   r,   F)r,   r8   z%sr:   r   r   reasonN)r   getr&   r   rm   r   r   	ExceptionKeyboardInterrupt
SystemExitr   r   )r2   _methodr3   r   r4   r  r  r5   r,   clientalles               r   websocket_callr*  	  s    
 CN!;
<Cjj#Gzz"4b9zz"4d;**]D1KZZ%(F4-g{6RM#34ooc?"dRWWS\122(*5 4!CF334s$   6C 
.C 9C D*D  Dc                 *   |j                  d      }g }|D ]k  \  }}|dk(  s|j                  d      D ]L  }	 t        |      }	d|	cxk  rdk  sn t	        d|z        |	|v rt	        d|z        |j                  |	       N m |st	        d	      t        ||      }|j                  d
      }
	 t        | ||
      }t        ||      S # t        $ r t	        d|z        w xY w# t        t        t        f$ r}t        dt        |            d}~ww xY w)zAn internal function to be called in api-client when a websocket
    connection is required for port forwarding. args and kwargs are the
    parameters of apiClient.request method.r   r   r  zInvalid port number: %sr   i   z+Port number must be between 0 and 65536: %szDuplicate port numbers: %sz"Missing required parameter `ports`r4   r   N)r"  r  r   r   r   r   r   r/   r   r#  r$  r%  r   r   )r2   r&  r3   r   r   r   paramr   r   r   r4   r   r)  s                r   portforward_callr-  "  s.   
 ::n-LE$uGC(J"%d)K K/%/'(UX\(\]]%''(Dt(KLL[) ) % @AA
C
.Cjj#G4$]CA	9e,, " J'(AD(HIIJ  (*5 4!CF334s#   C/C# C #D7DDr   )+syskubernetes.client.restr   r   r  collectionsrw   r   r   r   rD   rN   r   six.moves.urllib.parser   r   r   r   r	   r   r
   r   r   r   base64r   requests.utilsr   rp   rZ   rd   r   RESIZE_CHANNELr   r&   
namedtupler   r   r   r/   r	  r*  r-  r   r   r   <module>r6     s     >     
   
  C B ! V V $ 0{ {K& K&\ $[##L6(;
q5 q5h((T&424r   