
    !                     V   S r SSKJr  SSKJr  SSKJr  SSKJr  SSKrSSKrSSKrSSK	r	SSK
r	SSKrSSKrSSKJr  SSKJr  SS	KJr  SS
KJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSK J!r!  SSK J"r"  SSK J#r#  SSK J$r$  SSK J%r%  SSK&J'r'  SSK(J)r)  SSK*J+r+  SSK*Jr  SSK*J,r,  SSK*J-r-  SSK*J.r.  SSK/J0r0  SSK1J2r2  SSK1J3r3  SSK4r4\Rj                  " SS5      r6\Rj                  " S S5      r7\Rj                  " S!S5      r8S"r9S#r:\;" 5       r< " S$ S%\=5      r> " S& S'\#R~                  5      r@ " S( S)\#R~                  5      rAS* rBS+ rC " S, S-\#R~                  5      rD " S. S/\#R~                  5      rE " S0 S1\#R~                  5      rF " S2 S3\#R~                  5      rGS4 rHS5 rIS6 rJS7 rKS8 rLS9rMS:rNS;rO    SjS< jrPS=rQS> rRS? rSS@ rTSA rU\R                  " SB5      rW\R                  " SC5      rX\R                  " SD5      rYSE rZ\R                  " SF5      r[SG r\SH r]SI r^SJ r_SK r`SL ra " SM SN\;5      rb " SO SP\b5      rc " SQ SR\;5      rdSS reST rf " SU SV\b5      rgSWrh " SX SY\b5      ri " SZ S[\R                  5      rk " S\ S]\b5      rlS^rmS_ rnS`roSa rpSb rqSc rrSkSd jrsSe rtSf ruSg rvSh rwSi rxg)lz<Library for manipulating serverless local development setup.    )absolute_import)division)print_function)unicode_literalsN)encoding_helper)
exceptions)yaml_parsing)container_resourceservice)apis)messages)base)	auth_util)builders)common)
dataobject)secrets)yaml_helper)iam_util)secrets_mapping)config)log)
properties)yaml)
console_io)encoding)filesiamv1cloudresourcemanagerrunzgcr.io/buildpacks/builderz^[a-zA-Z_][a-zA-Z_0-9]*$c                       \ rS rSrSrSrg)_ParseErrorE   z-File does not parse with the expected schema. N__name__
__module____qualname____firstlineno____doc____static_attributes__r&       ,lib/googlecloudsdk/command_lib/code/local.pyr$   r$   E   s    5r.   r$   c                       \ rS rSrSrSrSrg)ServiceAccountSettingI   z.Setting object representing a service account.namer&   Nr(   r)   r*   r+   r,   NAMESr-   r&   r.   r/   r1   r1   I   s
    6
%r.   r1   c                   0   ^  \ rS rSrSrSrU 4S jrSrU =r$ )#ApplicationDefaultCredentialSettingN   z?Setting object representing the application default credential.Nc                 t   > U R                   (       d  [        [        U ]   " U 40 UD6U l         U R                   $ N)	_instancesuperr8   __new__)clskwargs	__class__s     r/   r>   +ApplicationDefaultCredentialSetting.__new__S   s@    ==?)!()),8068cm ==r.   r&   )	r(   r)   r*   r+   r,   r<   r>   r-   __classcell__)rA   s   @r/   r8   r8   N   s    G) r.   r8   c                     SU -  $ )zGCR package path for a builder that works on the given appengine runtime.

Args:
  runtime: Name of a runtime from app.yaml, e.g. 'python38'.

Returns:
  gcr.io image path.
z0gcr.io/gae-runtimes/buildpacks/%s/builder:latestr&   )runtimes    r/   _GaeBuilderPackagePathrF   [   s     
<g	EEr.   c                     U [         :H  $ )zReturn true if the builder is the GCP base builder.

Args:
  bldr: Name of the builder.

Returns:
  True if the builder is the GCP base builder.
)_DEFAULT_BUILDPACK_BUILDER)bldrs    r/   _IsGcpBaseBuilderrJ   g   s     
+	++r.   c                       \ rS rSrSrSrSrg)_SecretPaths   zConfiguration for a single secret version.

Attributes:
  key: The secret version to mount.
  path: The file path to mount it on.
keypathr&   Nr5   r&   r.   r/   rL   rL   s   s     %r.   rL   c                   8    \ rS rSrSrSr\ SS j5       rS rSr	g)	_SecretVolume~   a  Configuration for a single volume that mounts secret versions.

Attributes:
  name: (str) The name of the volume to be referenced in the k8s resource.
  mount_path: (str) The filesystem location where the volume is mounted.
  secret_name: (str) The secret manager reference.
  mapped_secret: (str) If set, the path of the secret in another project to
    use. For example 'projects/123/secrets/foo'.
  items: (List[SecretPath]) The list of keys and paths for the secret.
)r4   mapped_secret
mount_pathsecret_nameitemsNc                    / nU=(       d    0 nUR                    H0  nUR                  [        UR                  UR                  S95        M2     UR
                  nUR                  UR
                  S5      nU(       dQ  [        R                  " U5      (       d6  UnUR                  US5      nU(       d  [        UR
                  5      u  pxXtU'   U " UR                  UR                  UUUS9$ )zFMake a SecretVolume based on the volumeMount and secret from the yaml.rN   Nr4   rU   rV   rW   rT   )rW   appendrL   rO   rP   
secretNamegetr   IsValidK8sName_BuildReachableSecretr4   	mountPath)	r?   mountvolume_secretsecret_aliasesrenamed_secretsrW   itemr4   rT   s	            r/   FromParsedYaml_SecretVolume.FromParsedYaml   s     E%+O##ll;488$))<= $##D"&&}'?'?FM'"8"8">">m  t,d3M4L4LM)-&ZZ??#% %r.   c                     U R                   (       d  UR                   (       a  U R                   UR                   :H  $ U R                  UR                  :H  $ r;   )rT   rV   )selfothers     r/   IsSameSecret_SecretVolume.IsSameSecret   sA    U005#6#666u0000r.   r&   r;   )
r(   r)   r*   r+   r,   r6   classmethodre   rj   r-   r&   r.   r/   rR   rR   ~   s+    	 J%
 &*	% %21r.   rR   c                       \ rS rSrSrSrSrg)_SecretEnvVar   a  Configuration for a single env var that's pulled from a secret.

Attributes:
  name: (str) the name of the secret in the resource
  key: (str) the secret version to use
  mapped_secret: (str) if set, the path of the secret from the other project
    that this secret will pull from. For example 'projects/123/secrets/foo'.
    If not set, will pull from the secret called 'name' in the current
    project.
r4   rO   rT   r&   Nr5   r&   r.   r/   rn   rn      s    	 +%r.   rn   c                   Z    \ rS rSrSrSr\S 5       rSS jrS r	S r
S rS	 rS
 rS rSrg)Settings   a  Settings for local development environments.

Attributes:
  service_name: Name of the kuberntes service.
  image: Docker image tag.
  credential: Credential setting for either service account or application
    default credential.
  context: Path to directory to use as the current working directory for the
    docker build.
  builder: The builder specification or None.
  local_port: Local port to which to forward the service connection.
  env_vars: Container environment variables.
  env_vars_secrets: Container environment variables where the values come
    from Secret Manager.
  volumes_secrets: Volumes where the values come from secret manager.
  renamed_secrets: internal map of secrets that don't correspond to k8s
    naming conventions.
  cloudsql_instances: Cloud SQL instances.
  memory: Memory limit.
  cpu: CPU limit.
  namespace: Kubernetes namespace to run in.
  readiness_probe: If true, create readiness probe.
  allow_secret_manager: If true, allow fetching secrets from secret manager
)service_nameimage
credentialcontextbuilder
local_portenv_varsenv_vars_secretsvolumes_secretsrc   cloudsql_instancesmemorycpu	namespacereadiness_probeallow_secret_managerc                 x   [         R                  R                  [        R                  " 5       5      nUR                  SS5      R                  SS5      R                  5       nSn[        R                  " US9nU " U/ [         R                  R                  [        R                  " 5       5      SU0 0 / 0 [        S9
$ )z5The settings you get with no args or other overrides._- 
Dockerfile
dockerfileN)
rx   r}   rw   ru   rt   rz   r{   r|   rc   r   )osrP   basenamer   GetCWDreplacelowerr   DockerfileBuilderabspath_FLAG_UNSPECIFIED)r?   dir_namert   dockerfile_arg_defaultrx   s        r/   DefaultsSettings.Defaults   s     ww/H##C-55c3?EEGL)((4JKG/!. r.   c           	      	   U R                  U5      nSUR                  R                  0n UR                  R                  R                  R
                  u  n0 nUR                  R                  [        R                  S5      n[        R                  " US5      R                  5        VV	s0 s H  u  pXR!                  5       _M     nnn	UR                  R#                  5       (       a  UR$                  R                  [        R                  S5      n
UR'                  [        R                  " U
S5      R                  5        VV	s0 s H  u  pUU	R!                  5       _M     sn	n5        0 n0 nUR(                   GHI  nUR*                  (       Ga  UR*                  R,                  (       a  [        R                  " S5      eUR*                  R.                  (       a  UR*                  R.                  R                  nUR                  US5      nU(       d[  [0        R2                  " U5      (       d@  UnU R4                  R                  US5      nU(       d  [7        U5      u  pXR4                  U'   [9        UR*                  R.                  R:                  UUS9XR                  '   GM.  GM1  UR<                  XR                  '   GML     UR'                  [?        U R@                  U RB                  UU5      5        UR                  R                  R                  RD                  nU(       a  [G        US9US	'   URH                  nU(       a  UUS
'   UR'                  U RK                  U5      5        0 nUR                  R                  R                  RL                   H\  nURN                  (       a  URN                  UUR                  '   M/  [        R                  " SRQ                  UR                  5      5      e   / nURR                   H  nUR                  U;  a/  [        R                  " SRQ                  UR                  5      5      eURU                  [V        RY                  UUUR                     UU R4                  5      5        M     UUS'   U RZ                  " S0 UD6$ ! [         a    [        R                  " S5      ef = fs  sn	nf s  sn	nf )a  Overrides settings with service.yaml and returns a new Settings object.

Args:
  yaml_path: Filename to read.
  is_alpha: boolean set to true if alpha features should be used.

Returns:
  New Settings object.

Raises:
  _ParseError: Input does not look like a service.yaml
rt   z0knative Service must have exactly one container. Tz+env_vars from config_maps are not supportedN)rO   r4   rT   r3   rv   ru   zGCould not process volume "{}". Only volumes from secrets are supported.z5Container referenced volume "{}" which was not found.r|   r&   )._ParseServiceYamlmetadatar4   spectemplate
containers
ValueErrorr   Errorannotationsr\   r
   SECRETS_ANNOTATIONr   ParseAnnotationrW   FormatAnnotationItemIsFullObjecttemplate_annotationsupdateenv	valueFromconfigMapKeyRefsecretKeyRefr   r]   rc   r^   rn   rO   value_MergedEnvVarsrz   r{   serviceAccountNamer1   ru   _ResourceRequestsvolumessecretformatvolumeMountsrZ   rR   re   r   )rh   	yaml_pathis_alphaknative_servicereplacements	containerrb   aliaseskvtemplate_aliasesnew_env_varsnew_env_vars_secretsvarrV   rT   service_account_name
image_nameall_volsvolreferenced_volss                        r/   WithServiceYamlSettings.WithServiceYaml   s!    ,,Y7O 	0055LQ#((1166AAky N))----r3G $33GTBHHJJDA 	
!!##J   ,,..(==AA

/
/5/>/N/N0&&+eg0.0.tq 

 
 
"#0. 	
 L}}	==((  !NO
O]]''2277+(,,[$?-w'='=k'J'J'M..22=$GK+@+O(k4?""=1+8--,,00),+
xx
( ( "%XX' ( t}}d&;&;\+	-. +//88==PP#8#$%l<  J(l7..y9:H##,,1199	 ZZ  ==CVCHH=MO 	O	 : O%%		!  ((.sxx(8: 	:

&
&sHSXX,>'+';';=>	 & '6L"#<<',''Y  QOPPQs   ,R$ +SS
$!Sc                     [         R                  " U5      n[        R                  " U[        R
                  5      n[        R
                  " U[        5      nU$ ! [         R                  [        R                  4 a    [        5       ef = fr;   )
r   	load_pathmessages_utilDictToMessageWithErrorCheckRUN_MESSAGES_MODULEServicek8s_servicer   DecodeErrorr$   )rh   r   	yaml_dictmessager   s        r/   r   Settings._ParseServiceYamlR  st    ..+i99
(002g#++G5HIo  JJ112 Ms   AA /B	c                 4   UR                   (       a  UR                   R                  (       d  0 $ 0 nUR                   R                  R                   HC  nUR                  S:X  a  UR                  US'   UR                  S:X  d  M4  UR                  US'   ME     U$ )Nr   r~   )	resourceslimitsadditionalPropertiesrO   r   )rh   r   retprops       r/   r   Settings._ResourceRequests\  sy    i&9&9&@&@i
C##**??	U	ZZE
	X	

H	 @
 Jr.   c                     [         R                  R                  U5      n[        UR                  R                  5      n[        R                  " USSS9nU R                  US9$ ! [        R                   a    [        5       ef = f)zOverrides settings with app.yaml and returns a new Settings object.

Args:
  yaml_path: Filename to read.

Returns:
  New Settings object.

Raises:
  ParseError: Input does not look like an app.yaml
TFrx   trustdevmode)rx   )app_engine_yaml_parsingServiceYamlInfoFromFiler   r   r$   rF   parsedrE   r   BuildpackBuilderr   )rh   r   service_configbuilder_urlrx   s        r/   WithAppYamlSettings.WithAppYamlg  s}    .>>GG
n ))>)>)F)FGK''48G<<<(( :: Ms   A% %Bc                 4   0 nS H(  nUR                  U5      (       d  M  [        X5      X#'   M*     UR                  S5      (       a  [        5       US'   O,UR                  S5      (       a  [	        UR
                  S9US'   U R                  nUR                  (       a)  [        R                  R                  UR                  5      nXBS'   [        USS5      (       a  S	US
'   OUR                  S
5      (       a  [        UR                  5      US
'   OUR                  S5      (       a"  [        R                  " UR                  S9US
'   OM[!        U R                  [        R                  5      (       a$   U R                  US
'   US
   R#                  U5        [        USS	5      (       a  UR.                  nO[        US0 5      =(       d    0 nU R1                  [        US0 5      =(       d    0 5      u  pgUR3                  [5        U R.                  U R6                  UU5      5        [9        U R:                  U5      US'   U R<                  " S0 UD6$ ! [        R$                   a4    [&        R(                  R+                  S5        [        [,        5      US
'    Nf = f)z?Overrides settings with args and returns a new Settings object.)	ry   r~   r   r   r   r}   ru   rt   r   application_default_credentialrv   service_accountr3   rw   no_skaffold_fileFNrx   r   r   zCNo Dockerfile detected. Using GCP buildpacks to build the containerrz   env_vars_filer   r|   r&   )IsKnownAndSpecifiedgetattrIsSpecifiedr8   r1   r   rw   sourcer   rP   r   _BuilderFromArgrx   r   r   r   
isinstanceValidateInvalidLocationErrorr   statusPrintrH   rz   _GetSecretsr   r   r{   _MergeSecretVolumesr|   r   )rh   argsr   override_argrw   new_envsnew_env_secretsnew_sec_volumess           r/   WithArgsSettings.WithArgs}  sC    L
 
	!	!,	/	/%,T%@"
 899#F#Hl< 			+	,	,#8##$%l< llG{{,g%t'// $l9		!	!)	,	,"1$,,"?Y##L11"*"<"<#(Y dllH$>$>??,&*llL##,,W5 tZ&&h39rh'+'7'7i$*(,$Ot}}d&;&;X&	() ':o'/L"#<<',''% .. ,JJ K L&5*',L#,s   4#I AJJc           	         0 n0 n0 nUR                  5        GH  u  pVUR                  S5      n[        U5      S:w  a%  [        R                  " SR                  U5      5      eUu  pS n
UR                  S5      (       aV  Un
X;  aJ  UR                  5       R                  SS5      S S S-   [        [        R                  " 5       5      -   nXU
'   ONXJ   nOI[        R                  " U5      (       d.  XR                  ;   a  Un
U R                  U   nO[        U5      u  pUR                  S	5      (       aa  [         R"                  R                  U5      u  pX;  a  [%        UUU/ U
S
9nXU'   OX;   nUR                   R'                  [)        XS95        GM}  [+        XU
S9X%'   GM     U[-        UR/                  5       5      4$ )N:   z<Expected secret to be of form <secretName>:<version>, got {}	projects/r   .   r   /rY   rN   rp   )rW   splitlenr   r   r   
startswithr   r   struuiduuid1r   r]   rc   r^   r   rP   rR   rZ   rL   rn   listvalues)rh   secrets_argsrz   r   r   rO   r   partsrV   versionrT   rU   filenamevolumes                 r/   r   Settings._GetSecrets  s   HGG#))+ll3e	Uq  @@FvP 	P"km				,	,#'!))#s3BQ7#=$**,   $/-
 .+%%k22...%-,,[9+'<['I
$+			!ww}}S1
$ #%)+& !'*
&&KGCD%HO ,R T'..*+++r.   c                    [        U R                  [        R                  5      (       a%  U R                  R	                  U R
                  5        0 nU R                  c  [        U R                  5      US'   U R                  " S0 UD6$ )zCValidate and compute settings after all user inputs have been read.ru   r&   )
r   rx   r   r   r   rw   ru   _DefaultImageNamert   r   )rh   r   s     r/   BuildSettings.Build  se    $,, : :;;
llDLL)Lzz/0A0ABl7<<',''r.   r&   N)F)r(   r)   r*   r+   r,   r6   rl   r   r   r   r   r   r   r   r  r-   r&   r.   r/   rr   rr      sJ    2C%
  ,a(F	),;(z.,`(r.   rr   c                 f   U R                  5       n UR                  5       n[        U5      R                  U5      nU(       a%  [        R                  " SR                  U5      5      eUR                  5        H  u  pVXQ;   a  X	 X`U'   M     UR                  5        H  u  pvXp;   a  X	 XaU'   M     XS.$ )zDAdd the new env vars (both values and secrets) to the existing ones.z{} cannot be secret and literal)rz   r{   )copysetintersectionr   r   r   rW   )rz   r{   r   r   	conflictsnew_envval
new_secrets           r/   r   r     s     ]]_(%**, ,,,-AB)


<CCIN
OO
 #((*lg"

#W + .335oj

#&Z  6 	EEr.   c                 J   U  Vs0 s H  o"R                   U_M     nnU H  nUR                   U;  a  XCUR                   '   M#  X4R                      nUR                  U5      (       a  UR                   Vs0 s H  ofR                  U_M     nnUR                   Vs0 s H  ofR                  U_M     nnUR	                  U5        [        UR                  5       5      UR                  SS& M  XCUR                   '   M     [        UR                  5       5      $ s  snf s  snf s  snf )zACombine the secret volumes from existing source with new volumes.N)rU   rj   rW   rP   r   r	  r
  )	cur_volsnew_volsr   vol_mapnew_volcur_volrd   	cur_items	new_itemss	            r/   r   r     s    ,45HS^^S H'5g($+g  !**+g			g	&	&18?YY_	?18?YY_	?#	 0 0 23a '.""#  
gnn	 6 @?s   D4DD c                    U[         R                  R                  :H  n[        R	                  5       n[        U SS5      =(       d    [        R                  R                  n[        U SS5      n[        R                  " XE5      nU(       a-   UR                  Xa[         R                  R                  :H  5      nUR!                  U 5      nUR#                  5       nU$ ! [         a\    U(       a;   UR                  U5      n NH! [         a    [        R                  " SU-  5      ef = f[        R                  " SU-  5      ef = f)zHLayer the defaults, service.yaml/app.yaml values, and cmdline overrides.r   Nr   z4%r is unreadable as a service.yaml or app.yaml file.z(%r is unreadable as a service.yaml file.)r   ReleaseTrackALPHArr   r   r   r   rP   curdirr   ChooseExistingServiceYamlr   r$   r   r   r   r   r  )r   release_trackservice_config_may_be_app_yamlsettingscontext_dirservice_config_arg	yaml_files          r/   AssembleSettingsr0  "  s)    $1D4E4E4K4K#K  (h-?+t%5t<..{O)*))
d&7&7&=&==?h t$(^^(	/  
*	'	)))4( 	  D 	
 I( ) * 	*
*s   ,C E ,C??$D##E c                     [         R                  R                  R                  R	                  5       nU(       a  SR                  XS9nOU nUR                  5       nU$ )zComputes a default image name.zgcr.io/{project}/{service})projectr   )r   VALUEScorer2  Getr   r   )rt   project_nameru   s      r/   r  r  @  sV    ""''//335,(// 0 4E E ++-%	,r.   c                 D    [        U 5      n[        R                  " U UUS9$ )Nr   )rJ   r   r   )builder_argis_gcp_base_builders     r/   r   r   Q  s)    )+6		"	"!
# #r.   a.  
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {service}
  labels:
    service: {service}
spec:
  replicas: 1
  selector:
    matchLabels:
      app: {service}
  template:
    metadata:
      labels:
        app: {service}
    spec:
      containers: []
      terminationGracePeriodSeconds: 0
zi
name: {service}-container
image: {image}
env:
- name: PORT
  value: "8080"
ports:
- containerPort: 8080
z
name: {service}-readiness-probe
image: gcr.io/gcp-runtimes/ubuntu_18_0_4:latest
command: ["sleep"]
args: ["infinity"]
readinessProbe:
  exec:
    command:
    - "grep"
    - ":1F90"
    - "/proc/net/tcp"
    - "/proc/net/tcp6"
  periodSeconds: 1
c                    [         R                  " [        R                  U S95      n[         R                  " [        R                  XS95      nUb  [
        R                  " US5      nX(S'   Ub0  [
        R                  " US5      n[        R                  " U5      US'   Ub0  [
        R                  " US5      n	[        R                  " U5      U	S'   [
        R                  " US[        S9n
U
R                  U5        U(       a8  [         R                  " [        R                  U S95      nU
R                  U5        Xg4$ )	aq  Create a deployment specification for a service.

Args:
  service_name: Name of the service.
  image_name: Image tag.
  memory_limit: Container memory limit.
  cpu_limit: Container cpu limit.
  cpu_request: Container cpu request.
  readiness_probe: If true, add a readiness probe.

Returns:
  Dictionary object representing the deployment yaml, and the main container.
r   )r   ru   )r   r   r~   r   )r   requestsr   r   r   r   constructor)r   load_POD_TEMPLATEr   _CONTAINER_TEMPLATEr   GetOrCreatesix	text_typer	  rZ   #_READINESS_PROBE_CONTAINER_TEMPLATE)rt   r   memory_limit	cpu_limitcpu_requestr   
deploymentr   r   r;  r   readiness_containers               r/   _CreateDeploymentrK    s   & yy--l-CD*ii   HJ)$$Y0GHF#8$$Y0GHFMM),F5M&&y2KLHmmK0HUO&&<$P*I))+22<2HJ)*		r.   z
apiVersion: v1
kind: Service
metadata:
  name: {service}
spec:
  type: LoadBalancer
  selector:
    app: {service}
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 8080
c                 T    [         R                  U S9n[        R                  " U5      $ )zCreate a service specification.

Args:
  service_name: Name of the service.

Returns:
  Dictionary objects representing the service yaml.
r   )_SERVICE_TEMPLATEr   r   r?  )rt   	yaml_texts     r/   CreateServicerO    s&      &&|&<)	9	r.   c                 ^   [         R                  " U S[        S9n/ n[        UR	                  5       5       H_  u  pE[
        R                  " [        U5      (       d'  UR                  [        R                  " U5      5        ML  UR                  XES.5        Ma     U(       a  [        SU-  5      eg)zAdd environment variable settings to a container.

Args:
  container: (dict) Container to edit.
  env_vars: (dict) Key value environment variable pairs.
r   r=  r4   r   zCEnvironment variable name must be a C_IDENTIFIER. Invalid names: %rN)r   rB  r	  sortedrW   rematch_C_IDENTIFIERrZ   rC  
ensure_strr   )r   rz   env_listinvalid_keysrO   r   s         r/   _AddEnvironmentVariablesrZ    s     $$YdK(,8>>+,jc88M3''#..-.OOS12	 -
 
 )+78 9 9 r.   c                     [         R                  " U S[        S9n[        UR	                  5       5       H2  u  p4UR                  USUR                  UR                  S.0S.5        M4     g)zAdd environment variables from secrets to a container.

Args:
  container: (dict) Container to edit.
  env_vars_secrets: (dict) Key value environment variable pairs. Values are
    dict with key/name keys in them.
rQ  r=  r   )r4   rO   )r4   r   N)r   rB  r	  rS  rW   rZ   r4   rO   )r   r{   rX  rO   r   s        r/   _AddSecretEnvironmentVariablesr\    sb     $$YdK(+1134jcOO

yy
  5r.   c                 T   [        U 5      nSR                  XS9n[        U5      n[        U 5      (       a  U(       d  [	        SU -  5      eU$ U(       dT  [        U 5      n[        SUU5        SnSR                  U 5      n[        R                  " XVS9(       a  [        USU -   S	5        U$ )
zCreates a service account for local development.

Args:
  service_account_email: Email of the service account.

Returns:
  The resource name of the service account.
z,projects/{project}/serviceAccounts/{account})r2  accountz9%s cannot be created because it is a service account namez,Serverless Local Development Service AccountzoThe project editor role allows the service account to create, delete, and modify most resources in the project.zAdd project editor role to {}?r   prompt_stringzserviceAccount:zroles/editor)
_GetServiceAccountProjectr   _ServiceAccountExists_IsReservedServiceAccountNamer   _GetServiceAccountId_CreateAccountr   PromptContinue_AddBinding)service_account_email
project_idr   exists
account_idpermission_msgr`  s          r/   CreateDevelopmentServiceAccountrm    s     ))>?*GNN O 9 !!56&"#899 &(=> ? ? "!	%&;<JA:!N 	)//0EF    =*/2GG " 
r.   z9(?P<id>[^@]+)@(?P<project>[^\.]+).iam.gserviceaccount.comz=(?P<project_id>[^\.]+).google.com@appspot.gserviceaccount.comz=(?P<project_number>\d+)-compute@developer.gserviceaccount.comc                 >   [         R                  U 5      nU(       a  UR                  S5      $ [        R                  U 5      nU(       a  UR                  S5      $ [        R                  U 5      nU(       a  [        UR                  S5      5      $ [        U S-   5      e)zGet the project id from a service account email.

Args:
  service_account_email: (str) Email address of service account.

Returns:
  The project id of the project to which the service account belongs.
r2  ri  project_number' is not a valid service account address)_PROJECT_SERVICE_ACCOUNT_RErU  group_APPENGINE_SERVICE_ACCOUNT_COMPUTE_SERVICE_ACCOUNT_ProjectNumberToIdr   rh  matchers     r/   ra  ra  3  s     (--.CD'==##&,,-BC'==&&$**+@A'gmm,<=>>(<= 	> >r.   z&(?P<id>[^@]+)@.*\.gserviceaccount\.comc                 x    [         R                  U 5      nU(       d  [        U S-   5      eUR                  S5      $ )Nrp  id)_SERVICE_ACCOUNT_RErU  r   rr  rv  s     r/   rd  rd  O  s?    %%&;<'	
*>? @ @	t	r.   c                     [         R                  " SS5      n[        R                  U S9nUR                  R                  U5      n[        R                  " UR                  5      $ )zCoverts project number to project id.

Args:
  project_number: (str) The project number as a string.

Returns:
  The project id.
r!   r    )	projectId)	r   GetClientInstanceCRM_MESSAGE_MODULE&CloudresourcemanagerProjectsGetRequestprojectsr5  rC  ensure_textr|  )ro  resource_managerreqr2  s       r/   ru  ru  W  s\     ++,BDIAA 	B 	 #%%))#.'	**	++r.   c                 d    [         R                  U 5      =(       d    [        R                  U 5      $ r;   )rs  rU  rt  )rh  s    r/   rc  rc  g  s,    
$
*
*+@
A @
"
(
()>
?Ar.   c                     [         R                  " SS5      n [        R                  U S9nUR                  R                  U5        g! [        R                   a     gf = f)zTests if service account email.

Args:
  service_account_name: (str) Service account resource name.

Returns:
  True if the service account exists.
r   r    r3   TF)r   r}  IAM_MESSAGE_MODULE$IamProjectsServiceAccountsGetRequestprojects_serviceAccountsr5  apitools_exceptionsHttpNotFoundError)r   r   requests      r/   rb  rb  l  sc     ""5$/' EE! F #G$$((1		.	. s   .A AAc                    [         R                  " SS5      n [        R                  U S9n[        R	                  XS9nUR
                  R                  [        R                  SU-   US95        g! [        R                   a     gf = f)zCreate an account if it does not already exist.

Args:
  display_name: (str) Display name.
  account_id: (str) User account id.
  project: (str) Project name.
r   r    )displayName)	accountIdserviceAccountr   )r4   createServiceAccountRequestN)
r   r}  r  ServiceAccountCreateServiceAccountRequestr  Create'IamProjectsServiceAccountsCreateRequestr  HttpConflictError)display_namerk  r2  r   service_account_msgr  s         r/   re  re    s     ""5$/'
	,;;  < " << = BG$$++BBw&G 	C 	MN 
	.	. 		s   AA0 0BBc                    [         R                  " SS5      nUR                  R                  [        R                  U S95      n[        R                  " XAU5      (       dg  [        R                  " [        R                  XAU5        [        R                  U [        R                  US9S9nUR                  R                  U5        gg)ziAdds a binding.

Args:
  project: (str) Project name.
  account: (str) User account.
  role: (str) Role.
r!   r    )resource)policy)r  setIamPolicyRequestN)r   r}  r  GetIamPolicyr~  /CloudresourcemanagerProjectsGetIamPolicyRequestr   BindingInPolicyAddBindingToIamPolicyBinding/CloudresourcemanagerProjectsSetIamPolicyRequestSetIamPolicyRequestSetIamPolicy)r2  r^  role
crm_clientr  r  s         r/   rg  rg    s     %%&<dC*++HH I & 
	!	!&4	8	8""#5#=#=v#')

L
L.BB C  M C $$S) 
9r.   c                   *    \ rS rSrSrS rS rS rSrg)KubeConfigGeneratori  zhThe base code generator with default return values.

Subclasses may override any of the member methods.
c                     / $ )zqCreate top level kubernetes configs.

Returns:
  List of kubernetes configuration yamls encoded as dictionaries.
r&   rh   s    r/   CreateConfigs!KubeConfigGenerator.CreateConfigs  s	     Ir.   c                     g)zModify a deployment.

Subclasses that override this method should use this method for adding
or deleting resources (e.g. containers, volumes, metadata) to the
deployment.

Args:
  deployment: (dict) Deployment yaml in dictionary form.
Nr&   )rh   rI  s     r/   ModifyDeployment$KubeConfigGenerator.ModifyDeployment      r.   c                     g)zModify a container.

Subclasses that override this method should use this method for adding,
deleting, or modifying any of the yaml for a container.

Args:
  container: (dict) Container yaml in dictionary form.
Nr&   )rh   r   s     r/   ModifyContainer#KubeConfigGenerator.ModifyContainer  r  r.   r&   N)	r(   r)   r*   r+   r,   r  r  r  r-   r&   r.   r/   r  r    s    
	r.   r  c                   4    \ rS rSrSr      SS jrS rSrg)AppContainerGeneratori  z6Generate deployment and service for a developer's app.Nc	                 d    Xl         X l        X0l        X@l        XPl        X`l        Xpl        Xl        g r;   )_service_name_image_name	_env_vars_env_vars_secrets_memory_limit
_cpu_limit_cpu_request_readiness_probe)	rh   rt   r   rz   r{   rF  rG  rH  r   s	            r/   __init__AppContainerGenerator.__init__  s2     &!N-%O#+r.   c                    [        U R                  U R                  U R                  U R                  U R
                  U R                  5      u  pU R                  SSS.n[        X#5        U R                  (       a  [        X R                  5        U R                  (       a  [        X R                  5        [        U R                  5      nX/$ )Ndevzdev-0001)	K_SERVICEK_CONFIGURATION
K_REVISION)rK  r  r  r  r  r  r  rZ  r  r  r\  rO  )rh   rI  r   default_env_varsr   s        r/   r  #AppContainerGenerator.CreateConfigs  s    -D,,d.@.@**D,A,ACJ ''   Y9~~y..9$Y0F0FGD../G  r.   )r  r  r  r  r  r  r  r  )NNNNNF)r(   r)   r*   r+   r,   r  r  r-   r&   r.   r/   r  r    s#    >
  $ $,$!r.   r  c                       \ rS rSrSrS rSrg)
SecretInfoi  z%Information about a generated secret.c                 `    SU l         SU R                   R                  SS5      -   S-   U l        g )Nzlocal-development-credential/etc/r   r   z'/local_development_service_account.json)rV   r   rP   r  s    r/   r  SecretInfo.__init__  s1    5D4++33C==:;DIr.   )rP   rV   N)r(   r)   r*   r+   r,   r  r-   r&   r.   r/   r  r    s
    -<r.   r  c                 .    [        U 5      n[        U5      $ )zGet a service account secret file as text.

Args:
  account_name: (str) Name of the service account.

Returns:
  Context of the service account secret as a string.
)rm  CreateServiceAccountKey)account_namer   s     r/   GetServiceAccountSecretr    s     4LA/	 	11r.   c                  ~    [         R                  " 5         [        R                  " [         R                  " 5       5      $ )zGet a copy of the application default credential for a user.

Returns:
  Text version of the user's application default credential.
)r   AssertADCExistsjsondumpsGetADCAsJsonr&   r.   r/   GetUserCredentialr    s(     	I**,	--r.   c                   6    \ rS rSrSrS rS rS rS rS r	Sr
g	)
CredentialGeneratori  z"Configures service account secret.c                     Xl         g r;   _credential_fetcher)rh   credential_fetchers     r/   r  CredentialGenerator.__init__  s    1r.   c                     [        5       $ r;   )r  r  s    r/   GetInfoCredentialGenerator.GetInfo  s
    <r.   c                 6    [        U R                  5       5      /$ )zCreate a secret.)LocalDevelopmentSecretSpecr  r  s    r/   r  !CredentialGenerator.CreateConfigs!  s    &t'?'?'ABCCr.   c                     U R                  5       n[        R                  " US[        5      n[	        X2R
                  5        g)z$Add a secret volume to a deployment.r   r   r   r   N)r  r   rB  r	  _AddSecretVolumerV   )rh   rI  secret_infor   s       r/   r  $CredentialGenerator.ModifyDeployment%  s5    ,,.K%%j&M&*,G W556r.   c                     U R                  5       n[        R                  " US[        5      n[	        X2R
                  5        [        R                  " US[        5      n[        XBR                  5        g)zEAdd volume mount and set application credential environment variable.r   rQ  N)r  r   rB  r	  _AddSecretVolumeMountrV   _AddSecretEnvVarrP   )rh   r   r  mountsenvss        r/   r  #CredentialGenerator.ModifyContainer-  sR    ,,.K$$Y0A4HF&"9"9:""9h=DT++,r.   r  N)r(   r)   r*   r+   r,   r  r  r  r  r  r-   r&   r.   r/   r  r    s    *2D7-r.   r  zcloud-sql-proxyc                   *    \ rS rSrSrS rS rS rSrg)CloudSqlProxyGeneratori9  zDGenerate kubernetes configurations for a Cloud SQL proxy connection.c                     Xl         X l        g r;   _instance_names_secret_info)rh   instance_namesr  s      r/   r  CloudSqlProxyGenerator.__init__<  s    )#r.   c                    [         R                  " US[        S9nUR                  S0 S.5        [         R                  " US[        S9nUR                  [	        U R
                  U R                  R                  5      5        g)z7Add sidecar container and empty volume for unix socket.r  r=  cloudsql)r4   emptyDirr<  N)r   rB  r	  rZ   _CreateCloudSqlProxyContainerr  r  rP   )rh   rI  r   r   s       r/   r  'CloudSqlProxyGenerator.ModifyDeployment@  st    %%;OGNNJB78((>J %d&:&:&*&7&7&<&<	>?r.   c                 ~    US   [         :X  a  g[        R                  " US[        S9nUR	                  SSSS.5        g)	zAdd volume mount to continer.

This method will not modify the CloudSql proxy container.

Args:
  container: (dict) Container yaml as a dict.
r4   Nr  r=  r  	/cloudsqlTr4   r_   readOnly)_CLOUD_PROXY_CONTAINER_NAMEr   rB  r	  rZ   )rh   r   volume_mountss      r/   r  &CloudSqlProxyGenerator.ModifyContainerM  sI     77++$$8M  r.   r  N)	r(   r)   r*   r+   r,   r  r  r  r-   r&   r.   r/   r  r  9  s    L$?r.   r  c                       \ rS rSrSrSrg)SecretsNotAllowedErrori`  zEError thrown when the deploy is not allowed to access secret manager.r&   Nr'   r&   r.   r/   r  r  `  s    Mr.   r  c                   6    \ rS rSrSr\4S jrS rS rS r	Sr
g)	SecretsGeneratorie  z3Generate kubernetes secrets for referenced secrets.c                 R   [         R                  R                  R                  R	                  5       U l        Xl        X0l        0 U l        [        R                  " [        5      nUR                  5        H8  u  pxXhR                  UR                  4   R                  UR                   5        M:     U H  nUR                  (       dC  XhR"                  UR                  4   R                  [$        R&                  R(                  5        MW  UR                   H6  n	XhR"                  UR                  4   R                  U	R                   5        M8     M     UR                  5        H4  u  u  pn[*        R,                  " U
[/        U5      US9U R                  U
'   M6     X@l        XPl        g )N)r4   versionsrT   )r   r3  r4  r2  r5  r6  rt   secret_volumesall_secretscollectionsdefaultdictr  rW   r4   rT   addrO   rV   r   SpecialVersion	MOUNT_ALLr   SecretManagerSecret	frozensetr   r   )rh   rt   env_secretsr	  r   r   secrets_builderr   r   rd   rV   rT   r  s                r/   r  SecretsGenerator.__init__h  sV    #))..66::<D$(D!--c2O &&(	{{F$8$89:>>vzzJ ) !\\++V-A-ABCGG**44	6 LLD
--!//1 225#dhh- ! ! 3B2G2G2I.$h&-&A&AX&%''d{# 3J
 N 4r.   c                    U R                   (       d  / $ U R                  [        L a  / nU R                   R                  5        HD  u  p#UR                  (       a  UR                  UR                  5        M3  UR                  U5        MF     SnSR                  U5      n[        R                  " 5       (       a?  [        R                  " XES9(       a&  [        R                  R                  S5        SU l        U R                  (       a  U R                  [        L a  [        S5      e[        R                  " U R                   [#        U R                   R%                  5       5      U R&                  5      $ )NzThis config references secrets stored in secret manager. Continuing will fetch the secret values and download the secrets to your local machine.z)Fetch secrets from secret manager for {}?r_  zRYou can skip this message in the future by passing the flag --allow-secret-managerTzConfig requires secrets but access to secret manager was not allowed. Replace secrets with environment variables or allow secret manager with --allow-secret-manager to proceed.)r
  r   r   rW   rT   rZ   r   r   	CanPromptrf  r   r   r   r  r   BuildSecretsr6  r  r
  r   )rh   	requestedrO   secsecrets_msgr`  s         r/   r  SecretsGenerator.CreateConfigs  s1   i  $55i&&,,.(#


3,,
-


3
	 /
:k 6
<
<Y
G  
				J$=$=%<

*	+ %)!%%!!%66"IJ J  1 1 #D$4$4$;$;$= >P Pr.   c                 
   US   S   U R                   :w  a  g U R                  (       d  g [        R                  " US[        5      nU R                   H.  n[        X#R                  UR                  UR                  5        M0     g )Nr   r4   r  )	rt   r	  r   rB  r	  _AddSecretVolumeByNamerV   r4   rW   )rh   rI  r   r  s       r/   r  !SecretsGenerator.ModifyDeployment  sr     *f%):)::%%j&M&*,G %%W&8&8&++#\\+ &r.   c                    US   SR                  U R                  5      :w  a  g U R                  (       d  g [        R                  " US[
        5      nU R                   H#  n[        X#R                  UR                  5        M%     g )Nr4   z{}-containerr  )	r   rt   r	  r   rB  r	  _AddVolumeMountr4   rU   )rh   r   r  r  s       r/   r   SecretsGenerator.ModifyContainer  sh    N11$2C2CDD$$Y0A4HF%%fkk6+<+<= &r.   )r
  r   r   r6  r	  rt   N)r(   r)   r*   r+   r,   r   r  r  r  r  r-   r&   r.   r/   r  r  e  s!    ; %65BPB+>r.   r  z1.16c                 b    [         S[        -   S/SSSR                  U 5      -   SU-   /SSS	./S
.$ )Nz!gcr.io/cloudsql-docker/gce-proxy:z/cloud_sql_proxyz-dir=/cloudsqlz-instances=,z-credential_file=r  r  )r4   r_   )r4   ru   commandr   r   )r   _CLOUD_SQL_PROXY_VERSIONjoin)	instancessecret_paths     r/   r  r    sP    )25MM$%
MCHHY,??

+
 " 	
 r.   zY
apiVersion: v1
kind: Secret
metadata:
  name: local-development-credential
type: Opaque
c                    [         R                  R                  [        R                  " 5       R
                  [        U 5      S-   5      n[        R                  " [         R                  SU5      n[         R                  R                  U5      (       a  [        R                  " U5      $ SR                  U US9n[        R                  " USSS9  [         R"                  " SS	5      nUR$                  nUR'                  U UR)                  UR(                  R*                  R,                  S
9S9nUR.                  R1                  U5      n[        R2                  " X'R4                  5        [6        R8                  " UR4                  5      $ )zCreate a service account key.

Args:
  service_account_name: Name of service acccount.

Returns:
  The contents of the generated private key file as a string.
z.jsonLOCAL_CREDENTIAL_PATHa  Creating a user-managed service account key for {service_account_name}. This service account key will be the default credential pointed to by GOOGLE_APPLICATION_CREDENTIALS in the local development environment. The user is responsible for the storage,rotation, and deletion of this key. A copy of this key will be stored at {local_key_path}.
Only use service accounts from a test project. Do not use service accounts from a production project.)r   local_key_pathz	Continue?T)r   r`  cancel_on_nor   r    )privateKeyType)r4   createServiceAccountKeyRequest)r   rP   r&  r   Pathsglobal_config_dir_Utf8ToBase64r   GetEncodedValueenvironrj  r   ReadFileContentsr   r   rf  r   r}  MESSAGES_MODULE+IamProjectsServiceAccountsKeysCreateRequestCreateServiceAccountKeyRequestPrivateKeyTypeValueValuesEnumTYPE_GOOGLE_CREDENTIALS_FILEprojects_serviceAccounts_keysr  WriteFileContentsprivateKeyDatarC  r  )r   default_credential_pathcredential_file_pathwarning_msgr   message_modulecreate_key_requestrO   s           r/   r  r    sd    GGLLlln&&()G35 "11"**2I2IK WW^^())!!"677? AG*>$8 AG A:  4I ""5$/'**. @@#)7))+JJ,,-I-I * K A L  	--445GH#.0B0BC	++	,,r.   c                 Z    [         R                  " [        5      nS[        U 5      0US'   U$ )zCreate a kubernetes yaml spec for a secret.

Args:
  key: (str) The private key as a JSON string.

Returns:
  Dictionary representing yaml dictionary.
z&local_development_service_account.jsondata)r   r?  _SECRET_TEMPLATEr1  )rO   yaml_configs     r/   r  r    s1     		*++.c0B+f 
r.   c                     [        XUS9  g )N)rV   volume_name)r  )r   rV   s     r/   r  r     s    KAr.   c                 X  ^ [        U4S jU  5       5      (       a  gU=(       d    /  Vs/ s H+  n[        R                  UR                  UR                  S9PM-     nnU R                  [        R                  " [        R                  T[        R                  XS9S95      5        gs  snf )a  Add a secret volume to a list of volumes.

Args:
  volumes: (list[dict]) List of volume specifications.
  secret_name: (str) Name of the secret.
  volume_name: (str) Name of the volume to add.
  items: (list[_SecretPath]) Optional list of SecretPaths to map on the
    filesystem.
c              3   2   >#    U  H  oS    T:H  v   M     g7fr4   Nr&   ).0r  rG  s     r/   	<genexpr>)_AddSecretVolumeByName.<locals>.<genexpr>/  s     =W6;	&Ws   NrN   )r[   rW   )r4   r   )
anyr   	KeyToPathrO   rP   rZ   r   MessageToDictVolumeSecretVolumeSource)r   rV   rG  rW   secpath	items_lsts     `   r/   r  r  %  s     	=W===
 krk!' ##',,#G!   
..##

$
$(;;( < ; % <=>	s   2B'c           	      @    [        U USUR                  SS5      -   S9  g)zAdd a secret volume mount.

Args:
  mounts: (list[dict]) List of volume mount dictionaries.
  secret_name: (str) Name of the secret.
r  r   r   )
mount_namerU   N)r   r   )r  rV   s     r/   r  r  =  s'     ;..sC88:r.   c                    ^ [        U4S jU  5       5      (       a  g [        R                  TUSS9nU R                  [        R
                  " U5      5        g )Nc              3   4   >#    U  H  nTUS    :H  v   M     g7frJ  r&   )rK  r`   rV  s     r/   rL  "_AddVolumeMount.<locals>.<genexpr>K  s     9&uV}	$&s   Tr  )rN  r   VolumeMountrZ   r   rP  )r  rV  rU   r`   s    `  r/   r   r   J  sJ    9&999


)
)d * <%----e45r.   c                 H    SS U  5       ;  a  U R                  SUS.5        gg)a*  Adds a environmental variable that points to the secret file.

Add a environment varible where GOOGLE_APPLICATION_CREDENTIALS is the name
and the path to the secret file is the value.

Args:
  envs: (list[dict]) List of dictionaries with a name entry and value entry.
  path: (str) Path to secret.
GOOGLE_APPLICATION_CREDENTIALSc              3   *   #    U  H	  oS    v   M     g7frJ  r&   )rK  r   s     r/   rL  #_AddSecretEnvVar.<locals>.<genexpr>\  s     -JTc&kTs   rR  N)rZ   )r  rP   s     r/   r  r  R  s*     &-JT-JJKK9DIJ Kr.   c                 ~    [         R                  " [        R                  " [         R                  " U 5      5      5      $ )z*Encode a utf-8 string as a base 64 string.)rC  r  base64	b64encodeensure_binary)ss    r/   r1  r1  `  s'    	))#*;*;A*>?	@@r.   c                     U R                  SS5      R                  5       n[        [        R                  " 5       5      nUS S[        U5      -
   U-   nS nX:w  a  U nX4$ )Nr   r      )r   r   r  r  r  r  )r4   new_nameumappeds       r/   r^   r^   e  s]    \\#s#))+(	$**,!msSV|$q((&F		r.   )NNNFr;   )yr,   
__future__r   r   r   r   r`  r  r  r   os.pathrT  r  apitools.base.pyr   r   r  googlecloudsdk.api_lib.appr	   r   googlecloudsdk.api_lib.runr
   r   r   googlecloudsdk.api_lib.utilr   r   r   googlecloudsdk.callioper   googlecloudsdk.command_lib.authr   googlecloudsdk.command_lib.coder   r   r   r   r   googlecloudsdk.command_lib.iamr   googlecloudsdk.command_lib.runr   googlecloudsdk.corer   r   r   r   googlecloudsdk.core.consoler   googlecloudsdk.core.utilr   r   rC  GetMessagesModuler  r~  r   rH   rV  objectr   	TypeErrorr$   
DataObjectr1   r8   rF   rJ   rL   rR   rn   rr   r   r   r0  r  r   r@  rA  rE  rK  rM  rO  rZ  r\  rm  compilerq  rs  rt  ra  rz  rd  ru  rc  rb  re  rg  r  r  r  r  r  r  r   r  r   r  r  r%  r  rD  r  r  r  r  r  r   r  r1  r^   r&   r.   r/   <module>r|     s   C &  % '    	  	  , > N 9 = , A ( 5 4 2 6 3 7 3 : & * # * $ 2 - * 
++E48 ++,BDI ,,UD9 8 +
 H 6) 6J11 

**?*? 
	F	,*'' *1J)) *1Z+J)) +x(z$$ x(v	F6 &<"#* ' #$ $( $"&&+(V  
9&*%T !jj@B 
  ZZDF 
 ::DF >2 jj!JK , A
&	,*.!& !H%!/ %!P< <
2.-- -< 0 $0 $NZ-- 
[>* [>| "   .-b A
>0
:6KA
r.   