
    p[                        d Z ddlmZ ddlmZ ddlmZ ddl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 dZdZ G d dej,                        Z G d de      Zd Zd Zd Zd Zd Zd Z G d de      Zd(dZ 	 	 	 	 	 	 	 	 	 	 d)dZ!dZ"dZ#de#z   Z$d  Z%	 	 	 	 	 d*d!Z&d" Z'd# Z(d$e#z   Z)d% Z*d& Z+d' Z,y)+z,Utilities for generating kubeconfig entries.    )absolute_import)division)unicode_literalsN)config)
exceptions)log)yaml)encoding)files)	platformsa!  
Fetch credentials for a running {kind} cluster.
This command updates a kubeconfig file with appropriate credentials and
endpoint information to point kubectl at a specific {kind} cluster.
By default, credentials are written to ``HOME/.kube/config''.
You can provide an alternate path by setting the ``KUBECONFIG'' environment
variable. If ``KUBECONFIG'' contains multiple paths, the first one is used.
This command enables switching to a specific cluster, when working
with multiple clusters. It can also be used to access a previously created
cluster from a new workstation.
The command will configure kubectl to automatically refresh its
credentials using the same identity as the gcloud command-line tool.
See [](https://cloud.google.com/kubernetes-engine/docs/kubectl) for
kubectl documentation.
z
To get credentials of a cluster named ``my-cluster'' managed in location ``us-west1'',
run:
$ {command} my-cluster --location=us-west1
c                       e Zd ZdZy)Errorz>Class for errors raised by edgecontainer kubeconfig utilities.N__name__
__module____qualname____doc__     Alib/googlecloudsdk/command_lib/edge_cloud/container/kubeconfig.pyr   r   8   s    Fr   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   c                 .    d}|j                  | ||      S )a  Generates a kubeconfig context for a Edge Container cluster.

  Args:
    project_id: str, project ID associated with the cluster.
    location: str, Google location of the cluster.
    cluster_id: str, ID of the cluster.

  Returns:
    The context for the kubeconfig entry.
  z2edgecontainer_{project_id}_{location}_{cluster_id})
project_idlocation
cluster_id)format)r   r   r   templates       r   GenerateContextr   @   s)     B(	h: 
 
G Gr   c                 f    d}|j                  | j                  dn| j                  dz   |||      S )a\  Generates command arguments for kubeconfig's authorization provider.

  Args:
    track: ReleaseTrack of gcloud command.
    cluster_id: str, ID of the cluster.
    project_id: str, ID of the project of the cluster.
    location: str, Google location of the cluster.

  Returns:
    The command arguments for kubeconfig's authorization provider.
  zr{prefix}edge-cloud container clusters print-access-token {cluster_id} --project={project_id} --location={location}  )prefixr   r   r   )r   r#   )trackr   r   r   r   s        r   GenerateAuthProviderCmdArgsr%   P   sE    B  
<<'RU\\C-?	 
 
 r   c                     dd|d|d| gS )z(Returns exec auth provider command args.z--use_edge_cloudz	--projectz
--locationz	--clusterr   )r   r   r   s      r   GenerateExecAuthCmdArgsr'   h   s#     
 r   c           	      l   t         j                         }t               }t        |||      |j                  |<   |d   j                  t        |||             i }|j                  t        j                  d       nt        |j                        |d<   |j                  t        j                  d       nt        |j                        |d<   t        |fi |}|d   d= ||j                  |<   |d	   j                  |       t        | d
d      }|d}i }| j                  t        j                  d       nt        | j                        |d<   t!        |dj#                  | j$                  |      fi ||j&                  |<   |d   j                  t!        |dj#                  | j$                  |      fi |       |j)                  |       ||d<   t+        j,                  |t.        j0                         |j3                          t        j4                  j7                  dj#                  |             y)aJ  Generates a kubeconfig entry based on offline credential for a Edge Container cluster.

  Args:
    cluster: object, Edge Container cluster.
    context: str, context for the kubeconfig entry.
    credential_resp: Response from GetOfflineCredential API.

  Raises:
      Error: don't have the permission to open kubeconfig file
  contextsNz)Offline credential is missing client key.key_dataz1Offline credential is missing client certificate.	cert_datauserexecusersporti  .Cluster is missing certificate authority data.ca_datahttps://{}:{}clusterscurrent-contextNA new kubeconfig entry "{}" has been generated and set as the current context.)
KubeconfigDefaultEmptyKubeconfigContextr)   append	clientKeyr   error_GetPemDataForKubeconfigclientCertificateUserr.   getattrclusterCaCertificatewarningClusterr   endpointr3   SetCurrentContextr	   dumpsysstderr
SaveToFilestatusPrint)	clustercontextcredential_resp
kubeconfigkubeconfig_for_outputuser_kwargsr,   r/   cluster_kwargss	            r   &GenerateKubeconfigForOfflineCredentialrS   v   s    !!#*)+!('7!C*g
#**77GW+MN+&II9:6!!K
 &&.IIAB7)) K 
g	%	%$
6l6"*7 ''-	&#	&$	\D.!!)KK@A 8$$!N9 ")%%g&6&6="AO"*g 
#**


 
 !1!14
8  w'-4)*))!3::.**r   c                 H   t         j                         }t        |||      |j                  |<   d||dd|d}t	        |fi |}||j
                  |<   i }| j                  t        j                  d       nt        | j                        |d<   t        | dd	      }	|	d	}	t        |d
j                  | j                  |	      fi ||j                  |<   |j                  |       |j!                          t        j"                  j%                  dj                  |             y)a  Generates a kubeconfig entry for a Edge Container cluster.

  Args:
    cluster: object, Edge Container cluster.
    context: str, context for the kubeconfig entry.
    cmd_path: str, authentication provider command path.
    cmd_args: str, authentication provider command arguments.
    exec_args: str, exec auth command arguments.

  Raises:
      Error: don't have the permission to open kubeconfig file
  gcpz{.expireTime}z{.accessToken})auth_providerauth_provider_cmd_pathauth_provider_cmd_argsauth_provider_expiry_keyauth_provider_token_keyexec_auth_argsNr0   r1   r/   i+  r2   r5   )r6   r7   r9   r)   r?   r.   rA   r   rB   r=   r@   rC   r   rD   r3   rE   rI   rJ   rK   )
rL   rM   cmd_pathcmd_args	exec_argsrO   rQ   r,   rR   r/   s
             r   GenerateKubeconfigr_      s&    !!#*!('7!C*g ( ("1!1!+ 
g	%	%$"*7.!!)KK@A 8$$!N9
 
&$	'$	\D!(%%g&6&6="QAO"Q*gw'***r   c                 h    t        j                  | j                  d            j                  d      S )Nzutf-8)base64	b64encodeencodedecode)pems    r   r=   r=      s)     
		#**W-	.	5	5g	>>r   c                       e Zd ZdZd Zed        Zed        Zd Zd Z	d Z
ed        Zed	        Zed
        Zed        Zed        Zd Zy)r6   z1Interface 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 )Nr3   namer.   r)   )	_filename_datar3   r.   r)   )selfraw_datafilenamerL   r,   rM   s         r   __init__zKubeconfig.__init__   s    DNDJDMDJDM::j)'.dmmGFO$ *

7#!%djjf $::j)'.dmmGFO$ *r   c                      | j                   d   S Nr4   rj   rk   s    r   current_contextzKubeconfig.current_context   s    ::'((r   c                     | j                   S N)ri   rr   s    r   rm   zKubeconfig.filename  s    >>r   c                    | j                   j                  |d        | j                  j                  |d        | j                  j                  |d        | j                  j                  d      |k(  rd| j                  d<   y y )Nr4   r!   )r)   popr3   r.   rj   get)rk   keys     r   ClearzKubeconfig.Clear  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      5 }t        j                  | j                  |       ddd       y# 1 sw Y   yxY w)zjSave kubeconfig to file.

    Raises:
      Error: don't have the permission to open kubeconfig file.
    r3   r.   r)   T)privateN)listr3   valuesrj   r.   r)   
file_utils
FileWriterri   r	   rF   )rk   fps     r   rI   zKubeconfig.SaveToFile  s     "$--"6"6"89DJJztzz0023DJJw!$--"6"6"89DJJz			t~~t	<
ii

B 
=	<	<s   2!CC%c                 "    || j                   d<   y rp   rq   )rk   rM   s     r   rE   zKubeconfig.SetCurrentContext  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)r3   r.   r)   zinvalid type for {0}: {1}zexpected key {0} not foundN)r   
isinstancer}   r   typeKeyError)clsdatary   r<   s       r   	_ValidatezKubeconfig._Validate  s     ,>2#$s)T*1883id3i* + + 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   r   inner_errorr   )r   rm   r   r<   s       r   LoadFromFilezKubeconfig.LoadFromFile(  sl    (^^H%d MM$tX	 :: (:AA
E%%' ( ((s   1 A.%A))A.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   debugr   r   MakeDirospathdirnamer8   rI   )r   rm   r<   rO   s       r   LoadOrCreatezKubeconfig.LoadOrCreate2  s    h''7 	iiHOO
 23((3js    B&A9B!B&!B&c                 H    | j                  t        j                               S ru   )r   r6   DefaultPath)r   s    r   r7   z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
   GetEncodedValuer   environsplitpathsepr   abspathr   OperatingSystem	IsWindowsjoinr   r   )rO   home_dir
home_drive	home_paths       r   r   zKubeconfig.DefaultPathC  s@    ))"**lCJ##BJJ/2jWW__Z(( ''

F;H	11;;=++BJJDj**2::zBi		77<<
I6++BJJF$$*F?Hyy{@+; %+ %89 9 17 %+ %89 9
 77<<'844r   c                 T   | 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)zMerge another kubeconfig into self.

    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
    N)rE   rs   dictr}   r3   itemsr.   r)   )rk   rO   s     r   MergezKubeconfig.Merge^  s     	4//M:3M3MNZ  &&()D1D1D1F,GGIDMd:++1134tDJJ<L<L<N7OOPDJZ  &&()D1D1D1F,GGIDMr   N)r   r   r   r   rn   propertyrs   rm   rz   rI   rE   classmethodr   r   r   r7   staticmethodr   r   r   r   r   r6   r6      s    9/ ) )  )
 , 
> 
>   
 
 6 6 5 54Ir   r6   c                 \    d|i}|r|rt        d      |r||d<   n|r||d<   nd|d<   | |dS )z0Generate and return a cluster kubeconfig object.serverz'cannot specify both ca_path and ca_datazcertificate-authorityzcertificate-authority-dataTzinsecure-skip-tls-verify)rh   rL   )r   )rh   r   ca_pathr1   rL   s        r   rC   rC   o  sU     ' 
9
::'.G#$,3G()*.G&'7	++r   c                    |s|r|s|r|	st        d      i }t               rt        |
      |d<   n|r|s|s|s|rt        |||||      |d<   |r|rt        d      |r||d<   n|r||d<   |r|	rt        d      |r||d	<   n|	r|	|d
<   | |dS )aH  Generates and returns a user kubeconfig object.

  Args:
    name: str, nickname for this user entry.
    auth_provider: str, authentication provider.
    auth_provider_cmd_path: str, authentication provider command path.
    auth_provider_cmd_args: str, authentication provider command args.
    auth_provider_expiry_key: str, authentication provider expiry key.
    auth_provider_token_key: str, authentication provider token key.
    cert_path: str, path to client certificate file.
    cert_data: str, base64 encoded client certificate data.
    key_path: str, path to client key file.
    key_data: str, base64 encoded client key data.
    exec_auth_args: list, exec auth provider command arguments.

  Returns:
    dict, valid kubeconfig user entry.

  Raises:
    Error: if no auth info is provided (auth_provider or cert AND key)
  z3either auth_provider or cert & key must be providedr-   )rh   r\   r]   
expiry_key	token_keyzauth-providerz+cannot specify both cert_path and cert_datazclient-certificatezclient-certificate-dataz)cannot specify both key_path and key_dataz
client-keyzclient-key-data)rh   r,   )r   _UseExecAuth_ExecAuthPlugin_AuthProvider)rh   rV   rW   rX   rY   rZ   	cert_pathr+   key_pathr*   r[   r,   s               r   r?   r?     s    B I(
E
FF	$^">2DL 	!#" ,))-+d? 9
=
>>!*D	&/D	"#(
;
<<!D&D		%%r   zPath to sdk installation not found. Please check your installation or use the `--auth-provider-cmd-path` flag to provide the path to gcloud manually.zInstall gke-gcloud-auth-plugin for use with kubectl by following https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke z{ACTION REQUIRED: gke-gcloud-auth-plugin, which is needed for continued use of kubectl, was not found or is not executable. c                 2    t               }|| dt        dd}|S )a  Generate and return an exec auth plugin config.

  Args:
    exec_auth_args: list, exec auth provider command arguments.

  Constructs an exec auth plugin config entry readable by kubectl.
  This tells kubectl to call out to gke-gcloud-auth-plugin and
  parse the output to retrieve access tokens to authenticate to
  the kubernetes master.

  Kubernetes GKE Auth Provider plugin is defined at
  https://kubernetes.io/docs/reference/access-authn-authz/authentication/#client-go-credential-plugins

  GKE GCloud Exec Auth Plugin code is at
  https://github.com/kubernetes/cloud-provider-gcp/tree/master/cmd/gke-gcloud-auth-plugin

  Returns:
    dict, valid exec auth plugin config entry.
  z$client.authentication.k8s.io/v1beta1T)commandargs
apiVersioninstallHintprovideClusterInfo))_GetGkeGcloudPluginCommandAndPrintWarningGKE_GCLOUD_AUTH_INSTALL_HINT)r[   r   exec_cfgs      r   r   r     s+    ( 67' :1 ( 
/r   c                 .   d| i}| dk(  rd}t         j                  j                         rd}|Ot        j                         j
                  }|t        t              t        j                  j                  ||      }||r|nd|r|nd|r|ndd}||d	<   |S )
a  Generates and returns 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
    cmd_path: str, authentication provider command path.
    cmd_args: str, authentication provider command arguments.
    expiry_key: str, authentication provider expiry key.
    token_key: str, authentication provider token key.

  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.
  rh   rU   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   r   r   r   Pathssdk_bin_pathr   SDK_BIN_PATH_NOT_FOUNDr   r   r   )	rh   r\   r]   r   r   providerbin_namer   cfgs	            r   r   r     s    : d^(	U]H  **,h\\^00l		*++lH5h
  !H&J #I(D %J*FC$ HX	/r   c                     d} t        j                  t        j                  |       }|Z|j	                         dk(  ry|j	                         dk7  r3t        j                  dj                  | |j	                                      y)z4Returns a bool noting if ExecAuth should be enabled.USE_GKE_GCLOUD_AUTH_PLUGINfalseFtruez.Ignoring unsupported env value found for {}={}T)r
   r   r   r   lowerr   rB   r   )env_flaguse_gke_gcloud_auth_plugins     r   r   r   9  sy    )('77

HM  +!'')W4	#	)	)	+v	5	kk
:
A
A288: 
r   c                  t   d} t         j                  j                         rd} | }	 t        j                  |dgddt        j
                  t        j
                         t        |       |S # t        $ r 	 t        j                         j                  }|t        j                  t               nZt        j                  j!                  ||      }t        j                  |dgddt        j
                  t        j
                         |}Y |S # t        $ r t        j                  t               Y Y |S w xY ww xY w)zGets Gke Gcloud Plugin Command to be used.

  Returns Gke Gcloud Plugin Command to be used. Also,
  prints warning if plugin is not present or doesn't work correctly.

  Returns:
    string, Gke Gcloud Plugin Command to be used.
  zgke-gcloud-auth-pluginzgke-gcloud-auth-plugin.exez	--version   F)timeoutcheckstdoutrH   )r   r   r   
subprocessrunDEVNULL_ValidateGkeGcloudPluginVersion	Exceptionr   r   r   r   critical GKE_GCLOUD_AUTH_PLUGIN_NOT_FOUNDr   r   r   )r   r   r   sdk_path_bin_names       r   r   r   L  s    &(((*+H'5NNG[)$,,$,,	.
 $G,, 
.+ 
 55 \\^00l		56GGLLw?);7 "(00(00		2
 $ 
.  5	ll34	.5%5s+   AA+ +	D75BD"D3.D72D33D7zkACTION REQUIRED: gke-gcloud-auth-plugin, which is needed for continued use of kubectl needs to be updated. c                     t        j                  | dgdddd      }d|j                  vr)d|j                  vrt	        j
                  t               yyy)zValidate Gke Gcloud Plugin Command to be used.

  GDCE will depend on the newest available version, so warn customers if they
  have an older version installed.

  Args:
    command: Gke Gcloud Plugin Command to be used.
  z--helpr   FT)r   r   capture_outputtextz--project stringN)r   r   rH   r   r   r   %GKE_GCLOUD_AUTH_PLUGIN_NOT_UP_TO_DATE)r   results     r   r   r     sW     >>& --LL67 . .r   c                     | ||ddS )z0Generate and return a context kubeconfig object.)rL   r,   )rh   rM   r   )rh   rL   r,   s      r   r9   r9     s     
 r   c                      dg g ddi g dS )Nv1r!   Config)r   r)   r3   r4   kindpreferencesr.   r   r   r   r   r8   r8     s!    
 r   )NN)
NNNNNNNNNN)rU   NNNN)-r   
__future__r   r   r   ra   r   r   rG   googlecloudsdk.corer   r   core_exceptionsr   r	   googlecloudsdk.core.utilr
   r   r   r   COMMAND_DESCRIPTIONCOMMAND_EXAMPLEr   r   r   r%   r'   rS   r_   r=   objectr6   rC   r?   r   r   r   r   r   r   r   r   r   r9   r8   r   r   r   <module>r      s3   3 &  '  	  
 & = # $ - 8 .  GO!! GM MG 0=@,*^?I ID,"  $ $"&!%G&V # ; ! !B ! 	<~&,^+-IJ &
80	r   