
    )                         S r SSKJr  SSKJr  SSKJ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
rSS jrS rS rS rS rS rS rS rS rg)z0Common utilities and shared helpers for secrets.    )absolute_import)division)unicode_literalsN)
exceptions)yaml)
console_io)filesi   c                 @   U (       d  gU=(       d    [         n [        R                  " XS9n[        U5      U:  a#  [        R
                  " SR                  XS95      eU$ ! [        R                   a(  n[        R
                  " SR                  XS95      eSnAff = f)a  Read data from the given file path or from stdin.

This is similar to the cloudsdk built in ReadFromFileOrStdin, except that it
limits the total size of the file and it returns None if given a None path.
This makes the API in command surfaces a bit cleaner.

Args:
    path (str): path to the file on disk or "-" for stdin
    max_bytes (int): maximum number of bytes
    is_binary (bool): if true, data will be read as binary

Returns:
    result (str): result of reading the file
N)binaryzGThe file [{path}] is larger than the maximum size of {max_bytes} bytes.)path	max_bytesz!Failed to read file [{path}]: {e}r   e)	DEFAULT_MAX_BYTESr   ReadFromFileOrStdinlenr   BadFileExceptionformatr	   Error)r   r   	is_binarydatar   s        .lib/googlecloudsdk/command_lib/secrets/util.pyReadFileOrStdinr      s     
,,)	D))$AD
4y9''6t69; ; K	 D

%
%+222BD DDs   AA! !B5#BBc                     U (       d  g [         R                  " XSS9  g! [         R                   a(  n[        R                  " SR                  XS95      eSnAff = f)zWrites the given binary contents to the file at given path.

Args:
    path (str): The file path to write to.
    content (str): The byte string to write.

Raises:
    Error: If the file cannot be written.
NT)privatez"Unable to write file [{path}]: {e}r   )r	   WriteBinaryFileContentsr   r   r   r   )r   contentr   s      r   WriteBinaryFiler   ?   s\     
E	!!$>	 E

%
%,333CE EEs     A#AAc                    SU ;  d
  U S   (       d  [         R                  " S5      e/ n/ nU S    H  nSU;  a  [         R                  " S5      eUR                  US   5        SU;   a7  SUS   ;   a  UR                  US   S   5        O[         R                  " S5      eU(       d  My  [        U5      [        U5      :w  d  M  [         R                  " S5      e   S	X!4$ )
a>  "Reads user managed replication policy file and returns its data.

Args:
    user_managed_policy (str): The json user managed message

Returns:
    result (str): "user-managed"
    locations (list): Locations that are part of the user-managed replication
    keys (list): list of kms keys to be used for each replica.
replicasz3Failed to find any replicas in user_managed policy.locationz*Failed to find a location in all replicas.customerManagedEncryption
kmsKeyNamezZFailed to find a kmsKeyName in customerManagedEncryption for replica at least one replica.zOnly some replicas have customerManagedEncryption. Please either add the missing field to the remaining replicas or remove it from all replicas.zuser-managed)r   r   appendr   )user_managed_policykeys	locationsreplicas       r   _ParseUserManagedPolicyr)   S   s     **2E3

%
%=? ?	$)$Z0g ''
68 8WZ()"g-	!<=	=G78FG)),- 	- tD	S^+''  1" 
	((    c                     U (       d  S/ / 4$ SU ;  a  [         R                  " S5      eU S   nSU;  a  [         R                  " S5      eS/ US   /4$ )a  "Reads automatic replication policy file and returns its data.

Args:
    automatic_policy (str): The json user managed message

Returns:
    result (str): "automatic"
    locations (list): empty list
    keys (list): 0 or 1 KMS keys depending on whether the policy has CMEK
	automaticr"   znFailed to parse replication policy. Expected automatic to contain either nothing or customerManagedEncryption.r#   z9Failed to find a kmsKeyName in customerManagedEncryption.)r   r   )automatic_policycmeks     r   _ParseAutomaticPolicyr/   x   sw     
B (88

%
%	78 8 
5	6$

%
%CE E	b4-.	..r*   c                 ~    SU ;   a  [        U S   5      $ SU ;   a  [        U S   5      $ [        R                  " S5      e)z9Reads replication policy dictionary and returns its data.userManagedr,   zWExpected to find either "userManaged" or "automatic" in replication, but found neither.)r)   r/   r   r   )replication_policys    r   _ParseReplicationDictr3      sN    (("#5m#DEE&& !3K!@AA##	 r*   c                     [         R                  " U 5      n[        U5      $ ! [         a     Of = f [        R
                  " U 5      n[        U5      $ ! [        R                   a    [        R                  " S5      ef = f)a  Reads replication policy file contents and returns its data.

Reads the contents of a json or yaml replication policy file which conforms to
https://cloud.google.com/secret-manager/docs/reference/rest/v1/projects.secrets#replication
and returns data needed to create a Secret with that policy. If the file
doesn't conform to the expected format, a BadFileException is raised.

For Secrets with an automtic policy, locations is empty and keys has
either 0 or 1 entry depending on whether the policy includes CMEK. For Secrets
with a user managed policy, the number of keys returns is either 0 or is equal
to the number of locations returned with the Nth key corresponding to the Nth
location.

Args:
    file_contents (str): The unvalidated contents fo the replication file.

Returns:
    result (str): Either "user-managed" or "automatic".
    locations (list): Locations that are part of the user-managed replication
    keys (list): list of kms keys to be used for each replica.
z8Failed to parse replication policy file as json or yaml.)	jsonloadsr3   
ValueErrorr   loadYAMLParseErrorr   r   )file_contentsr2   s     r   ParseReplicationFileContentsr;      s    ,	M2 !344	 		D=1 !344			 D

%
%BD DDs    # 
00 A +B c                 J   U R                  S5      (       a  / $ [        5       nU H  nUR                  UR                  5        M      U R                  S5      (       a^  U R                   H  nUR                  U5        M     / nU H0  nUR                  U;   d  M  UR                  UR                  5        M2     U$ U R                  S5      (       aS  / nU H  nUR                  UR                  5        M      U R                   H  nXB;  d  M
  UR                  U5        M     U$ g)a@  Applies updates to the list of topics on a secret.

Preserves the original order of topics.

Args:
  args (argparse.Namespace): The collection of user-provided arguments.
  original_topics (list): Topics configured on the secret prior to update.

Returns:
    result (list): List of strings of topic names after update.
clear_topicsremove_topics
add_topicsN)IsSpecifiedsetaddnamer>   discardr$   r?   )argsoriginal_topics
topics_settopic
topic_name
new_topicss         r   ApplyTopicsUpdaterK      s    
n%%Iu*eNN5::  
o&&((
$ )J 	z	!%**% ! 	l##J 

# !oo
		%*% &  $r*   c                    U R                  S5      (       a  0 $ [        5       nUR                  U Vs0 s H  o3R                  UR                  _M     sn5        U R                  S5      (       aT  U R
                   H  nX$	 M     [        5       nU H-  nUR                  U;   d  M  UR                  XVR                  '   M/     U$ U R                  S5      (       a  [        5       nUR                  U Vs0 s H  o3R                  UR                  _M     sn5        UR                  U R                  R                  5        VVs0 s H  u  pGXG_M	     snn5        U$ gs  snf s  snf s  snnf )ak  Applies updates to the list of version-aliases on a secret.

Makes no alterations to the original version aliases

Args:
  args (argparse.Namespace): The collection of user-provided arguments.
  original_version_aliases (list): version-aliases configured on the secret
    prior to update.

Returns:
    result (dict): dict of version_aliases pairs after update.
clear_version_aliasesremove_version_aliasesupdate_version_aliasesN)r@   dictupdatekeyvaluerN   rO   items)rE   original_version_aliasesversion_aliases_dictpairaliasnew_version_aliasesversion_alias_pairversions           r   ApplyAliasUpdater\      s[    
-..I(@A(@xx(@AC	.//,,

% -&6			#7	76H6N6N223 7 011&*BC*B$4::	*BCE $ ; ; A A C  CU 	 C    2 B 	D     E2 EE$
c                    U R                  S5      (       a  0 $ [        5       nUR                  U Vs0 s H  o3R                  UR                  _M     sn5        U R                  S5      (       aT  U R
                   H  nX$	 M     [        5       nU H-  nUR                  U;   d  M  UR                  XVR                  '   M/     U$ U R                  S5      (       a  [        5       nUR                  U Vs0 s H  o3R                  UR                  _M     sn5        UR                  U R                  R                  5        VVs0 s H  u  pGXG_M	     snn5        U$ gs  snf s  snf s  snnf )aW  Applies updates to the list of annotations on a secret.

Makes no alterations to the original annotations

Args:
  args (argparse.Namespace): The collection of user-provided arguments.
  original_annotations (list): annotations configured on the secret prior to
    update.

Returns:
    result (dict): dict of annotations pairs after update.
clear_annotationsremove_annotationsupdate_annotationsN)r@   rP   rQ   rR   rS   r`   ra   rT   )rE   original_annotationsannotations_dictrW   
annotationnew_annotationsannotation_pairmetadatas           r   ApplyAnnotationsUpdaterh     sV    
)**IV(<=(<xx(<=?	*++--


& .fO/			 0	0/>/D/D++, 0 ,--fO*>?*>$4::	*>?A&*&=&=&C&C&E&E"Z 	&E   . > 	@r]   )NT)__doc__
__future__r   r   r   r5   googlecloudsdk.callioper   googlecloudsdk.corer   googlecloudsdk.core.consoler   googlecloudsdk.core.utilr	   r   r   r   r)   r/   r3   r;   rK   r\   rh    r*   r   <module>rp      s]    7 &  '  . $ 2 * D@E(")J/0!DH#L$N$r*   