o
    Q+                     @   s  d Z ddlmZ ddlmZ ddlm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ZG dd deZG dd deZG dd deZG dd deZejdddejjj fddZd ddZG dd deZdae Z dd Z!dS )!zFetching GCE metadata.    )absolute_import)division)unicode_literalsN)
properties)	gce_cache)gce_read)retry)urllibzNinsecure-cloudtop-shared-user@cloudtop-prod.google.com.iam.gserviceaccount.comc                   @      e Zd ZdZdS )ErrorzExceptions for the gce module.N__name__
__module____qualname____doc__ r   r   @/tmp/google-cloud-sdk/lib/googlecloudsdk/core/credentials/gce.pyr   %       r   c                   @   r
   )MetadataServerException9Exception for when the metadata server cannot be reached.Nr   r   r   r   r   r   )   r   r   c                   @   r
   )&CannotConnectToMetadataServerExceptionr   Nr   r   r   r   r   r   -   r   r   c                   @   r
   )MissingAudienceForIdTokenErrorzBException for when audience is missing from ID token minting call.Nr   r   r   r   r   r   1   r   r      )max_retrialsr   c              
   C   s   zt | |W S  tjjy. } z|j|v rW Y d}~dS |jdkr&tdt|d}~w tjjy? } zt|d}~ww )zCReads data from a URI with no proxy, yielding cloud-sdk exceptions.Ni  zThe request is rejected. Please check if the metadata server is concealed.
See https://cloud.google.com/kubernetes-engine/docs/how-to/protecting-cluster-metadata#concealment for more information about metadata server concealment.)	r   ReadNoProxyr	   error	HTTPErrorcoder   URLErrorr   )urihttp_errors_to_ignoretimeouter   r   r   _ReadNoProxyWithCleanFailures5   s   

r#   Fc                    s    fdd}|S )a  Handles when the metadata server is missing and resets the caches.

  If you move gcloud from one environment to another, it might still think it
  in on GCE from a previous invocation (which would result in a crash).
  Instead of crashing, we ignore the error and just update the cache.

  Args:
    return_list: True to return [] instead of None as the default empty answer.

  Returns:
    The value the underlying method would return.
  c                    s    fdd}|S )Nc                    sj   z | g|R i |W S  t y4   t t | _W d    n1 s%w   Y  r0g  Y S d  Y S w N)r   _metadata_lockr   ForceCacheRefresh	connected)selfargskwargs)freturn_listr   r   Inner\   s   z=_HandleMissingMetadataServer.<locals>._Wrapper.<locals>.Innerr   )r+   r-   r,   )r+   r   _WrapperZ   s   z._HandleMissingMetadataServer.<locals>._Wrapperr   )r,   r/   r   r.   r   _HandleMissingMetadataServerK   s   r0   c                   @   s~   e Zd ZdZdd Ze dd Ze dd Zedd	d
d Ze dd Z	dd Z
e 		dddZe dd ZdS )_GCEMetadatazsClass for fetching GCE metadata.

  Attributes:
      connected: bool, True if the metadata server is available.
  c                 C   s   t  | _d S r$   )r   GetOnGCEr'   )r(   r   r   r   __init__p   s   z_GCEMetadata.__init__c                 C   s(   | j sdS ttjdd}|tkrdS |S )a  Get the default service account for the host GCE instance.

    Fetches GOOGLE_GCE_METADATA_DEFAULT_ACCOUNT_URI and returns its contents.

    Raises:
      CannotConnectToMetadataServerException: If the metadata server
          cannot be reached.
      MetadataServerException: If there is a problem communicating with the
          metadata server.

    Returns:
      str, The email address for the default service account. None if not on a
          GCE VM, or if there are no service accounts associated with this VM.
    Ni  r    )r'   r#   r   'GOOGLE_GCE_METADATA_DEFAULT_ACCOUNT_URICLOUDTOP_COMMON_SERVICE_ACCOUNT)r(   accountr   r   r   DefaultAccounts   s   z_GCEMetadata.DefaultAccountc                 C   s    | j sdS ttj}|r|S dS )a  Get the project that owns the current GCE instance.

    Fetches GOOGLE_GCE_METADATA_PROJECT_URI and returns its contents.

    Raises:
      CannotConnectToMetadataServerException: If the metadata server
          cannot be reached.
      MetadataServerException: If there is a problem communicating with the
          metadata server.

    Returns:
      str, The project ID for the current active project. None if no project is
          currently active.
    N)r'   r#   r   GOOGLE_GCE_METADATA_PROJECT_URI)r(   projectr   r   r   Project   s   z_GCEMetadata.ProjectTr.   c                 C   sX   | j sg S ttjd }| }g }|D ]}|d}|dks#|tkr$q|| q|S )aU  Get the list of service accounts available from the metadata server.

    Returns:
      [str], The list of accounts. [] if not on a GCE VM.

    Raises:
      CannotConnectToMetadataServerException: If no metadata server is present.
      MetadataServerException: If there is a problem communicating with the
          metadata server.
    /default)r'   r#   r    GOOGLE_GCE_METADATA_ACCOUNTS_URIsplitstripr7   append)r(   accounts_listingaccounts_linesaccountsaccount_liner8   r   r   r   Accounts   s   
z_GCEMetadata.Accountsc                 C   s.   | j sdS ttjdd}|r|dd S dS )a  Get the name of the zone containing the current GCE instance.

    Fetches GOOGLE_GCE_METADATA_ZONE_URI, formats it, and returns its contents.

    Raises:
      CannotConnectToMetadataServerException: If the metadata server
          cannot be reached.
      MetadataServerException: If there is a problem communicating with the
          metadata server.

    Returns:
      str, The short name (e.g., us-central1-f) of the zone containing the
          current instance.
      None if not on a GCE VM.
    Nr4   r5   r=   )r'   r#   r   GOOGLE_GCE_METADATA_ZONE_URIr@   )r(   	zone_pathr   r   r   Zone   s   z_GCEMetadata.Zonec                 C   s2   | j sdS |  }|rd|ddd S dS )a  Get the name of the region containing the current GCE instance.

    Fetches GOOGLE_GCE_METADATA_ZONE_URI, extracts the region associated
    with the zone, and returns it.  Extraction is based property that
    zone names have form <region>-<zone> (see https://cloud.google.com/
    compute/docs/zones) and an assumption that <zone> contains no hyphens.

    Raises:
      CannotConnectToMetadataServerException: If the metadata server
          cannot be reached.
      MetadataServerException: If there is a problem communicating with the
          metadata server.

    Returns:
      str, The short name (e.g., us-central1) of the region containing the
          current instance.
      None if not on a GCE VM.
    N-rH   )r'   rK   joinr@   )r(   zoner   r   r   Region   s    z_GCEMetadata.RegionstandardFc                 C   s:   | j sdS |s
t |rdnd}ttjj|||dddS )a  Get a valid identity token on the host GCE instance.

    Fetches GOOGLE_GCE_METADATA_ID_TOKEN_URI and returns its contents.

    Args:
      audience: str, target audience for ID token.
      token_format: str, Specifies whether or not the project and instance
        details are included in the identity token. Choices are "standard",
        "full".
      include_license: bool, Specifies whether or not license codes for images
        associated with GCE instance are included in their identity tokens

    Raises:
      CannotConnectToMetadataServerException: If the metadata server
          cannot be reached.
      MetadataServerException: If there is a problem communicating with the
          metadata server.
      MissingAudienceForIdTokenError: If audience is missing.

    Returns:
      str, The id token or None if not on a CE VM, or if there are no
      service accounts associated with this VM.
    NTRUEFALSE)audienceformatlicensesr4   r5   )r'   r   r#   r    GOOGLE_GCE_METADATA_ID_TOKEN_URIrT   )r(   rS   token_formatinclude_licenser   r   r   
GetIdToken   s   z_GCEMetadata.GetIdTokenc                 C   s,   | j sdS ttjdd}|stjjjjS |S )a}  Get the universe domain of the current GCE instance.

    If the GCE metadata server universe domain endpoint is not found, or the
    endpoint returns an empty string, return the default universe domain
    (googleapis.com); otherwise return the fetched universe domain value, or
    raise an exception if the request fails.

    Raises:
      CannotConnectToMetadataServerException: If the metadata server
          cannot be reached.
      MetadataServerException: If there is a problem communicating with the
          metadata server.

    Returns:
      str, The universe domain value from metadata server. None if not on GCE.
    Nr4   r5   )	r'   r#   r   'GOOGLE_GCE_METADATA_UNIVERSE_DOMAIN_URIr   VALUEScoreuniverse_domainr>   )r(   r]   r   r   r   UniverseDomain(  s   z_GCEMetadata.UniverseDomainN)rP   F)r   r   r   r   r3   r0   r9   r<   rG   rK   rO   rY   r^   r   r   r   r   r1   i   s$    



(r1   c                   C   sD   t  tst aW d   tS W d   tS 1 sw   Y  tS )zGet a singleton for the GCE metadata class.

  Returns:
    _GCEMetadata, An object used to collect information from the GCE metadata
    server.
  N)r%   	_metadatar1   r   r   r   r   MetadataK  s   

r`   )F)"r   
__future__r   r   r   	threadinggooglecloudsdk.corer   googlecloudsdk.core.credentialsr   r   googlecloudsdk.core.utilr   	six.movesr	   r7   	Exceptionr   r   r   r   RetryOnExceptionr[   computegce_metadata_read_timeout_secGetIntr#   r0   objectr1   r_   Lockr%   r`   r   r   r   r   <module>   s2   

 _