
    dW              
          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c mZ d dl	mc m
Z
 d dlmc mc mZ d dlmZmZmZ d dlmZmZmZ d dlmZmZmZ dadZdZdZdZd	Z ej@                  d
      Z!ejD                  ejF                  ejH                  ejJ                  ejL                  ejN                  ejP                  ejR                  ejT                  dg
Z+e+dd Z,e,j[                  ej\                         ej^                  gZ0ejb                  ejd                  ejf                  gZ4ejj                  gZ6dgZ7ejH                  ejP                  dgZ8ejr                  ejt                  ejv                  ejx                  gZ=dZ>dZ?dZ@dj                  ee      ZBdj                  eB      ZCdZDdZEdZFdZG G d deH      ZIdefdZJd3dZKd ZLd ZMd ZNd ZOd ZPd ZQd  ZRd! ZSd" ZTd# ZUd4d$ZVd% ZW	 	 d5d&ZXddddeddfd'ZYddddedd(fd)ZZdddded(fd*Z[dddded(fd+Z\ddddedd(fd,Z]dddded(fd-Z^d3d.Z_d3d/Z`d0 Zad3d1Zbd2 Zcy)6    N)	HttpErrorResourceGoneErrorInvalidContainerError)
httpclienturlparseustr)PY_VERSION_MAJOR
AGENT_NAMEGOAL_STATE_AGENT_VERSIONF         z<SAS_SIGNATURE>z3^(https?://[a-zA-Z0-9.].*sig=)([a-zA-Z0-9%-]*)(.*)$i  i  
http_proxyhttps_proxyno_proxyz{0}/{1}z
{0}+healthInvalidContainerConfigurationRequestRoleConfigFileNotFoundz168.63.129.16i  c                       e Zd Z ej                         ZeZddddZe	dd       Z
e	d        Ze	d        Ze	efd       Zy)	IOErrorCounterr   
hostpluginprotocolotherNc                 ,   t         j                  5  | t         j                  k(  rA|t        k(  rt         j                  dxx   dz  cc<   n7t         j                  dxx   dz  cc<   nt         j                  dxx   dz  cc<   d d d        y # 1 sw Y   y xY w)Nr   r   r   r   )r   _lock_protocol_endpointHOST_PLUGIN_PORT_countshostports     G/usr/lib/python3/dist-packages/azurelinuxagent/common/utils/restutil.py	incrementzIOErrorCounter.incrementv   sy    !! 	5~888++"**<8A=8"**:6!;6&&w/14/	5 	5 	5s   A0B

Bc                      t         j                  5  t         j                  j                         } t         j	                          | cd d d        S # 1 sw Y   y xY wN)r   r   r   copyreset)countss    r"   get_and_resetzIOErrorCounter.get_and_reset   sC    !! 	#++002F  "	 	 	s   4AAc                  l    t         j                  5  ddddt         _        d d d        y # 1 sw Y   y xY w)Nr   r   )r   r   r        r"   r'   zIOErrorCounter.reset   s3    !! 	O34A%NN"	O 	O 	Os   *3c                     | t         _        y r%   )r   r   )endpoints    r"   set_protocol_endpointz$IOErrorCounter.set_protocol_endpoint   s
    ,4)r,   NN)__name__
__module____qualname__	threadingRLockr   KNOWN_WIRESERVER_IPr   r   staticmethodr#   r)   r'   r/   r+   r,   r"   r   r   q   su    IOOE,!Q7G5 5   O O ': 5 5r,   r   c                 V    d}t        |       D ]  }|d   |d   |d   z   f} ||d   z  S )N)r   r   r   r   )range)retry_attemptdelayfib_s       r"   _compute_delayr>      sC    
C=! &1vs1vc!f}%&Q<r,   c                     |t         }| |v S r%   )RETRY_CODES)statusretry_codess     r"   _is_retry_statusrC      s    ![  r,   c           	      f    t        t        D cg c]  }t        | |      s| c}      dkD  S c c}w )Nr   )lenRETRY_EXCEPTIONS
isinstance)exs     r"   _is_retry_exceptionrJ      s*    +@az!Q/?@AAEE@s   ..c                     | t         v S r%   )THROTTLE_CODES)rA   s    r"   _is_throttle_statusrM      s    ^##r,   c                 F   t        |       }|j                  }|j                  rdj                  ||j                        }|j                  rdj                  ||j                        }d}|j
                  j                         dk(  rd}|j                  |j                  ||fS )zt
    Parse URL to get the components of the URL broken down to host, port
    :rtype: string, int, bool, string
    z{0}#{1}z{0}?{1}FhttpsT)	r   pathfragmentformatqueryschemelowerhostnamer!   )urlorel_urisecures       r"   
_parse_urlr[      s    
 	AffGzz""7AJJ7ww""7AGG4Fxx~~7"::qvvvw..r,   c                 &   t        |       }|j                  ry|j                  r<dj                  |j                  |j                  |j                  |j
                        S dj                  |j                  |j                  |j
                        S | S )z:
    Parse URL and return scheme://hostname:port/path
    {0}://{1}:{2}{3}z{0}://{1}{2})r   rV   r!   rR   rT   rP   )rW   rX   s     r"   _trim_url_parametersr^      sh     	Azz66%,,QXXqzz166166RR!((1::qvvFFJr,   c                     | j                  d      dk(  rR	 t        | j                  d      d         }|dk  s|dkD  ry	 t	        j
                  | j                  d      d          yy# t        $ r Y yw xY w# t        j                  $ r Y yw xY w)zU
    Very simple check of the cidr format in no_proxy variable.
    :rtype: bool
    /r   F    r   T)countintsplit
ValueErrorsocket	inet_atonerror)string_networkmasks     r"   is_valid_cidrrk      s    
 C A%	~++C034D !8tby	^11#6q9:
    		 || 		s"   A( 'A7 (	A43A47BBc                 p    ddd| z
  z  dz
  z  }t        j                  t        j                  d|            S )zConverts mask from /xx format to xxx.xxx.xxx.xxx
    Example: if mask is 24 function returns 255.255.255.0
    :rtype: str
    l    r   ra   z>I)rf   	inet_ntoastructpack)rj   bitss     r"   dotted_netmaskrq      s7    
 b4i1,,DFKKd344r,   c           
      r   t        j                  dt        j                  |             d   }|j	                  d      \  }}t        j                  dt        j                  t        t        |                        d   }t        j                  dt        j                  |            d   |z  }||z  ||z  k(  S )zThis function allows you to check if an IP belongs to a network subnet
    Example: returns True if ip = 192.168.1.1 and net = 192.168.1.0/24
             returns False if ip = 192.168.1.1 and net = 192.168.100.0/24
    :rtype: bool
    z=Lr   r`   )rn   unpackrf   rg   rd   rq   rc   )ipnetipaddrnetaddrrp   netmasknetworks          r"   address_in_networkrz      s     ]]4!1!1"!56q9FIIcNMGTmmD&"2"2>#d)3L"MNqQGmmD&"2"27";<Q?'IGW'G"344r,   c                 b    	 t        j                  |        y# t         j                  $ r Y yw xY w)z
    :rtype: bool
    FT)rf   rg   rh   )	string_ips    r"   is_ipv4_addressr}      s2    #  << s    ..c                  "   t         j                  j                  t              xs1 t         j                  j                  t        j	                               } | r1| j                  dd      j                  d      D cg c]  }|s|	 } }| S c c}w )N  ,)osenvirongetNO_PROXY_ENVupperreplacerd   )r   r    s     r"   get_no_proxyr      sl    zz~~l+Srzz~~l>P>P>R/SH%-%5%5c2%>%D%DS%IRTTDRR O Ss   <BBc                     t               }|rjt        |       r)|D ]#  }t        |      rt        | |      s y| |k(  s# y y|D ]1  }| j	                         j                  |j	                               s1 y y)NTF)r   r}   rk   rz   rU   endswith)r    r   proxy_ipproxy_domains       r"   bypass_proxyr     s    ~H4 $   *)$9#X%     !)  ::<((););)=>  	  r,   c                 *   t        j                         }d }|t        j                         }||fS | rt        nt        }d }||j                         fD ])  }|t        j                  v st        j                  |   } n |t        |      \  }}}}||fS r%   )	confget_httpproxy_hostget_httpproxy_portHTTPS_PROXY_ENVHTTP_PROXY_ENVr   r   r   r[   )rZ   r    r!   http_proxy_envhttp_proxy_urlvr=   s          r"   _get_http_proxyr     s    ""$DD<&&( : -3 ."6"6"89 	ABJJ!#A	
 %).9D$1:r,   c                 B    t         j                  dt        z   dz   |       S )Nz\1z\3)SAS_TOKEN_RETRIEVAL_REGEXsubREDACTED_TEXT)rW   s    r"   redact_sas_tokens_in_urlsr   4  s    $(()>)FLLr,   c                    |i n|}d|d<   |d uxr |	d u}||rdnd}d|vr	t         |d<   |r||	}}|rdnd}dj                  ||||      }n||}}|}|r-t        j                  |||	      }|r+|j	                  ||       nt        j
                  |||	      }|}|
rd
}t        j                  d| t        |      t        j                  |      |       |j                  | |||       |j                         S )Nclose
Connectioni  P   z
User-AgentrO   httpr]   )timeoutz
[REDACTED]z'HTTP connection [{0}] [{1}] [{2}] [{3}])methodrW   bodyheaders)HTTP_USER_AGENTrR   r   HTTPSConnection
set_tunnelHTTPConnectionloggerverboser   textutilstr_to_encoded_ustrrequestgetresponse)r   r    rY   r   r!   datarZ   r   
proxy_host
proxy_portredact_data	use_proxy	conn_host	conn_portrT   rW   connpayloads                     r"   _http_requestr   8  s-    ObG#GL$&A:T+AI|s"7" /):9	" ''dGD#T9	)))*329; OOD$'(()218: G NN<,S1//8	 	LLCdGLDr,   c                 N   |t         }|t        }t        |      \  }}}}d\  }}|r5t        |      s*t	        |      \  }}|s|rt        j                  d||       |rNt        t        d      s>t        j                         st        d      d}t        st        j                  d       d	a|r\|Z|Xt        t        j                  d
      s>t        j                         st        d      d}t        st        j                  d       d	ad}d}d}d}||k  rW|dkD  rF|rt        nt!        ||      }t        j                  d|dz   |||       t#        j$                  |       |dz  }	 t'        | ||||||||||	      }t        j                  d|j(                         |
r|S t+        |      r\t-        |j(                  |      rEdj/                  | ||j(                        }t1        |j(                        rd	}t3        |t4              }|j(                  t6        v rt9        |      }t;        |      |j(                  t        j<                  k(  rt9        |      }t>        |v rtA        |      |S t        dj/                  ||            # t        jB                  $ r<}|
r tE        |      }dj/                  | ||      }tG        |      rY d}~Y d}~ed}~wtH        $ rC}|
r tJ        jM                  ||       tE        |      }dj/                  | ||      }Y d}~d}~ww xY w)a  
    NOTE: This method provides some logic to handle errors in the HTTP request, including checking the HTTP status of the response
          and handling some exceptions. If return_raw_response is set to True all the error handling will be skipped and the
          method will return the actual HTTP response and bubble up any exceptions while issuing the request. Also note that if
        return_raw_response is True no retries will be done.
    Nr0   )rZ   zHTTP proxy: [{0}:{1}]r   z!HTTPS is unavailable and requiredFz#Python does not include SSL supportTr   z,HTTPS tunnelling is unavailable and requiredz(Python does not support HTTPS tunnellingr   r   )r:   r;   z;[HTTP Retry] Attempt {0} of {1} will delay {2} seconds: {3}r   )r!   r   rZ   r   r   r   r   z[HTTP Response] Status Code {0})rB   z'[HTTP Retry] {0} {1} -- Status Code {2}z*[HTTP Failed] {0} {1} -- HttpException {2}r   z$[HTTP Failed] {0} {1} -- IOError {2}z{0} -- {1} attempts made)'DEFAULT_RETRIESr@   r[   r   r   r   r   hasattrr   r   get_allow_httpr   SECURE_WARNING_EMITTEDwarnr   THROTTLE_DELAY_IN_SECONDSr>   timesleepr   rA   request_failedrC   rR   rM   maxTHROTTLE_RETRIESRESOURCE_GONE_CODESread_response_errorr   BAD_REQUESTINVALID_CONTAINER_CONFIGURATIONr   HTTPExceptionr^   rJ   IOErrorr   r#   )r   rW   r   r   r   r   	max_retryrB   retry_delayr   return_raw_responser    r!   rZ   rY   r   r   msgattemptr;   was_throttledrespresponse_errorrH   	clean_urls                            r"   http_requestr   h  s     #	! #-S/D$ *J
d+!0!?
JNN2J
K gj*;<""$?@@%KK=>%)" 
22LA""$JKK%KKBC%)"
CGEM
I
Q; ) .+'2=? 
 NN I	! JJu1:	 !%!(!(&*&*(.)0,6,6-8
:D NN<dkkJ"d##DKK[ICJJ6SVX\XcXcdC +4;;7(,$'	3C$D	 {{11!4T!:'77 {{j444!4T!:2nD/??K& .55c7C
DD# '' 	",S1I>EEfiYZ[C"1% 	"$$$T$:,S1I8??	STUC	s2   *9J $A&J A$J L$,KL$!8LL$
   c                 L    |t         }|t        }t        d| d|||||||
      S )a  
    NOTE: This method provides some logic to handle errors in the HTTP request, including checking the HTTP status of the response
          and handling some exceptions. If return_raw_response is set to True all the error handling will be skipped and the
          method will return the actual HTTP response and bubble up any exceptions while issuing the request. Also note that if
          return_raw_response is True no retries will be done.
    NGET)r   r   r   rB   r   r   r   r@   r   )rW   r   r   r   rB   r   r   r   s           r"   http_getr     sD     #	!T7 '"+"+$/$/,?A Ar,   c                 J    |t         }|t        }t        d| d ||||||	      S )NHEADr   r   r   rB   r   r   rW   r   r   r   rB   r   r   s          r"   	http_headr     s?     #	!T7 '"+"+$/$/1 1r,   c                 J    |t         }|t        }t        d| |||||||	      S )NPOSTr   r   )rW   r   r   r   r   rB   r   r   s           r"   	http_postr   /  s?     #	!T7 '"+"+$/$/1 1r,   c	                 L    |t         }|t        }t        d| ||||||||
      S )NPUT)r   r   r   rB   r   r   r   )	rW   r   r   r   r   rB   r   r   r   s	            r"   http_putr   E  sB     #	!T7 '"+"+$/$/$/1 1r,   c                 J    |t         }|t        }t        d| d ||||||	      S )NDELETEr   r   r   s          r"   http_deleter   ]  s?     #	!T7 '"+"+$/$/1 1r,   c                 .    |t         }t        | |       S )N)ok_codes)OK_CODESrequest_succeededr   r   s     r"   r   r   r  s     999r,   c                 :    |t         }| d uxr | j                  |v S r%   )r   rA   r   s     r"   r   r   x  s&    t7x 77r,   c                 2    | d uxr | j                   t        v S r%   )rA   NOT_MODIFIED_CODES)r   s    r"   request_not_modifiedr   ~  s    tA/A AAr,   c                 \    |t         }| duxr | j                  dk\  xr | j                  |vS )z`
    Host plugin will return 502 for any upstream issue, so a failure is any 5xx except 502
    Ni  )!HOSTPLUGIN_UPSTREAM_FAILURE_CODESrA   )r   upstream_failure_codess     r"   request_failed_at_hostpluginr     s8     %!Bt`s 2`t{{J`7``r,   c                    d}| 	 dj                  | j                  | j                  | j                               }t        dk  rt        |dd      }n$|j                  dd      j                  dd      }t        j                  |      }|S |S # t        $ r3}t        j                  t        j                  |             Y d }~|S d }~ww xY w)Nr   z[HTTP Failed] [{0}: {1}] {2}   asciiignore)encodingerrors)rR   rA   reasonreadr	   r   encodedecoder   replace_non_ascii	Exceptionr   r   format_exception)r   resultrH   s      r"   r   r     s    F	63::		%F  !#fwxHVWXV>VWXV>  //7F M6M  	6KK11!455M	6s   BB 	C(CCr%   )F)NNFNNNF)dr   rer4   r   rf   rn   azurelinuxagent.common.confcommonr   azurelinuxagent.common.loggerr   %azurelinuxagent.common.utils.textutilutilsr    azurelinuxagent.common.exceptionr   r   r   azurelinuxagent.common.futurer   r   r   azurelinuxagent.common.versionr	   r
   r   r   r   DELAY_IN_SECONDSr   r   r   compiler   RESET_CONTENTPARTIAL_CONTENT	FORBIDDENINTERNAL_SERVER_ERRORNOT_IMPLEMENTEDBAD_GATEWAYSERVICE_UNAVAILABLEGATEWAY_TIMEOUTINSUFFICIENT_STORAGEr@   'HGAP_GET_EXTENSION_ARTIFACT_RETRY_CODESappendr   GONEr   OKCREATEDACCEPTEDr   NOT_MODIFIEDr   r   rL   NotConnectedIncompleteReadImproperConnectionStateBadStatusLinerF   r   r   r   rR   r   HTTP_USER_AGENT_HEALTHr   "REQUEST_ROLE_CONFIG_FILE_NOT_FOUNDr6   r   objectr   r>   rC   rJ   rM   r[   r^   rk   rq   rz   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r+   r,   r"   <module>r&     s  ( 
 	     * * . . 8 8 ` ` D D a a    !&BJJ']^  $$""##& +6a. ' ' . .z/E/E F OO 
 MM  
 % !
 "" &&	  "":/GH%,,_= "A %D "%  5V 5B "#*: !F$/ .5
5.,M PUNS-d  !-"%*REl )!&A< *1. *10 )12  ,1*:8Bar,   