o
    RDiQ                     @  s  d dl m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 d dlmZ d	d
lmZmZ d	dlmZmZmZ erRejjZejjZd	dlmZmZ d	dl m!Z!m"Z" e#e$Z%g dZ&edd Z'G dd deZ(dgZ)d>ddZ*dd Z+d?ddZ,d>d d!Z-d@d$d%Z.d&d' Z/	(dAdBd)d*Z0d+d, Z1d@d-d.Z2d@d/d0Z3d1d2 Z4d3d4 Z5d@d5d6Z6d7d8 Z7e	dCdDd<d=Z8dS )E    )annotationsN)CancelledError)TimeoutError)ThreadPoolExecutor)contextmanager)Enum)cache   )'ENV_VAR_BOOL_POSITIVE_VALUES_LOWERCASED"ENV_VAR_DISABLE_PLATFORM_DETECTION)boto3botocoreinstalled_boto)SessionManagerSessionManagerFactory)RequestExceptionTimeout)z3snowflake.connector.vendored.urllib3.connectionpoolzbotocore.utilszbotocore.httpsessionzurllib3.connectionpoolc               
   c  s    i } z.t D ]}t|}|j| |< |tjd  qdV  W |  D ]\}}t|| q#dS |  D ]\}}t|| q6w )a8  
    Context manager to temporarily suppress all logs from underlying HTTP libraries during platform detection.

    This prevents noisy DEBUG logs and stack traces from urllib3 and botocore when detecting
    cloud platforms, which can confuse customers (SNOW-2204396). Our own debug logs are not affected.
    r	   N)_LOGGERS_TO_SUPPRESSlogging	getLoggerlevelsetLevelCRITICALitems)original_levelslogger_name
lib_loggerr    r   _/var/www/Datamplify/venv/lib/python3.10/site-packages/snowflake/connector/platform_detection.py!_suppress_platform_detection_logs%   s   

r   c                   @  s    e Zd ZdZdZdZdZdZdS )_DetectionStatez=Internal enum to represent the detection state of a platform.detectednot_detectedtimeoutworker_timeoutN)__name__
__module____qualname____doc__DETECTEDNOT_DETECTEDHTTP_TIMEOUTWORKER_TIMEOUTr   r   r   r   r    ;   s    r    disabled"platform_detection_timeout_secondsfloatc                 C  sb   t s
td tjS zt| dd}|dd| }|jr!tj	W S tjW S  t
y0   tj Y S w )ae  
    Check if the current environment is running on an AWS EC2 instance.

    If we query the AWS Instance Metadata Service (IMDS) for the instance identity document
    and receive content back, then we assume we are running on an EC2 instance.
    This function is compatible with IMDSv1 and IMDSv2 since we send the token in the request.
    It will ignore the token if on IMDSv1 and use the token if on IMDSv2.

    Args:
        platform_detection_timeout_seconds: Timeout value for the metadata service request.

    Returns:
        _DetectionState: DETECTED if running on EC2, NOT_DETECTED otherwise.
    z7boto3 is not installed, skipping EC2 instance detectionr	   )r#   num_attemptsz*/latest/dynamic/instance-identity/documentN)r   loggerdebugr    r*   IMDSFetcher_get_request_fetch_metadata_tokencontentr)   	Exception)r.   fetcherdocumentr   r   r   is_ec2_instanceH   s(   

r:   c                   C     dt jv rtjS tjS )a/  
    Check if the current environment is running in AWS Lambda.

    If we check for the LAMBDA_TASK_ROOT environment variable and it exists,
    then we assume we are running in AWS Lambda.

    Returns:
        _DetectionState: DETECTED if LAMBDA_TASK_ROOT env var exists, NOT_DETECTED otherwise.
    LAMBDA_TASK_ROOTosenvironr    r)   r*   r   r   r   r   is_aws_lambdam   
   
r@   arnstrreturnboolc                   s   ddg}t  fdd|D S )z
    Validate if an AWS ARN is suitable for use with Snowflake's Workload Identity Federation (WIF).

    Args:
        arn: The AWS ARN string to validate.

    Returns:
        bool: True if ARN is valid for WIF, False otherwise.
    z^arn:[^:]+:iam::[^:]+:user/.+$z&^arn:[^:]+:sts::[^:]+:assumed-role/.+$c                 3  s    | ]	}t | V  qd S N)rematch).0prB   r   r   	<genexpr>   s    z'is_valid_arn_for_wif.<locals>.<genexpr>)any)rB   patternsr   rK   r   is_valid_arn_for_wif~   s   rO   c                 C  s   t s
td tjS z*t| | ddid}tjd|d }|r#d|vr'tjW S t	|d r1tj
W S tjW S  ty@   tj Y S w )a  
    Check if the current environment has a valid AWS identity for authentication.

    If we retrieve an ARN from the caller identity and it is a valid WIF ARN,
    then we assume we have a valid AWS identity for authentication.

    Args:
        platform_detection_timeout_seconds: Timeout value for AWS API calls.

    Returns:
        _DetectionState: DETECTED if valid AWS identity exists, NOT_DETECTED otherwise.
    z7boto3 is not installed, skipping AWS identity detectiontotal_max_attemptsr	   )connect_timeoutread_timeoutretriessts)configArn)r   r1   r2   r    r*   Configr   clientget_caller_identityrO   r)   r7   )r.   rU   caller_identityr   r   r   has_aws_identity   s(   


r[   session_managerr   c                 C  ^   z|j dddi| d}|jdkrtjW S tjW S  ty#   tj Y S  ty.   tj Y S w )a   
    Check if the current environment is running on an Azure Virtual Machine.

    If we query the Azure Instance Metadata Service and receive an HTTP 200 response,
    then we assume we are running on an Azure VM.

    Args:
        platform_detection_timeout_seconds: Timeout value for the metadata service request.
        session_manager: SessionManager instance for making HTTP requests.

    Returns:
        _DetectionState: DETECTED if on Azure VM, HTTP_TIMEOUT if request times out,
                        NOT_DETECTED otherwise.
    z?http://169.254.169.254/metadata/instance?api-version=2021-02-01MetadataTrueheadersr#      getstatus_coder    r)   r*   r   r+   r   )r.   r\   
token_respr   r   r   is_azure_vm   s    


rg   c                  C  &   g d} t dd | D rtjS tjS )a  
    Check if the current environment is running in Azure Functions.

    If we check for Azure Functions environment variables (FUNCTIONS_WORKER_RUNTIME,
    FUNCTIONS_EXTENSION_VERSION, AzureWebJobsStorage) and they all exist,
    then we assume we are running in Azure Functions.

    Returns:
        _DetectionState: DETECTED if all Azure Functions env vars are present,
                        NOT_DETECTED otherwise.
    )FUNCTIONS_WORKER_RUNTIMEFUNCTIONS_EXTENSION_VERSIONAzureWebJobsStoragec                 s      | ]}|t jv V  qd S rF   r>   r?   rI   varr   r   r   rL          z$is_azure_function.<locals>.<genexpr>allr    r)   r*   service_varsr   r   r   is_azure_function   s   ru   https://management.azure.comc                 C  sl   d| }ddi}z|j ||| d}|jdkrtjW S tjW S  ty*   tj Y S  ty5   tj Y S w )a  
    Check if Azure Managed Identity is available and accessible on an Azure VM.

    If we attempt to mint an access token from the Azure Instance Metadata Service
    managed identity endpoint and receive an HTTP 200 response,
    then we assume managed identity is available.

    Args:
        platform_detection_timeout_seconds: Timeout value for the metadata service request.
        session_manager: SessionManager instance for making HTTP requests.
        resource: The Azure resource URI to request a token for.

    Returns:
        _DetectionState: DETECTED if managed identity is available, HTTP_TIMEOUT if request
                        times out, NOT_DETECTED otherwise.
    zVhttp://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=r^   truer`   rb   rc   )r.   r\   resourceendpointra   responser   r   r   )is_managed_identity_available_on_azure_vm   s    



r{   c                   C  s   t tjdS )NIDENTITY_HEADER)rE   r>   r?   rd   r   r   r   r   /is_managed_identity_available_on_azure_function  s   r}   c                 C  s(   t  tjkrt rtjS tjS t| |S )aF  
    Determine if Azure Managed Identity is available in the current environment.

    If we are on Azure Functions and the IDENTITY_HEADER environment variable exists,
    then we assume managed identity is available.
    If we are on an Azure VM and can mint an access token from the managed identity endpoint,
    then we assume managed identity is available.
    Handles Azure Functions first since the checks are faster
    Handles Azure VM checks second since they involve network calls.

    Args:
        platform_detection_timeout_seconds: Timeout value for managed identity checks.
        session_manager: SessionManager instance for making HTTP requests.

    Returns:
        _DetectionState: DETECTED if managed identity is available, HTTP_TIMEOUT if
                        detection timed out, NOT_DETECTED otherwise.
    )ru   r    r)   r}   r*   r{   )r.   r\   r   r   r   has_azure_managed_identity  s   r~   c                 C  sd   z|j d| d}|jr|j ddkrtjW S tjW S  ty&   tj Y S  ty1   tj Y S w )a-  
    Check if the current environment is running on Google Compute Engine (GCE).

    If we query the Google metadata server and receive a response with the
    "Metadata-Flavor: Google" header, then we assume we are running on GCE.

    Args:
        platform_detection_timeout_seconds: Timeout value for the metadata service request.
        session_manager: SessionManager instance for making HTTP requests.

    Returns:
        _DetectionState: DETECTED if on GCE, HTTP_TIMEOUT if request times out,
                        NOT_DETECTED otherwise.
    zhttp://metadata.google.internalr#   Metadata-FlavorGoogle)rd   ra   r    r)   r*   r   r+   r   r.   r\   rz   r   r   r   	is_gce_vm7  s"   

r   c                  C  rh   )a  
    Check if the current environment is running in Google Cloud Run service.

    If we check for Cloud Run service environment variables (K_SERVICE, K_REVISION,
    K_CONFIGURATION) and they all exist, then we assume we are running in Cloud Run service.

    Returns:
        _DetectionState: DETECTED if all Cloud Run service env vars are present,
                        NOT_DETECTED otherwise.
    )	K_SERVICE
K_REVISIONK_CONFIGURATIONc                 s  rl   rF   rm   rn   r   r   r   rL   f  rp   z+is_gcp_cloud_run_service.<locals>.<genexpr>rq   rs   r   r   r   is_gcp_cloud_run_serviceX     r   c                  C  s&   ddg} t dd | D rtjS tjS )a  
    Check if the current environment is running in Google Cloud Run job.

    If we check for Cloud Run job environment variables (CLOUD_RUN_JOB, CLOUD_RUN_EXECUTION)
    and they both exist, then we assume we are running in a Cloud Run job.

    Returns:
        _DetectionState: DETECTED if all Cloud Run job env vars are present,
                        NOT_DETECTED otherwise.
    CLOUD_RUN_JOBCLOUD_RUN_EXECUTIONc                 s  rl   rF   rm   rn   r   r   r   rL   y  rp   z'is_gcp_cloud_run_job.<locals>.<genexpr>rq   )job_varsr   r   r   is_gcp_cloud_run_jobk  r   r   c                 C  r]   )aK  
    Check if the current environment has a valid Google Cloud Platform identity.

    If we query the GCP metadata service for the default service account email
    and receive a non-empty response, then we assume we have a valid GCP identity.

    Args:
        platform_detection_timeout_seconds: Timeout value for the metadata service request.
        session_manager: SessionManager instance for making HTTP requests.
    Returns:
        _DetectionState: DETECTED if valid GCP identity exists, HTTP_TIMEOUT if request
                        times out, NOT_DETECTED otherwise.
    zZhttp://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/emailr   r   r`   rb   rc   r   r   r   r   has_gcp_identity~  s    


r   c                   C  r;   )a3  
    Check if the current environment is running in GitHub Actions.

    If we check for the GITHUB_ACTIONS environment variable and it exists,
    then we assume we are running in GitHub Actions.

    Returns:
        _DetectionState: DETECTED if GITHUB_ACTIONS env var exists, NOT_DETECTED otherwise.
    GITHUB_ACTIONSr=   r   r   r   r   is_github_action  rA   r   float | NoneSessionManager | None	list[str]c                 C  s   zt jtd tv rtdt tW S | du rd} |du r+td t	j
ddd}d	}| d
|  }| }t  t t t t t d}| dkrtdd]}|t||t||t|||t|||t|||t||d}| D ]+\}}	z
|	j|d||< W qy ttfy   tj||< Y qy ty   tj ||< Y qyw W d   n1 sw   Y  g }
| D ]\}}|tj!kr|
"| q|tj#tjfv r|
"| d qtd|
 |
W  d   W S 1 sw   Y  W dS  ty   g  Y S w )a  
    Detect all potential platforms that the current environment may be running on.
    Swallows all exceptions and returns an empty list if any exception occurs to not affect main driver functionality.

    Args:
        platform_detection_timeout_seconds: Timeout value for platform detection requests. Defaults to 0.2 seconds
                if None is provided.
        session_manager: SessionManager instance for making HTTP requests. If None, a new instance will be created.

    Returns:
        list[str]: List of detected platform names. Platforms that timed out (either HTTP timeout
                  or thread timeout) will have "_timeout" suffix appended to their name.
                  Returns _PLATFORM_DETECTION_DISABLED_RESULT if the ENV_VAR_DISABLE_PLATFORM_DETECTION
                  environment variable is set to a value in ENV_VAR_BOOL_POSITIVE_VALUES_LOWERCASED
                  (case-insensitive). Returns empty list if any exception occurs during detection.
     z7Platform detection disabled via %s environment variableNg?zONo session manager provided. HTTP settings may not be preserved. Using default.Fr   )use_poolingmax_retriesg?r	   )r@   ru   is_gce_cloud_run_serviceis_gce_cloud_run_jobr   g           )max_workers)r:   r[   rg   r~   r   r   r   _timeoutz4Platform detection completed. Detected platforms: %s)$r>   r?   rd   r   lowerr
   r1   r2   #_PLATFORM_DETECTION_DISABLED_RESULTr   get_managerr   r@   ru   r   r   r   r   submitr:   r[   rg   r~   r   r   r   resultFutureTimeoutErrorFutureCancelledErrorr    r,   r7   r*   r)   appendr+   )r.   r\   http_timeout_epsilonhttp_timeoutthreads_timeout	platformsexecutorfutureskeyfuturedetected_platformsplatform_namedetection_stater   r   r   detect_platforms  s   	*
(Er   )r.   r/   )rB   rC   rD   rE   )r.   r/   r\   r   )rv   )r\   r   rF   )r.   r   r\   r   rD   r   )9
__future__r   r   r>   rG   concurrent.futuresr   r   r   r   concurrent.futures.threadr   
contextlibr   enumr   	functoolsr   	constantsr
   r   optionsr   r   r   rU   rW   utilsr3   r\   r   r   vendored.requestsr   r   r   r%   r1   r   r   r    r   r:   r@   rO   r[   rg   ru   r{   r}   r~   r   r   r   r   r   r   r   r   r   r   <module>   sR    



%


#"&

!!
!