
    ]'                         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S	KJr  SS
KJr  SSKr " S S\R$                  5      rS rS rS rS rSS jr   SS jrS r SS jrSS jrg)z0Convenience functions for dealing with metadata.    )absolute_import)division)unicode_literalsN)	constants)
exceptions)arg_parsers)log)filesc                       \ rS rSrSrSrg)InvalidSshKeyException!   z:InvalidSshKeyException is for invalid ssh keys in metadata N)__name__
__module____qualname____firstlineno____doc____static_attributes__r       4lib/googlecloudsdk/api_lib/compute/metadata_utils.pyr   r   !   s    Br   r   c                     U R                  5       nU(       a[  [        [        R                  " U5      5       H8  u  p4UR                  R                  U R                   R                  UUS95        M:     U$ )z/Converts a metadata dict to a Metadata message.)keyvalue)Metadatasortedsix	iteritemsitemsappendItemsValueListEntry)message_classesmetadata_dictmessager   r   s        r   _DictToMetadataMessager$   %   se    $$&'S]]=9:
mm?33GG H   ; 
.r   c                 n    0 nU (       a+  U R                    H  nUR                  XR                  '   M     U$ )z&Converts a Metadata message to a dict.)r   r   r   )metadata_messageresitems      r   _MetadataMessageToDictr)   0   s.    
# &&jjc((m '	*r   c                    U R                  [        R                  S5      nU R                  [        R                  S5      nSR	                  X45      nSU;   a  [        S5      eUR                  S5      n/ nU H/  nU(       d  M  [        U5      (       d  M  UR                  U5        M1     U(       a-  SnUR                  SR	                  U5      5      n[        U5      eg)a  Validates the ssh-key entries in metadata.

The ssh-key entry in metadata should start with <username> and it cannot
be a private key
(i.e. <username>:ssh-rsa <key-blob> <username>@<example.com> or
<username>:ssh-rsa <key-blob>
google-ssh {"userName": <username>@<example.com>, "expireOn": <date>}
when the key can expire.)

Args:
  metadata_dict: A dictionary object containing metadata.

Raises:
  InvalidSshKeyException: If the <username> at the front is missing or private
  key(s) are detected.
 
zPRIVATE KEYzHPrivate key(s) are detected. Note that only public keys should be added.zThe following key(s) are missing the <username> at the front
{}

Format ssh keys following https://cloud.google.com/compute/docs/instances/adding-removing-ssh-keysN)
getr   SSH_KEYS_METADATA_KEYSSH_KEYS_LEGACY_METADATA_KEYjoinr   split_SshKeyStartsWithKeyTyper   format)	r"   ssh_keysssh_keys_legacyssh_keys_combinedkeyskeys_missing_usernamer   r#   message_contents	            r   _ValidateSshKeysr:   9   s    $ y>>C(!%%i&L&L&(*/ii ;<''
 	  
	 	 	&$c
s',,""3'  4G
 nnTYY/D%EFO
 
11 r   c                 ~    [         R                   Vs/ s H  oR                  U5      PM     nn[        U5      $ s  snf )zChecks if the key starts with any key type in constants.SSH_KEY_TYPES.

Args:
  key: A ssh key in metadata.

Returns:
  True if the key starts with any key type in constants.SSH_KEY_TYPES, returns
  false otherwise.

)r   SSH_KEY_TYPES
startswithany)r   key_typekey_starts_with_typess      r   r2   r2   e   sA     09/F/F/F8nnX/F   
"	##s   :c                     U =(       d    0 n U=(       d    0 n[         R                  " U 5      n[        R                  " U5       HG  u  p4X2;   a%  [        R
                  " SR                  U5      5      e[        R                  " U5      X#'   MI     U$ )a  Returns the dict of metadata key:value pairs based on the given dicts.

Args:
  metadata: A dict mapping metadata keys to metadata values or None.
  metadata_from_file: A dict mapping metadata keys to file names containing
    the keys' values or None.

Raises:
  ToolException: If metadata and metadata_from_file contain duplicate
    keys or if there is a problem reading the contents of a file in
    metadata_from_file.

Returns:
  A dict of metadata key:value pairs.
z)Encountered duplicate metadata key [{0}].)	copydeepcopyr   r   compute_exceptionsDuplicateErrorr3   r
   ReadFileContents)metadatametadata_from_filenew_metadata_dictr   	file_paths        r   ConstructMetadataDictrK   v   s      ^()/RmmH-&89nc
--
5
<
<S
AC C"33I>	 :
 
r   c                    [        X5      n[        U5      nUR                  U5         [        U5        [        U U5      nU(       a  UR                  Ul        U$ ! [         a   n[
        R                  " U5         SnANKSnAff = f)ae  Creates a Metadata message from the given dicts of metadata.

Args:
  message_classes: An object containing API message classes.
  metadata: A dict mapping metadata keys to metadata values or None.
  metadata_from_file: A dict mapping metadata keys to file names containing
    the keys' values or None.
  existing_metadata: If not None, the given metadata values are combined with
    this Metadata message.

Raises:
  ToolException: If metadata and metadata_from_file contain duplicate
    keys or if there is a problem reading the contents of a file in
    metadata_from_file.

Returns:
  A Metadata protobuf.
N)	rK   r)   updater:   r   r	   warningr$   fingerprint)r!   rG   rH   existing_metadatarI   existing_metadata_dictenew_metadata_messages           r   ConstructMetadataMessagerT      s    , ,HI12CD 12+, 00FH '8'D'D$	 
  KKNNs   A 
B$A??Bc                 0    [        U 5      [        U5      :H  $ )zEReturns True if both metadata messages have the same key/value pairs.)r)   )	metadata1	metadata2s     r   MetadataEqualrX      s    			*.DY.O	OOr   c                     U(       a  U R                  5       nO8U(       a1  [        U5      nU H  nUR                  US5        M     [        X5      nUR                  Wl        U$ )a  Removes keys from existing_metadata.

Args:
  message_classes: An object containing API message classes.
  existing_metadata: The Metadata message to remove keys from.
  keys: The keys to remove. This can be None if remove_all is True.
  remove_all: If True, all entries from existing_metadata are
    removed.

Returns:
  A new Metadata message with entries removed and the same
    fingerprint as existing_metadata if existing_metadata contains
    a fingerprint.
N)r   r)   popr$   rO   )r!   rP   r7   
remove_allrS   rQ   r   s          r   RemoveEntriesr\      sd      *33534EF  d+ 11 &7%B%B"	r   c           	          SnU(       a  US-  nU R                  S[        R                  " SS90 US[        R                  S9  SnU(       a  US-  nU R                  S	[        R                  " SS90 US
S9  g)z/Adds --metadata and --metadata-from-file flags.aK        Metadata to be made available to the guest operating system
      running on the instances. Each metadata entry is a key/value
      pair separated by an equals sign. Each metadata key must be unique
      and have a max of 128 bytes in length. Each value must have a max of
      256 KB in length. Multiple arguments can be
      passed to this flag, e.g.,
      ``--metadata key-1=value-1,key-2=value-2,key-3=value-3''.
      The combined total size for all metadata entries is 512 KB.

      In images that have Compute Engine tools installed on them,
      such as the
      link:https://cloud.google.com/compute/docs/images[official images],
      the following metadata keys have special meanings:

      *startup-script*::: Specifies a script that will be executed
      by the instances once they start running. For convenience,
      ``--metadata-from-file'' can be used to pull the value from a
      file.

      *startup-script-url*::: Same as ``startup-script'' except that
      the script contents are pulled from a publicly-accessible
      location on the web.


      For startup scripts on Windows instances, the following metadata keys
      have special meanings:
      ``windows-startup-script-url'',
      ``windows-startup-script-cmd'', ``windows-startup-script-bat'',
      ``windows-startup-script-ps1'', ``sysprep-specialize-script-url'',
      ``sysprep-specialize-script-cmd'', ``sysprep-specialize-script-bat'',
      and ``sysprep-specialize-script-ps1''. For more information, see
      [Running startup scripts](https://cloud.google.com/compute/docs/startupscript).
      zR

      At least one of [--metadata] or [--metadata-from-file] is required.
      z
--metadata   )
min_lengthz	KEY=VALUE)typedefaulthelpmetavaractionz      Same as ``--metadata'' except that the value for the entry will
      be read from a local file. This is useful for values that are
      too large such as ``startup-script'' contents.
      z--metadata-from-filezKEY=LOCAL_FILE_PATH)r`   ra   rb   rc   N)add_argumentr   ArgDictStoreOnceAction)parserrequiredmetadata_helpmetadata_from_file_helps       r   AddMetadataArgsrl      s    !
-D  
 
M 	!,((  *

   
 
 	!,"#  %r   )NN)NNN)NF)F)r   
__future__r   r   r   rB   googlecloudsdk.api_lib.computer   r   googlecloudsdk.callioper   "googlecloudsdk.command_lib.computerD   googlecloudsdk.corer	   googlecloudsdk.core.utilr
   r   Errorr   r$   r)   r:   r2   rK   rT   rX   r\   rl   r   r   r   <module>rt      s    7 &  '  4 5 / O # * 
CZ-- C)2X$": '+04/3%PP ).<>%r   