
    5                        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
Jr  SSKJr  SS	KJr   " S
 S\R                  5      r " S S\R                  5      rS rS rSS jrS rS rS r " S S\5      rg)zEOperations on secret names and the run.google.com/secrets annotation.    )absolute_import)division)print_function)unicode_literalsN)container_resource)
exceptions)	platformsc                       \ rS rSrSrSrSrg)SpecialVersion    z1Special cases for ReachableSecret.secret_version.r    N)__name__
__module____qualname____firstlineno____doc__	MOUNT_ALL__static_attributes__r       5lib/googlecloudsdk/command_lib/run/secrets_mapping.pyr   r       s    9 )r   r   c                       \ rS rSrSrSrSrg)SpecialConnector(   z-Special cases for ReachableSecret._connector.r   r   N)r   r   r   r   r   PATH_OR_ENVr   r   r   r   r   r   (   s    5 +r   r   c                 j    U R                   R                  R                  [        R                  S5      $ )N )templateannotationsgetr   SECRETS_ANNOTATION)resources    r   _GetSecretsAnnotationr"   4   s,    				&	&	*	*++R
 r   c                     U R                   R                  nU(       a  X[        R                  '   g  U[        R                  	 g ! [         a     g f = fN)r   r   r   r    KeyError)r!   valuer   s      r   _SetSecretsAnnotationr'   :   sK    !!--+
9>"556
(;;
< 
s   A 
AAc                 2   0 nU (       d  0 $ U R                  S5       HZ  n UR                  S5      u  pE[        R                  U5      (       d  [        SU-  5      e[        U[        R
                  US9X$'   M\     U$ ! [         a    [        SU-  5      ef = f)zParse existing secrets annotation.

Args:
  formatted_annotation: str
  force_managed: bool

Returns:
  Dict[local_alias_str, ReachableSecret]
,:z%Invalid secret entry %r in annotationz$Invalid secret path %r in annotation)force_managed)split
ValueErrorReachableSecretIsRemotePathr   r   )formatted_annotationr+   reachable_secretspairlocal_aliasremote_paths         r   ParseAnnotationr5   E   s     	I"((-dG!%Ck ''44=KLL%4%11&" . 
  G>EFFGs   A==Bc                 `    SR                  S [        U R                  5       5       5       5      $ )Nr)   c              3   T   #    U  H  u  pU< S UR                  5       < 3v   M      g7f)r*   N)FormatAnnotationItem).0aliasreachable_secrets      r   	<genexpr>$_FormatAnnotation.<locals>.<genexpr>a   s)      %F
!% (==?@%Fs   &()joinsorteditems)r1   s    r   _FormatAnnotationrA   `   s/    	 %+,=,C,C,E%F 
 r   c                 F   [         R                  R                  S U R                  R                  R                  5        5       5      n[        [         R                  " S U R                  R                  R                  R                  5        5       S U 5       5      5      $ )zSet of all secret names (local names & remote aliases) in use.

Args:
  resource: ContainerResource

Returns:
  List of local names and remote aliases.
c              3   j   #    U  H)  nUR                   R                  R                  5       v   M+     g 7fr$   )env_varssecretsvalues)r9   	containers     r   r<   _InUse.<locals>.<genexpr>p   s/      +<)   ''))<s   13c              3   :   #    U  H  nUR                   v   M     g 7fr$   
secretNamer9   sources     r   r<   rH   v   s      F& Fs   c              3   L   #    U  H  oR                   R                  v   M     g 7fr$   )secretKeyRefnamerL   s     r   r<   rH   z   s     
;(##(s   "$)		itertoolschainfrom_iterabler   
containersrF   	frozensetvolumesrE   )r!   rD   s     r   _InUserW   g   s     __** +((33::<+ ( 
oo$--55==DDF <(
;
 r   c                     [        U 5      n[        U 5      n[        U5      R                  5        VVs0 s H  u  p4X1;   d  M  X4_M     nnn[	        U [        U5      5        gs  snnf )z{Garbage-collect items in the run.googleapis.com/secrets annotation.

Args:
  resource: k8s_object resource to be modified.
N)rW   r"   r5   r@   r'   rA   )r!   in_user0   r:   rsto_keeps         r   PruneAnnotationr\      sl     (&.x8 '';<BBDD)%	 eiD 
  "3G"<=s   A!A!c                       \ rS rSrSrSrSrSrSrS\-   S-   \-   S	-   r	S
\-   S-   \-   \	-   S-   r
\S 5       rS S jrS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rSrg)!r.      a=  A named secret+version that we can use in an env var or volume mount.

See CL notes for references to the syntax being parsed here.

This same type is used for local secrets in this project and remote secrets
that are mapped in the run.googleapis.com/secrets annotation. This class
adds to that annotation as needed.
z(?P<project>[0-9]{1,19})z (?P<secret>[a-zA-Z0-9-_]{1,255})z:(?P<version_short>.+)z/versions/(?P<version_long>.+)z(?:|z)?z
^projects/z	/secrets/$c                 ^    [        [        R                  " [        R                  U 5      5      $ r$   )boolresearchr.   _REMOTE_SECRET_FLAG_VALUE)secret_names    r   r/   ReachableSecret.IsRemotePath   s#    
		/;;[I r   c                    X l         X0l        U(       d  [        R                  " 5       (       a  [        R
                  " U R                  U5      nU(       az  UR                  S5      U l        UR                  S5      U l	        UR                  S5      U l
        U R                  c  UR                  S5      U l
        U R                  c  SU l
        gU R                  X5        g)a  Parse flag value to make a ReachableSecret.

Args:
  flag_value: str. A secret identifier like 'sec1:latest'. See tests for
    other supported formats (which vary by platform).
  connector_name: Union[str, PATH_OR_ENV].  An env var ('ENV1') or a mount
    point ('/a/b') for use in error messages. Also used in validation since
    you can only use MOUNT_ALL mode with a mount path.
  force_managed: bool. If True, always use the behavior of managed Cloud Run
    even if the platform is set to gke. Used by Cloud Run local development.
projectsecretversion_shortNversion_longlatest)
_connectorr+   r	   	IsManagedrc   rd   re   groupremote_project_numberrf   secret_version_InitWithLocalSecret)self
flag_valueconnector_namer+   matchs        r   __init__ReachableSecret.__init__   s     %O&	++--ii66
Ce	%*[[%;" ;;x0#kk/:& %N ;$
& ($
j9r   c                 "   SU l         UR                  S5      n[        U5      S:X  a   Uu  U l        U R	                  U5      U l        O-[        U5      S:X  a  Uu  U l        U l        O[        SU-  5      eU R                  U R                  5        g)aH  Init this ReachableSecret for a simple, non-remote secret.

Args:
  flag_value: str. A secret identifier like 'sec1:latest'. See tests for
    other supported formats.
  connector_name: Union[str, PATH_OR_ENV]. An env var, a mount point, or
    PATH_OR_ENV. See __init__ docs.

Raises:
  ValueError on flag value parse failure.
Nr*         zInvalid secret spec %r)rq   r,   lenrf   _OmittedSecretKeyDefaultrr   r-   _AssertValidLocalSecretName)rt   ru   rv   partss       r   rs   $ReachableSecret._InitWithLocalSecret   s     "&DS!E
5zQ!t 99.Id	Uq.3+d+/*<==$$T%5%56r   c                     U R                   nU R                   [        R                  :X  a  UR                  nU R                  b  SU R                  -  OSnSR                  UU R                  US9$ )Nzproject=%s r   zO<ReachableSecret {project_display}name={secret_name} version={version_display}>)project_displayrf   version_display)rr   r   r   rP   rq   formatrf   )rt   r   r   s      r   __repr__ReachableSecret.__repr__   s|    ))On666',,o %%1 	222 	% &,V+((+ &, &
		r   c                     U R                   UR                   :H  =(       a9    U R                  UR                  :H  =(       a    U R                  UR                  :H  $ r$   )rq   rf   rr   rt   others     r   __eq__ReachableSecret.__eq__  sM    ""e&A&AA 	8 1 11	85#7#77r   c                     X:X  + $ r$   r   r   s     r   __ne__ReachableSecret.__ne__	  s    r   c                    U R                   (       d  [        R                  " 5       (       a#  [        R                  " SR                  US95      eU R                  [        R                  L a  [        SU-  5      eU R                  R                  S5      (       d%  [        R                  " SR                  U5      5      e[        R                  $ )a  The key/version value to use for a secret flag that has no version.

Args:
  name: The env var or mount point, for use in an error message.

Returns:
  str value to use as the secret version.

Raises:
  ConfigurationError: If the key is required on this platform.
zZNo secret version specified for {name}. Use {name}:latest to reference the latest version.)rP   z0Can't determine default key for secret named %r./z1Missing required item key for the secret at [{}].)r+   r	   ro   r   ConfigurationErrorr   rn   r   r   	TypeError
startswithr   r   rt   rP   s     r   r~   (ReachableSecret._OmittedSecretKeyDefault  s     Y0022))??Ev4v?P 
 
,88	8>E
 	
 __'',,++?FFtL
 	
 '''r   c                     [         R                  " SU R                  -   S-   U5      (       d  [        R                  " SU-  5      eg )N^r`   z%r is not a valid secret name.)rc   rd   _SECRET_NAME_PARTIALr   r   r   s     r   r   +ReachableSecret._AssertValidLocalSecretName+  sD    99TD555<dCC))
*T
1  Dr   c                    U R                   [        R                  L a  [        SU R                  -  5      eU R                   R                  S5      (       d  [        SU R                   -  5      eU R                   R                  SS5      S   $ )z'Last path component of self._connector.zECan't make SecretVolumeSource message for secret %r of unknown usage.r   zICan't make SecretVolumeSource message for secret connected to env var %r.r{   )rn   r   r   r   rf   r   rsplitrt   s    r   	_PathTailReachableSecret._PathTail1  s    *666 
 ??%%c**OO 
 ??!!#q)"--r   c                     U R                   S L$ r$   )rq   r   s    r   	_IsRemoteReachableSecret._IsRemoteA  s    %%T11r   c                 L   U R                  5       (       d  U R                  $ [        U5      n[        U5      nUR	                  5        H  u  pEX:X  d  M  Us  $    U R                  SS S-   [        [        R                  " 5       5      -   nXU'   [        U[        U5      5        U$ )aJ  What do we call this secret within this resource?

Note that there might be an existing alias to the same secret, which we'd
like to reuse. There's no effort to deduplicate the ReachableSecret python
objects; you just get the same alias from more than one of them.

The k8s_object annotation is edited here to include all new aliases. Use
PruneAnnotation to clean up unused ones.

Args:
  resource: k8s_object resource that will be modified if we need to add a
    new alias to the secrets annotation.

Returns:
  str for use as SecretVolumeSource.secret_name or SecretKeySelector.name
N   -)
r   rf   r"   r5   r@   struuiduuid1r'   rA   )rt   r!   r0   remotesr:   other_rs	new_aliass          r   _GetOrCreateAlias!ReachableSecret._GetOrCreateAliasD  s    " >>0:23G"==?		 +   !$s*S->>II($5g$>?r   c                     U R                  5       (       d  [        S5      eSR                  U R                  U R                  S9$ )zRender a secret path for the run.googleapis.com/secrets annotation.

Returns:
  str like 'projects/123/secrets/s1'

Raises:
  TypeError for a local secret name that doesn't belong in the annotation.
z#Only remote paths go in annotationsz6projects/{remote_project_number}/secrets/{secret_name})rq   rf   )r   r   r   rq   rf   r   s    r   r8   $ReachableSecret.FormatAnnotationItemc  sH     >>;<<CJJ"88$$ K  r   c                 z    [         R                  " 5       (       a  U R                  U5      $ U R                  U5      $ )zBuild message for adding to resource.template.volumes.secrets.

Args:
  resource: k8s_object that may get modified with new aliases.

Returns:
  messages.SecretVolumeSource
)r	   ro   !_AsSecretVolumeSource_ManagedMode$_AsSecretVolumeSource_NonManagedMode)rt   r!   s     r   AsSecretVolumeSource$ReachableSecret.AsSecretVolumeSources  s5     33H==66x@@r   c                     UR                  5       nUR                  U R                  5       U R                  S9nUR                  R                  U5        g )N)pathkey)MessagesModule	KeyToPathr   rr   r@   append)rt   r!   outmessagesitems        r   AppendToSecretVolumeSource*ReachableSecret.AppendToSecretVolumeSource  sD    &&(H4>>#39L9LMDIITr   c                     UR                  5       nUR                  U R                  U5      S9nU R                  X5        U$ )NrJ   )r   SecretVolumeSourcer   r   rt   r!   r   r   s       r   r   1ReachableSecret._AsSecretVolumeSource_ManagedMode  sH    &&(H

%
%))(3 & C 	##H2Jr   c                    UR                  5       nUR                  U R                  U5      S9nU R                  [        R
                  :w  a=  UR                  R                  UR                  U R                  U R                  S95        U$ )NrJ   )r   r   )	r   r   r   rr   r   r   r@   r   r   r   s       r   r   4ReachableSecret._AsSecretVolumeSource_NonManagedMode  s    &&(H

%
%))(3 & C n666	ii


!4!44;N;N

O Jr   c                     UR                  5       nUR                  U R                  U5      U R                  S9nUR	                  US9$ )zBuild message for adding to resource.template.env_vars.secrets.

Args:
  resource: k8s_object that may get modified with new aliases.

Returns:
  messages.EnvVarSource
)rP   r   )rO   )r   SecretKeySelectorr   rr   EnvVarSource)rt   r!   r   selectors       r   AsEnvVarSourceReachableSecret.AsEnvVarSource  sS     &&(H))##H-43F3F * H   h 77r   )rn   r+   rq   rf   rr   NF)r   r   r   r   r   _PROJECT_NUMBER_PARTIALr   _REMOTE_SECRET_VERSION_SHORT_REMOTE_SECRET_VERSION_LONG_REMOTE_SECRET_VERSIONre   staticmethodr/   rx   rs   r   r   r   r~   r   r   r   r   r8   r   r   r   r   r   r   r   r   r   r.   r.      s     8<!: A$% 	$$ 		    	 		
 	   
:<7.,(>. 2> A
	8r   r.   r   )r   
__future__r   r   r   r   enumrQ   rc   r   googlecloudsdk.api_lib.runr   googlecloudsdk.command_lib.runr   r	   Enumr   r   r"   r'   r5   rA   rW   r\   objectr.   r   r   r   <module>r      sx    L &  % '   	  9 5 4TYY 	tyy 	60>$U8f U8r   