
    0                     :   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dlmZ ddlmZ dZdZdZdZdZdZdZ dZ!dZ"dZ#dZ$dZ%dZ&dZ'dZ(dZ)dZ*dZ+d Z, ejZ                  d!g d"      Z.d# Z/d$ Z0d% Z1d& Z2d' Z3d( Z4d) Z5d* Z6d+ Z7d, Z8d- Z9d. Z:d/ Z;d0 Z<d1 Z=d2 Z>d3 Z?d4 Z@d5 ZA G d6 d7eB      ZCd8 ZD G d9 d:ej                        ZF G d; d<ej                        ZG G d= d>ej                        ZHy)?z6Utils for mesh flag in the instance template commands.    )absolute_import)division)unicode_literalsN)util)service_proxy_aux_data)api_util)	kube_util)
exceptions)execution_utils)yaml)fileszistio-eastwestgatewayzYgs://gce-service-proxy/service-proxy-agent/releases/service-proxy-agent-asm-{}-stable.tgzzKgs://gce-service-proxy/service-proxy-agent-installer/releases/installer.tgzzgce-service-proxy-asm-version"gce-service-proxy-installer-bucketzgce-service-proxy-agent-bucketzservice.istio.io/canonical-namez#service.istio.io/canonical-revisionzapp.kubernetes.io/namezapp.kubernetes.io/versionISTIO_META_CLOUDRUN_ADDRCLOUDRUN_ADDR15012z
(.*)\/(.*)z#\/\/gkehub(.*).googleapis.com\/(.*)z:(.*)-zistio-sidecar-injectoristiodzmeshconfig.googleapis.com:443ServiceProxyMetadataArgs)asm_version
project_idexpansionagateway_ipservice_proxy_api_serveridentity_providerservice_accountasm_proxy_configmcp_env_configtrust_domainmesh_idnetwork
asm_labelsworkload_nameworkload_namespacecanonical_servicecanonical_revisionasm_revision	root_certc                     t        j                  t        |       }|r"|j                  d      |j                  d      fS t	        j
                  dj                  |             )zParses the workload value to workload namespace and name.

  Args:
    workload: The workload value with namespace/name format.

  Returns:
    workload namespace and workload name.

  Raises:
    Error: if the workload value is invalid.
        zSvalue workload: {} is invalid. Workload value should have the formatnamespace/name.)research_WORKLOAD_PATTERNgroupr
   Errorformat)workloadworkload_matchs     Flib/googlecloudsdk/command_lib/compute/instance_templates/mesh_util.pyParseWorkloadr2   M   s[     99.9."N$8$8$;;;x(	* *    c                     t        j                  t        |       }|r|j                  d      S t	        j
                  dj                  |             )ap  Get membership name from an owner id value.

  Args:
    owner_id: The owner ID value of a membership. e.g.,
    //gkehub.googleapis.com/projects/123/locations/global/memberships/test.

  Returns:
    The full resource name of the membership, e.g.,
      projects/foo/locations/global/memberships/name.

  Raises:
    Error: if the membership name cannot be parsed.
  r(   zvalue owner_id: {} is invalid.)r)   r*   _GKEHUB_PATTERNr,   r
   r-   r.   )owner_idmembership_matchs     r1   _ParseMembershipNamer8   a   sJ     YY9!!!$$&--h7	9 9r3   c                    | st        d      	 t        j                  |       }t        |ddd      }|st        d      t        |      }t        j                  |      }|j                  s$t	        j                  dj                  |            d	j                  |j                  |      S # t        j                  $ r*}t	        j                  dj                  |       |      d}~ww xY w)
aR  Get the identity provider for the VMs.

  Args:
    membership_manifest: The membership manifest from the cluster.
    workload_namespace: The namespace of the VM workload.

  Returns:
    The identity provider value to be used on the VM connected to the cluster.

  Raises:
    ClusterError: If the membership manifest cannot be read.
  z2Cannot verify an empty membership from the clusterz&Invalid membership from the cluster {}NspecowneridznInvalid membership does not have an owner id. Please make sure your cluster is correctly registered and retry.zwInvalid membership {} does not have a unique_Id field. Please make sure your cluster is correctly registered and retry.z{}@google@{})ClusterErrorr   loadr-   r
   r.   _GetNestedKeyFromManifestr8   r   GetMembershipuniqueId)membership_manifestr!   membership_dataer6   membership_name
memberships          r1   _GetVMIdentityProviderrG   v   s     

K
LLQii 34O
 'vw.(	
   ! ! )2/%%o6*			


 3396/3JL L 
		z224F	GG% 
 Q


0778KLaQ QQs   B+ +C(>%C##C(c                 n    	 |d   }|S # t         t        f$ r | ri cY S t        j                  d      w xY w)zRetrieve proxy config from a mesh config.

  Args:
    is_mcp: Whether the control plane is managed or not.
    mesh_config: A mesh config from the cluster.

  Returns:
    proxy_config: The proxy config from the mesh config.
  defaultConfigz8Proxy config cannot be found in the Anthos Service Mesh.KeyError	TypeErrorr
   r-   )is_mcpmesh_configproxy_configs      r1   _RetrieveProxyConfigrP      sR    D/L 
 I	 Di


BD DDs   	 44c                 j    	 |d   }|S # t         t        f$ r | rY yt        j                  d      w xY w)zRetrieve trust domain from a mesh config.

  Args:
    is_mcp: Whether the control plane is managed or not.
    mesh_config: A mesh config from the cluster.

  Returns:
    trust_domain: The trust domain from the mesh config.
  trustDomainNz8Trust Domain cannot be found in the Anthos Service Mesh.rJ   )rM   rN   r   s      r1   _RetrieveTrustDomainrS      sP    D}-L 
 I	 D


BD DDs   	 22c                     t        | |      }	 |d   }|S # t        t        f$ r | rY yt        j                  d      w xY w)zRetrieve mesh id from a mesh config.

  Args:
    is_mcp: Whether the control plane is managed or not.
    mesh_config: A mesh config from the cluster.

  Returns:
    mesh_id: The mesh id from the mesh config.
  meshIdNz3Mesh ID cannot be found in the Anthos Service Mesh.)rP   rK   rL   r
   r-   )rM   rN   rO   r   s       r1   _RetrieveMeshIdrV      sX     &fk:,?8$G 
. I	 ?


=? ??s    >>c                 P    t        d|       }|i }|j                  dt              S )zGet the discovery address used in the MCP installation.

  Args:
    mesh_config: A mesh config from the cluster.

  Returns:
    The discovery address.
  T)rM   rN   discoveryAddress)rP   get_MCP_ADDRESS)rN   rO   s     r1   _RetrieveDiscoveryAddressr[      s1     &T{K,L
 
		,l	;;r3   c                 ,    | j                  |      }|ryy)zCheck if ASM control plane is managed.

  Args:
    kube_client: A kubernetes client for the cluster.
    revision: The ASM revision to check for control plane type.

  Returns:
    True if the control plane is MCP, otherwise False.
  TF)RetrieveMutatingWebhookURL)kube_clientrevisionurls      r1   _IsMCPra      s     	..x8#	r3   c                     | st        d      	 t        j                  |       }t        |ddd      }|S # t        j                  $ r*}t	        j                  dj                        |      d}~ww xY w)zGet the workload labels from a workload manifest.

  Args:
    workload_manifest: The manifest of the workload.

  Returns:
    The workload labels.

  Raises:
    WorkloadError: If the workload manifest cannot be read.
  0Cannot verify an empty workload from the cluster$Invalid workload from the cluster {}Nr:   metadatalabelsWorkloadErrorr   r>   r-   r
   r.   r?   )workload_manifestworkload_datarD   workload_labelss       r1   _GetWorkloadLabelsrl     s     

J
KKIII/0M
 .mVZ.68/ 
 
 I


.55mDaI II   4 A1%A,,A1c                 0    t        |      }t        ||       S )zGet the canonical service name of the workload.

  Args:
    workload_name: The name of the workload.
    workload_manifest: The manifest of the workload.

  Returns:
    The canonical service name of the workload.
  )rl   _ExtractCanonicalServiceName)r    ri   rk   s      r1   _GetCanonicalServiceNamerp   "  s     ''89/	%o}	EEr3   c                 .    t        |       }t        |      S )zGet the canonical service revision of the workload.

  Args:
    workload_manifest: The manifest of the workload.

  Returns:
    The canonical service revision of the workload.
  )rl    _ExtractCanonicalServiceRevision)ri   rk   s     r1   _GetCanonicalServiceRevisionrs   1  s     ''89/	)/	::r3   c                     | s|S | j                  t              }|r|S | j                  t              }|r|S | j                  d      }|r|S |S )zGet the canonical service name of the workload.

  Args:
    workload_labels: A map of workload labels.
    workload_name: The name of the workload.

  Returns:
    The canonical service name of the workload.
  app)rY   #_ISTIO_CANONICAL_SERVICE_NAME_LABEL_KUBERNETES_APP_NAME_LABEL)rk   r    svcs      r1   ro   ro   ?  s]     
?@#J67#JE"#J	r3   c                     | sy| j                  t              }|r|S | j                  t              }|r|S | j                  d      }|r|S y)zGet the canonical service revision of the workload.

  Args:
    workload_labels: A map of workload labels.

  Returns:
    The canonical service revision of the workload.
  latestversion)rY   '_ISTIO_CANONICAL_SERVICE_REVISION_LABEL_KUBERNETES_APP_VERSION_LABEL)rk   revs     r1   rr   rr   [  sW     
CD#J9:#JI&#J	r3   c                    | st        d      	 t        j                  |       }t        |dddd      }|dk7  rt        d	      y# t        j                  $ r*}t	        j                  dj                  |       |      d}~ww xY w)
z(Verify VM workload setup in the cluster.rc   rd   Nr:   re   annotationsz*security.cloud.google.com/IdentityProvidergooglezUnable to find the GCE IdentityProvider in the specified WorkloadGroup. Please make sure the GCE IdentityProvider is specified in the WorkloadGroup.rg   )ri   rj   rD   identity_provider_values       r1   VerifyWorkloadSetupr   v  s    	
J
KKMII/0M
 6VZ24 (
 ) * * ) 
 M


.556GH!M MMs   A B%A<<Bc                    | st        d      	 t        j                  |       }t        |ddd      }|st        d      |S # t        j                  $ r*}t	        j                  dj                  |       |      d}~ww xY w)z;Retrieve the Anthos Service Mesh revision for the workload.z1Cannot verify an empty namespace from the clusterz%Invalid namespace from the cluster {}Nre   rf   zistio.io/revzWorkload namespace does not have an Anthos Service Mesh revision label. Please make sure the namespace is labeled and try again.rg   )namespace_manifestnamespace_datarD   workload_revisions       r1   RetrieveWorkloadRevisionr     s    	
K
LLOYY12N
 0
08.J	
 4 5 5 
 
 O


/667IJAO OOs   A A>%A99A>c                     | st        d      	 t        j                  |       }t        |ddd      }|S # t        j                  $ r*}t	        j                  dj                  |       |      d}~ww xY w)z3Retrieve the service account used for the workload.rc   rd   Nr:   templateserviceAccountrg   )ri   rj   rD   r   s       r1   _RetrieveWorkloadServiceAccountr     s    	
J
KKMII/0M
 .mVZ.>@/	 
 M


.556GH!M MMrm   c                 D   |r#d}d}d}t        |
      }|j                  |	      }not        | j                  v r| j                  t           }n|j	                  |	      }|j                         }|j                         }dj                  |t              }d}t        ||      }t        |      }t        ||
      }t        ||
      }t        ||
      }|j                  d      d   }t        |      }t!        ||      }t#        |      }t%        |||||||||||||||||	|      S )z?Retrieve the necessary metadata to configure the service proxy.Nz{}:{}/)r[   RetrieveEnvConfig'_GCE_SERVICE_PROXY_ASM_VERSION_METADATAre   RetrieveASMVersionRetrieveExpansionGatewayIPRetrieveKubernetesRootCertr.   _ISTIO_DISCOVERY_PORTrG   r   rP   rS   rV   splitrl   rp   rs   r   )argsrM   r^   r   network_resourcer!   r    ri   rB   r$   rN   r   r   r%   r   
env_configr   r   r   r   r   r   r   r"   r#   s                            r1   _RetrieveServiceProxyMetadatar     sN    KI8E..|<J.$--?MM"IJk22<@k&AAC668I&~~.B.C EJ,-@-?A 44EF/)&+>%fk:,FK0'""3'+'!"34*.}>OP34EF	!:35M*:JGWj-+-?
 r3   c                 	   |j                   r|j                   }nt        j                         }|j                  |t        <   |j
                  |t        <   t        j                  |d      }t        j                         }d|d<   |j                  |j                  dd|d<   i |d<   |j                  }|st        j                         }d	|vrt        j                         |d	<   nt        j                  |d	         |d	<   |d	   }|j                  |d
<   |j                  |d<   d|d<   d|d<   |j                  |d<   |j                  |d<   |j                  |d<   |j                   r|j                   |d<   |j"                  r|j"                  |d<   dj%                  |j&                  |j                        |d<   |j                  |d<   |j
                  |d<   ||d<   |j(                  dk(  rd|d<   n|j(                  |d<   t        j                         }t        j                         }	d|	d<   d|	d<   |rmd d!t*        j,                  iig|	d"<   |j/                  |j0                         t2        |v r|t2           |t4        <   d#| j6                  vrt8        | j6                  d#<   nd d!t*        j:                  j%                  |j<                  |j(                  $      iig|	d"<   |j>                  |d%<   |j@                  | j6                  d&<   tB        | j6                  vr0tD        j%                  |j>                        | j6                  tB        <   |	g|d'<   ||d(<   d| j6                  d)<   d| j6                  d*<   d+| j6                  d,<   t        j                  |      | j6                  d-<   t        j                  |d      | j6                  d.<   | jF                  t        j                         | _#        |j                  | jF                  d0<   |j                  | jF                  d1<   |j"                  r|j"                  | jF                  d2<   n=tI        jJ                  |j&                        }
d3j%                  |
      | jF                  d2<   d4| jF                  d.<   y/)5zCModify the instance template to include the service proxy metadata.T)	sort_keysONmodeinfo)r   z
api-serverz	log-levelz
proxy-specserviceproxyMetadataISTIO_META_WORKLOAD_NAMEPOD_NAMESPACEtrueUSE_TOKEN_FOR_CSRISTIO_META_DNS_CAPTUREISTIO_META_AUTO_REGISTER_GROUPSERVICE_ACCOUNTCREDENTIAL_IDENTITY_PROVIDERTRUST_DOMAINISTIO_META_MESH_ID{}-{}ISTIO_META_NETWORKCANONICAL_SERVICECANONICAL_REVISIONISTIO_METAJSON_LABELSdefault ASM_REVISIONzinstall-gce-service-proxy-agentname	INSTALLEDdesired_state	scriptRunscriptinstallStepsr   )
ingress_ipr$   ISTIO_META_ISTIO_VERSIONrootcertsoftwareRecipesz
asm-configzenable-osconfigzenable-guest-attributestaskszosconfig-disabled-featureszgce-software-declarationzgce-service-proxyNasm_service_nameasm_service_namespacer   zproj-{}z
asm-istiod)&r   collectionsOrderedDictr"   rv   r#   r|   jsondumpsr   r   r   r    r!   r   r   r   r   r.   r   r$   r   .startup_script_for_asm_service_proxy_installerupdater   _CLOUDRUN_ADDR_KEY_ISTIO_META_CLOUDRUN_ADDR_KEYre   $_SERVICE_PROXY_INSTALLER_BUCKET_NAME$startup_script_for_asm_service_proxyr   r   r%   (_GCE_SERVICE_PROXY_AGENT_BUCKET_METADATA_SERVICE_PROXY_BUCKET_NAMErf   project_utilGetProjectNumber)r   rM   metadata_argsr   asm_labels_stringservice_proxy_configrO   proxy_metadatagce_software_declarationservice_proxy_agent_recipeproject_numbers              r1   _ModifyInstanceTemplater     s    ))J((*J .;-L-L )+ 2?1Q1Q -/ jjt<$002!%v &&!::(|$ %'y!//,	**,LL($/$;$;$=L!$/$;$;_%%'L!  0./</J/J.+,$1$D$D.!(..$%-3.)*5B5P5P.12&3&C&C."#(5(G(G $&%2%?%?N>"+8+@+@N'()0 5 5*7.%&(5(G(G.$%)6)I)I.%&,=.()9,%'N>"%2%?%?N>"(446*668'HV$0;_-&??
3 2~. -667^+6D
7n23+4==@
. mm89 	&KK,AA!.!;!;  =
3 2~. 2?1J1JN-. - 7 7DMM*/t}}D )//0I0IJ mm
24 2L0L,-'3|$%+$--!"-3$--)*07$--,-.2jj/ $--*+'+zzd(,$--#$ 
[[))+DK$1$C$C$++ !)6)I)I$++%&*22DKK	 "22=3K3KLN&--n=DKK	%1$++!"r3   c
                 `    t        ||      }
t        | |
|||||||||	      }t        | |
|       y)z@Configure the provided instance template args with ASM metadata.N)ra   r   r   )r   r^   r   r   r!   r    ri   rB   r$   rN   rM   service_proxy_metadata_argss               r1   ConfigureInstanceTemplater   `  sF    
 +|,& =
FK-=-):<OK!!
 $(CDr3   c                       e Zd ZdZddZd Zd Zd Zd Zd Z	d	 Z
d
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd ZddZy)KubernetesClientz-Kubernetes client for access Kubernetes APIs.Nc           
          d| _         t        j                         | _        t	        j
                  dd|ddddd      | _        | j                  j                  | j                        \  | _        | _	        y)zfKubernetesClient constructor.

    Args:
      gke_cluster: the location/name of the GKE cluster.
    20sNF)api_adaptergke_urigke_cluster
kubeconfiginternal_ipcross_connect_subnetworkprivate_endpoint_fqdncontext)
kubectl_timeoutr   TemporaryDirectorytemp_kubeconfig_dirhub_kube_utilKubeconfigProcessor	processorGetKubeconfigAndContextr   r   )selfr   s     r1   __init__zKubernetesClient.__init__r  sj     !D$779D"66$KUT"D2DN %)NN$J$J  %"!DOT\r3   c                     | S N )r   s    r1   	__enter__zKubernetesClient.__enter__  s    Kr3   c                 R    | j                   | j                   j                          y y r   )r   Close)r   _s     r1   __exit__zKubernetesClient.__exit__  s%    +
$$& ,r3   c           	          |D ]l  }| j                  ddddd|gd      \  }}|r%t        j                  dj                  ||            d|vsJt        j                  d	j                  |             y
)a`  Check to see if the user has read permissions in the namespaces.

    Args:
      *namespaces: The namespaces to verify reader permissions.

    Returns:
      true, if reads can be performed on all of the specified namespaces.

    Raises:
      Error: if failing to get check for read permissions.
      Error: if read permissions are not found.
    authzcan-irY   *-nNzBFailed to check if the user can read resources in {} namespace: {}yesz5Missing permissions to read resources in {} namespaceT_RunKubectlr
   r-   r.   )r   
namespacesnsouterrs        r1   HasNamespaceReaderPermissionsz.KubernetesClient.HasNamespaceReaderPermissions  s     !!7E3b
149hc3	PVB_ 	 
c	CJJ2NP 	P  r3   c                     |D ]j  }| j                  dd|gd      \  }}|sd|v r%t        j                  dj                  ||            t        j                  dj                  ||             y)a  Check to see if the namespaces exist in the cluster.

    Args:
      *namespaces: The namespaces to check.

    Returns:
      true, if namespaces exist.

    Raises:
      Error: if failing to verify the namespaces.
      Error: if at least one of the namespaces do not exist.
    rY   	namespaceNNotFoundzNamespace {} does not exist: {}z*Failed to check if namespace {} exists: {}Tr   )r   r   r   r   r  s        r1   NamespacesExistz KubernetesClient.NamespacesExist  s     R 8$?fa	  !B!I!I#"  8??CHJ 	J  r3   c                     | j                  dd|ddgd      \  }}|r%t        j                  dj                  ||            |S )z/Get the YAML output of the specified namespace.rY   r  -or   Nz!Error retrieving Namespace {}: {}r   )r   r  r   r  s       r1   GetNamespacezKubernetesClient.GetNamespace  sV    {ItV!56:<HC

-
4
4Y
DF FJr3   c                     | j                         st        d      | j                  g dd      \  }}|r3d|v rt        d      t        j                  dj                  |            |S )z)Get the YAML output of the Membership CR.zbMembership CRD is not found in the cluster. Please make sure your cluster is registered and retry.)rY   memberships.hub.gke.iorF   r  r   Nr  zjThe specified cluster is not registered to a fleet. Please make sure your cluster is registered and retry.z&Error retrieving the Membership CR: {})_MembershipCRDExistsr=   r   r
   r-   r.   r   r   r  s      r1   GetMembershipCRz KubernetesClient.GetMembershipCR  s    $$&-. . 	%&*,HC 	s	EF 	F 
2
9
9#
>@ @Jr3   c                     | j                  g dd      \  }}|r)d|v ryt        j                  dj                  |            y)z*Verifies if GKE Hub membership CRD exists.)rY   1customresourcedefinitions.v1.apiextensions.k8s.ior  Nr  Fz'Error retrieving the Membership CRD: {}Tr   r   r   r  s      r1   r  z%KubernetesClient._MembershipCRDExists  sT    	#$(*FAs 	s	
3
:
:3
?A Ar3   c                     | j                         st        d      | j                  g dd      \  }}|r3d|v rt        d      t        j                  dj                  |            |S )z/Get the YAML output of the IdentityProvider CR.zoIdentityProvider CRD is not found in the cluster. Please install Anthos Service Mesh with VM support and retry.)rY   +identityproviders.security.cloud.google.comr   r  r   Nr  zfGCE identity provider is not found in the cluster. Please install Anthos Service Mesh with VM support.zAError retrieving IdentityProvider google in default namespace: {})_IdentityProviderCRDExistsr=   r   r
   r-   r.   r  s      r1   GetIdentityProviderCRz&KubernetesClient.GetIdentityProviderCR  s    **,;< < 	!"&(HC 	s	BC 	C 
M6#;  Jr3   c                     | j                  g dd      \  }}|r)d|v ryt        j                  dj                  |            y)z)Verifies if Identity Provider CRD exists.)rY   r  r  Nr  Fz.Error retrieving the Identity Provider CRD: {}Tr   r  s      r1   r  z+KubernetesClient._IdentityProviderCRDExists  sT    	89=?FAs 	s	
:
A
A#
FH Hr3   c           	         | j                         st        d      | j                  dd|d|ddgd      \  }}|rEd|v rt        d	j	                  ||            t        j                  d
j	                  |||            |S )z6Get the YAML output of the specified WorkloadGroup CR.z\WorkloadGroup CRD is not found in the cluster. Please install Anthos Service Mesh and retry.rY   "workloadgroups.networking.istio.ior   r  r   Nr  zhWorkloadGroup {} in namespace {} is not found in the cluster. Please create the WorkloadGroup and retry.z5Error retrieving WorkloadGroup {} in namespace {}: {})_WorkloadGroupCRDExistsr=   r   rh   r.   r
   r-   )r   r!   r    r   r  s        r1   GetWorkloadGroupCRz#KubernetesClient.GetWorkloadGroupCR  s    '')+, , 3]DD&! HC 	s	BBH&1C34 	4 
A
H
H/67 7 Jr3   c                     | j                  g dd      \  }}|r)d|v ryt        j                  dj                  |            y)z%Verifies if WorkloadGroup CRD exists.)rY   r  r  Nr  Fz*Error retrieving the WorkloadGroup CRD: {}Tr   r  s      r1   r  z(KubernetesClient._WorkloadGroupCRDExists  sT    	/046FAs 	s	
6
=
=c
BD Dr3   c                     | j                  ddt        ddgd      \  }}|r)d|v ryt        j                  dj	                  |            y	)
z8Verifies if the ASM Expansion Gateway deployment exists.rY   deployr   istio-systemNr  Fz5Error retrieving the expansion gateway deployment: {}Tr   _EXPANSION_GATEWAY_NAMEr
   r-   r.   r  s      r1    ExpansionGatewayDeploymentExistsz1KubernetesClient.ExpansionGatewayDeploymentExists)  s\    	14H$PFAs
	s	
A
H
H
MO Or3   c                     | j                  ddt        ddgd      \  }}|r)d|v ryt        j                  dj	                  |            y	)
z5Verifies if the ASM Expansion Gateway service exists.rY   r   r   r  Nr  Fz2Error retrieving the expansion gateway service: {}Tr  r  s      r1   ExpansionGatewayServiceExistsz.KubernetesClient.ExpansionGatewayServiceExists4  s\    		2D.I4QFAs
	s	
>
E
Ec
JL Lr3   c           	      J   | j                         st        dj                  t                    | j	                         st        dj                  t                    | j                  ddt        ddddgd	      \  }}|r$t        j                  d
j                  |            |S )z4Retrieves the expansion gateway IP from the cluster.ztThe gateway {} deployment is not found in the cluster. Please install Anthos Service Mesh with VM support and retry.zqThe gateway {} service is not found in the cluster. Please install Anthos Service Mesh with VM support and retry.rY   rx   r   r  r  z-jsonpath={.status.loadBalancer.ingress[0].ip}Nz)Error retrieving expansion gateway IP: {})r!  r=   r.   r   r#  r   r
   r-   r  s      r1   r   z+KubernetesClient.RetrieveExpansionGatewayIP?  s    002CCI6%D'( (
 --/CCI6%D'( (
 u-t^T7! HC 
5
<
<S
AC CJr3   c                     | j                  g dd      \  }}|r3d|v rt        d      t        j                  dj	                  |            |j                  d      S )z)Retrieves the root cert from the cluster.)rY   	configmapzkube-root-ca.crtr  zjsonpath="{.data.ca\.crt}"Nr  z&Cluster root certificate is not found.z)Error retrieving Kubernetes root cert: {}")r   r=   r
   r-   r.   stripr  s      r1   r   z+KubernetesClient.RetrieveKubernetesRootCertV  sl    	()-/HC 	s	46 	6
5
<
<S
AC C99T?r3   c           
         | j                  ddddj                  |      ddddgd	      \  }}|rBd
|v rt        dj                  |            t        j                  dj                  |            |st        dj                  |            t        j                  t        |      }|r|j                  d      S t        j                  dj                  |            )zRetrieves the version of ASM.rY   r  z-lzistio.io/rev={},app=istiodr   r  r  z=jsonpath="{.items[0].spec.template.spec.containers[0].image}"Nr  nAnthos Service Mesh revision {} is not found in the cluster. Please install Anthos Service Mesh and try again.z7Error retrieving the version of Anthos Service Mesh: {}zgAnthos Service Mesh revision {} does not have an image property. Please re-install Anthos Service Mesh.r'   zValue image: {} is invalid.)	r   r.   r=   r
   r-   r)   r*   _ASM_VERSION_PATTERNr,   )r   r_   imager  version_matchs        r1   r   z#KubernetesClient.RetrieveASMVersionc  s    !!x;BB8LndG# 	JE3
 	s	)+ 	+ 
C
J
J3
OQ Q  !!'!13 3 II2E:M  ##


%,,U35 5r3   c           	         |dk(  rd}ndj                  |      }| j                  dd|dddd	gd
      \  }}|rCd|v rt        dj                  |            t        j                  dj                  ||            	 t        j                  |      }|S # t
        j                  $ r% t        j                  dj                  |            w xY w)z'Retrieves the env-* config map for MCP.r   envzenv-{}rY   r&  r   r  r  zjsonpath={.data}Nr  zrManaged Control Plane revision {} is not found in the cluster. Please install Managed Control Plane and try again.z7Error retrieving the config map {} from the cluster: {}z'Invalid config map from the cluster: {}r.   r   r=   r
   r-   r   r>   )r   r_   env_config_namer   r  r   s         r1   r   z"KubernetesClient.RetrieveEnvConfig~  s    9o 1o	_dN	!	#$(*HC 	s	)+ 	+ 
C
J
Js$% %A99S>j
 	 :: A
3
:
:3
?A AAs   <B 8Cc           	         |dk(  rd}ndj                  |      }| j                  dd|dddd	gd
      \  }}|rBd|v rt        dj                  |            t        j                  dj                  |            	 t        j                  |      }|S # t
        j                  $ r% t        j                  dj                  |            w xY w)z.Retrieves the MeshConfig for the ASM revision.r   istiozistio-{}rY   r&  r   r  r  zjsonpath={.data.mesh}Nr  r*  z5Error retrieving the mesh config from the cluster: {}z(Invalid mesh config from the cluster: {}r0  )r   r_   mesh_config_namer   r  rN   s         r1   RetrieveMeshConfigz#KubernetesClient.RetrieveMeshConfig  s    9 #**84	-t^	&	()-/HC 	s	)+ 	+ 
A
H
H BIIcNk
 	 :: B
4
;
;C
@B BBs   ;B 8C
c                 z   |dk(  rt         }ndj                  t         |      }dj                  t        |      }| j                  dd|ddgd      \  }}| j                  dd|ddgd      \  }}|rH|rFd|v rd|v rt	        d	j                  |            t        j                  d
j                  |            |r|S |S )z7Retrieves the Mutating Webhook URL used for a revision.r   r   rY   mutatingwebhookconfigurationr  z(jsonpath={.webhooks[0].clientConfig.url}Nr  r*  zHError retrieving the mutating webhook configuration from the cluster: {})_INCLUSTER_WEBHOOK_PREFIXr.   _MCP_WEBHOOK_PREFIXr   r=   r
   r-   )r   r_   incluster_webhookmcp_webhookincluster_outincluster_errmcp_outmcp_errs           r1   r]   z+KubernetesClient.RetrieveMutatingWebhookURL  s     93!..)BHM..!4h?K#'#3#3	.0A	9	;<@$B M= ''	.	9	;<@BGW 	}	$w)>)+ 	+ &( ( Nr3   c                    t        j                         g}| j                  r|j                  d| j                  g       | j                  r|j                  d| j                  g       |j                  d| j
                  g       |j                  |       t        j                         }t        j                         }t        j                  |d|j                  |j                  |      }|dk7  r0|j                         s |j                  dj                  |             |dk(  r|j                         nd|dk7  r|j                         fS dfS )	aB  Runs a kubectl command with the cluster referenced by this client.

    Args:
      args: command line arguments to pass to kubectl
      stdin: text to be passed to kubectl via stdin

    Returns:
      The contents of stdout if the return code is 0, stderr (or a fabricated
      error if stderr is empty) otherwise
    z	--contextz--kubeconfigz--request-timeoutT)no_exitout_funcerr_funcin_strr   z"kubectl exited with return code {}N)c_utilCheckKubectlInstalledr   extendr   r   ioStringIOr   Execwritegetvaluer.   )r   r   stdincmdr   r  
returncodes          r1   r   zKubernetesClient._RunKubectl  s    '')
*C||	jj+t||,-	jj.$//23JJ#T%9%9:;JJt
++-C
++-C %%TCII		%J Qs||~	ii4;;JGH'1_3<<>$	q 9< 9 # #"# #r3   r   )__name__
__module____qualname____doc__r   r   r   r  r  r	  r  r  r  r  r  r  r!  r#  r   r   r   r   r5  r]   r   r   r3   r1   r   r   o  so    5" '
2.(*,		.5688@#r3   r   c                 d    |D ]  }t        | t              s y	 | |   }  | S # t        $ r Y  yw xY w)a  Get the value of a key path from a dict.

  Args:
    manifest: the dict representation of a manifest
    *keys: an ordered list of items in the nested key

  Returns:
    The value of the nested key in the manifest. None, if the nested key does
    not exist.
  N)
isinstancedictrK   )manifestkeyskeys      r1   r?   r?     sD     ch%#h	  
/  s   "	//c                       e Zd ZdZy)PermissionsErrorz3Class for errors raised when verifying permissions.NrP  rQ  rR  rS  r   r3   r1   r[  r[    s    ;r3   r[  c                       e Zd ZdZy)r=   z5Class for errors raised when verifying cluster setup.Nr\  r   r3   r1   r=   r=     s    =r3   r=   c                       e Zd ZdZy)rh   z6Class for errors raised when verifying workload setup.Nr\  r   r3   r1   rh   rh     s    >r3   rh   )IrS  
__future__r   r   r   r   rH  r   r)    googlecloudsdk.api_lib.containerr   rE  5googlecloudsdk.command_lib.compute.instance_templatesr   *googlecloudsdk.command_lib.container.fleetr   r	   r   #googlecloudsdk.command_lib.projectsr   googlecloudsdk.corer
   r   r   googlecloudsdk.core.utilr   r   r   r   r   ,_GCE_SERVICE_PROXY_INSTALLER_BUCKET_METADATAr   rv   r|   rw   r}   r   r   r   r+   r5   r+  r8  r9  rZ   
namedtupler   r2   r8   rG   rP   rS   rV   r[   ra   rl   rp   rs   ro   rr   r   r   r   r   r   r   objectr   r?   r-   r[  r=   rh   r   r3   r1   <module>ri     s   = &  '  	  	 ; X ? Q D * / $ *1 ,  % +J '( -+K (&G #*O '5  ;  : $  ! 8  4  .1;112L O  *(9*$HN**.<(*6F;86*** 0fz2zEE#v E#P*<z'' <>:## >?J$$ ?r3   