
    ,                    :   d Z ddlm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dlmZ ddlmZ ddlmZ ddlmZ ddlmZ  G d dej0                        Z G d de      ZdZ G d de      Zd ZddZdZddZ ddZ!d Z"y) zFUtilities for loading and parsing kubeconfig used for Connect Gateway.    )absolute_import)annotations)division)unicode_literalsN)Any)
kubeconfig)config)
exceptions)log)
properties)yaml)encoding)files)	platformsc                      e Zd ZdZy)Errorz0Class for errors raised by kubeconfig utilities.N__name__
__module____qualname____doc__     Clib/googlecloudsdk/command_lib/container/fleet/gwkubeconfig_util.pyr   r   %   s    8r   r   c                      e Zd ZdZy)MissingEnvVarErrorzDAn exception raised when required environment variables are missing.Nr   r   r   r   r   r   )   s    Lr   r   gke_gcloud_auth_plugin_cachec                      e Zd ZdZddZed        Zed        Zd Zd Z	d Z
ed        Zed	        Zeddd       Zed        Zed        Zed        ZdddZy
)
Kubeconfigz1Interface for interacting with a kubeconfig file.c                .   || _         || _        i | _        i | _        i | _        | j                  d   D ]  }|| j                  |d   <    | j                  d   D ]  }|| j                  |d   <    | j                  d   D ]  }|| j                  |d   <    y )Nclustersnameuserscontexts)	_filename_datar!   r#   r$   )selfraw_datafilenameclusterusercontexts         r   __init__zKubeconfig.__init__2   s    DNDJDMDJDM::j)'.dmmGFO$ *

7#!%djjf $::j)'.dmmGFO$ *r   c                     | j                   d   S Ncurrent-contextr&   r'   s    r   current_contextzKubeconfig.current_context?   s    ::'((r   c                    | j                   S N)r%   r2   s    r   r)   zKubeconfig.filenameC   s    >>r   c                   | j                   j                  |d        | j                  j                  |d        | j                  j                  |d        | j                  j                  d      |k(  rd| j                  d<   y y )Nr0    )r$   popr!   r#   r&   get)r'   keys     r   ClearzKubeconfig.ClearG   sf    MMc4 MMc4 JJNN3zz~~'(C/&(djj"# 0r   c                   t        | j                  j                               | j                  d<   t        | j                  j                               | j                  d<   t        | j
                  j                               | j                  d<   t        j                  | j                  d      }t        j                  | j                  d      5 }t        j                  | j                  |       ddd       t        j                  j                  | j                        }t        j                  j                  |t              }t        j                  j!                  |      rt        j"                  |d       yy# 1 sw Y   xY w)zjSave kubeconfig to file.

    Raises:
      Error: don't have the permission to open kubeconfig file.
    r!   r#   r$   NT)privater7   )listr!   valuesr&   r#   r$   r   dump
file_utils
FileWriterr%   ospathdirnamejoin&GKE_GCLOUD_AUTH_PLUGIN_CACHE_FILE_NAMEexistsWriteFileAtomically)r'   _fprE    gke_gcloud_auth_plugin_file_paths        r   
SaveToFilezKubeconfig.SaveToFileN   s    "$--"6"6"89DJJztzz0023DJJw!$--"6"6"89DJJz
 			$**d#A			t~~t	<
ii

B 
= ggoodnn-G')ww||7(9$	ww~~67$$%ErJ 8 
=	<s   !E??Fc                "    || j                   d<   y r/   r1   )r'   r,   s     r   SetCurrentContextzKubeconfig.SetCurrentContexti   s    $+DJJ !r   c           
         |st        d      	 dD ]?  }t        ||   t              rt        dj                  ||   t	        ||                      y# t
        $ r}t        dj                  |            d}~ww xY w)z2Make sure we have the main fields of a kubeconfig.z
empty file)r!   r#   r$   zinvalid type for {0}: {1}zexpected key {0} not foundN)r   
isinstancer>   formattypeKeyError)clsdatar:   errors       r   	_ValidatezKubeconfig._Validatel   s     ,>2#$s)T*)00cDcOLN N 3  >.55e<==>s   A +A 	A<A77A<c                    	 t        j                  |      }| j                  |        | ||      S # t         j                  $ r*}t        dj                  ||j                              d }~ww xY w)Nz&unable to load kubeconfig for {0}: {1})r   	load_pathr   rR   inner_errorrX   )rU   r)   rV   rW   s       r   LoadFromFilezKubeconfig.LoadFromFiley   sl    (^^H%d MM$tX	 :: (:AA
E%%' ( ((s   1 A.%A))A.Nc                    	 t        j                  |      }| j	                  |       |s| j                         } | ||      S # t         j                  $ r}t        d|j                         d}~ww xY w)a  Parse a YAML kubeconfig.

    Args:
      raw_data: The YAML data to parse
      path: The path to associate with the data. Defaults to calling
        `Kubeconfig.DefaultPath()`.

    Returns:
      A `Kubeconfig` instance.

    Raises:
      Error: The data is not valid YAML.
    z"unable to parse kubeconfig bytes: N)r   loadr   r[   rX   DefaultPath)rU   r(   rD   rV   rW   s        r   LoadFromByteszKubeconfig.LoadFromBytes   sq    LYYx d MM$__dtT? :: L6u7H7H6IJKKLs   A A3A..A3c                R   	 | j                  |      S # t        t        f$ r}t        j                  dj                  ||             t        j                  t        j                  j                  |              | t               |      }|j                          |cY d}~S d}~ww xY w)zARead in the kubeconfig, and if it doesn't exist create one there.z6unable to load default kubeconfig: {0}; recreating {1}N)r\   r   IOErrorr   debugrR   rA   MakeDirrC   rD   rE   EmptyKubeconfigrM   )rU   r)   rW   r   s       r   LoadOrCreatezKubeconfig.LoadOrCreate   s    h''7 	iiHOO
 23((3js    B&A9B!B&!B&c                H    | j                  t        j                               S r5   )rf   r   r_   )rU   s    r   DefaultzKubeconfig.Default   s    J22455r   c                 J   t        j                  t        j                  d      } | rA| j	                  t        j
                        d   } t        j                  j                  |       S t        j                  t        j                  d      }|st        j                  j                         rt        j                  t        j                  d      }t        j                  t        j                  d      }|r"|r t        j                  j                  ||      }|s$t        j                  t        j                  d      }|sDt        dj                  t        j                  j                         rd	            d	            t        j                  j                  |d
d      S )z(Return default path for kubeconfig file.
KUBECONFIGr   HOME	HOMEDRIVEHOMEPATHUSERPROFILEzVenvironment variable {vars} or KUBECONFIG must be set to store credentials for kubectlz&HOMEDRIVE/HOMEPATH, USERPROFILE, HOME,)varsz.kuber	   )r   GetEncodedValuerC   environsplitpathseprD   abspathr   OperatingSystem	IsWindowsrF   r   rR   )r   home_dir
home_drive	home_paths       r   r_   zKubeconfig.DefaultPath   sG    ))"**lCJ##BJJ/2jWW__Z(( ''

F;H	11;;=++BJJDj**2::zBi		77<<
I6++BJJF$$*F**446 < %+ %DE E =C %+ %DE E
 77<<'844r   c                h   | |}}|r||}}| j                  |j                  xs |j                         t        t        |j                  j                               t        |j                  j                               z         | _        t        t        |j                  j                               t        |j                  j                               z         | _        t        t        |j                  j                               t        |j                  j                               z         | _        y)aB  Merge another kubeconfig into self.

    By default, in case of overlapping keys, the value in self is kept and the
    value in the other kubeconfig is lost.

    Args:
      kubeconfig: a Kubeconfig instance
      overwrite: whether to overwrite overlapping keys in self with data from
        the other kubeconfig.
    N)rO   r3   dictr>   r!   itemsr#   r$   )r'   r   	overwriteleftrights        r   MergezKubeconfig.Merge   s     
%D4Ed4//H53H3HIU^^!!#$tDMM,?,?,A'BBDDMU[[ !D)9)9);$<<>DJU^^!!#$tDMM,?,?,A'BBDDMr   )r(   zdict[str, Any]r)   strr5   )r(   bytesrD   r   returnr   )F)r   r   r}   boolr   None)r   r   r   r   r-   propertyr3   r)   r;   rM   rO   classmethodrX   r\   r`   rf   rh   staticmethodr_   r   r   r   r   r   r   /   s    9/ ) )  )K6, 
> 
>    2 
 
 6 6 5 54Dr   r   c                    d|i}| |dS )z0Generate and return a cluster kubeconfig object.server)r"   r*   r   )r"   r   r*   s      r   Clusterr      s"     ' 
 r   c                0    t        j                  | |      S )au  Generate and return a user kubeconfig object.

  Args:
    name: str, nickname for this user entry.
    auth_provider: str, authentication provider if not using `exec`. `exec` may
      still be used regardless of this parameter's value.
  Returns:
    dict, valid kubeconfig user entry.

  Raises:
    Error: if no auth_provider is not provided when `exec` is not used.
  r"   auth_provider)container_kubeconfigUserr   s     r   r   r      s     
	"	"!
 r   zPath to sdk installation not found. Please switch to application default
credentials using one of

$ gcloud config set container/use_application_default_credentials true
$ export CLOUDSDK_CONTAINER_USE_APPLICATION_DEFAULT_CREDENTIALS=truec                   d| i}| dk(  rt         j                  j                  j                  j	                         sd}t
        j                  j                         rd}t        j                         j                  }|(t        j                  t               t        t              t        j                   j#                  ||      dddd}||d	<   |S )
a  Generate and return an auth provider config.

  Constructs an auth provider config entry readable by kubectl. This tells
  kubectl to call out to a specific gcloud command and parse the output to
  retrieve access tokens to authenticate to the kubernetes master.
  Kubernetes gcp auth provider plugin at
  https://github.com/kubernetes/kubernetes/tree/master/staging/src/k8s.io/client-go/plugin/pkg/client/auth/gcp

  Args:
    name: auth provider name
  Returns:
    dict, valid auth provider config entry.
  Raises:
    Error: Path to sdk installation not found. Please switch to application
    default credentials using one of

    $ gcloud config set container/use_application_default_credentials true
    $ export CLOUDSDK_CONTAINER_USE_APPLICATION_DEFAULT_CREDENTIALS=true.
  r"   gcpgcloudz
gcloud.cmdz"config config-helper --format=jsonz{.credential.access_token}z{.credential.token_expiry})zcmd-pathzcmd-argsz	token-keyz
expiry-keyr	   )r   VALUES	containeruse_app_default_credentialsGetBoolr   ru   rv   r	   Pathssdk_bin_pathr   rW   SDK_BIN_PATH_NOT_FOUNDr   rC   rD   rF   )r"   providerbin_namer   cfgs        r   _AuthProviderr     s    ( d^(
em!!==EEGH  **,h<<>..L	ii&'()) GGLLx8812C HX	/r   c                $    ||d}|r||d<   | |dS )z0Generate and return a context kubeconfig object.)r*   r+   	namespace)r"   r,   r   )r"   r*   r+   r   ctxs        r   Contextr   8  s0     	#  C
 r   c                     dg g ddi g dS )Nv1r7   Config)
apiVersionr$   r!   r0   kindpreferencesr#   r   r   r   r   re   re   F  s!    
 r   r5   )r   )#r   
__future__r   r   r   r   rC   typingr    googlecloudsdk.api_lib.containerr   r   googlecloudsdk.corer	   r
   core_exceptionsr   r   r   googlecloudsdk.core.utilr   r   rA   r   r   r   rG   objectr   r   r   r   r   r   re   r   r   r   <module>r      s     M & "  ' 	  O & = # * $ - 8 .9O!! 9M M *H &pD pDf&H -`	r   