
    1                     L   d Z ddlmZ ddlmZ ddlmZ ddlZddlZddlZddlZddl	Z	ddl
mZ ddl
mZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddZddZ	 	 ddZd Zd Zd Zd Zd ZddZ  G d dejB                        Z!d Z"d Z#d Z$d Z%d dZ&y)!z7Common utilities for the gcloud export/import commands.    )absolute_import)division)unicode_literalsN)message_types)messages)encoding)encoding_helper)
exceptions)log)yaml)yaml_validatorc                     d}||dj                  |      z  }| j                  dt        j                  |      d       y)zAdd common export flags to the arg parser.

  Args:
    parser: The argparse parser object.
    schema_path: The resource instance schema file path if there is one.
  zPath to a YAML file where the configuration will be exported.
          Alternatively, you may omit this flag to write to standard output.NzL For a schema describing the export/import format, see:
          {}.
      z--destinationFhelprequiredformatadd_argumenttextwrapdedentparserschema_path	help_texts      -lib/googlecloudsdk/command_lib/export/util.pyAddExportFlagsr   '   sP    P) 

&
I 	??9%	      c                     d}||dj                  |      z  }d|v r|dz  }| j                  dt        j                  |      d       y)	zAdd common import flags to the arg parser.

  Args:
    parser: The argparse parser object.
    schema_path: The resource instance schema file path if there is one.
  zPath to a YAML file containing configuration export data.
          Alternatively, you may omit this flag to read from standard input.NzKFor a schema describing the export/import format, see:
          {}.
      $CLOUDSDKROOTz\

      Note: $CLOUDSDKROOT represents the Google Cloud CLI's installation directory.
      z--sourceFr   r   r   s      r   AddImportFlagsr    <   si    P) 

&
I +% 
 
i
 	??9%	  r   c                 4   t         j                  j                  t         j                  j                  t         j                  j                  t         j                  j                  t	        j
                  t                                d| |dj                  |            }|ru|j                  t         j                  j                  dz   t         j                  j                  z         }|dk  r|S t         j                  j                  dd||dz   d       }|S )	a^  Returns the schema installation path.

  $CLOUDSDKROOT/lib/googlecloudsdk/schemas/
    {api}/{api_version}/{message_name}.yaml

  Args:
    api_name: The api name.
    api_version: The API version string.
    message_name: The UpperCamelCase message name.
    for_help: Replaces the actual Cloud SDK installation root dir with
      $CLOUDSDKROOT.
  schemasz{}.yamlgooglecloudsdkr   r   lib   N)
ospathjoindirnamer   Decode__file__r   rfindsep)api_nameapi_versionmessage_namefor_helpr'   rel_path_indexs         r   GetSchemaPathr3   W   s     
ggoobggoobggoo
//(
#'% & '|$
$ ZZ.> > LMNk77<<^a5G5H0IJD	+r   c                 L    t        j                  |      j                  |        y)aQ  Validates YAML against JSON schema.

  Args:
    parsed_yaml: YAML to validate
    schema_path: JSON schema file path.

  Raises:
    IOError: if schema not found in installed resources.
    files.Error: if schema file not found.
    ValidationError: if the template doesn't obey the schema.
    SchemaError: if the schema is invalid.
  N)r   	ValidatorValidate)parsed_yamlr   s     r   ValidateYAMLr8   u   s     ;'00=r   c                 N    t        d t        j                  d|       D              S )a/  Parses disallowed properties from an error message.

  Args:
    error_message: The error message to parse.

  Returns:
    A list of property names.

  A sample error message might look like this:

  Additional properties are not allowed ('id', 'createTime', 'updateTime',
  'name' were unexpected)

  c              3   >   K   | ]  }|j                  d         yw)'N)strip).0propertys     r   	<genexpr>z#_ParseProperties.<locals>.<genexpr>   s      Q+OxhnnT+Os   z'[^']*')listrefindall)error_messages    r   _ParsePropertiesrD      s-     
 Q+-::i+OQ 
Q Qr   c                 >    |}|D ]  }||   }	 | D ]
  }||v s||=  y)zClear the given fields in a dict at a given path.

  Args:
    fields: A list of fields to clear
    path_deque: A deque containing path segments
    py_dict: A nested dict from which to clear the fields
  N )fields
path_dequepy_dicttmp_dictelemfields         r   _ClearFieldsrM      s5     (d~H e
5/ r   c                 H    d}d}| j                   |k(  xr || j                  v S )zChecks if an error is due to properties that were not in the schema.

  Args:
    error: A ValidationError

  Returns:
    Whether the error was due to disallowed properties
  additionalPropertiesz%Additional properties are not allowed)	validatormessage)errorprop_validatorprop_messages      r   _IsDisallowedPropertiesErrorrU      s+     *.8,	N	*	L|u}}/LLr   c                 <   d}t        j                  |      j                  |       D ]s  }t        |      r-t	        |j
                        }t        ||j                  |        n!t        j                  |j
                         d}|s_t        j                  d       u y)zFilter out fields from the yaml that are not in the schema.

  Args:
    parsed_yaml: yaml to filter
    schema_path: Path to schema.
  FTzDThe import command may need to be updated to handle the export data.N)
r   r5   IteraterU   rD   rQ   rM   r'   r   warning)r7   r   has_warningsrR   fields_to_removes        r   _FilterYAMLr[      s}     ,''4<<[Ie $E*)%--8#UZZ=	kk%-- l	kk % &! Jr   c                    t        j                  |      }|r$t        j                  |      j	                  |       	 t        j                  | |      }|S # t        $ r)}t        j                  dj                  |            d}~ww xY w)a[  Reads YAML from a stream as a message.

  Args:
    message_type: Type of message to load YAML into.
    stream: Input stream or buffer containing the YAML.
    schema_path: JSON schema file path. None for no YAML validation.

  Raises:
    ParseError: if yaml could not be parsed as the given message type.

  Returns:
    message_type object.
  zCannot parse YAML: [{0}]N)r   loadr   r5   r6   api_encodingPyValueToMessage	Exceptionr
   
ParseErrorr   )message_typestreamr   r7   rQ   es         r   Importre      s~     		&!+[)22;?F++L+FG 
. 
 F


 : A A! D
EEFs   A 	B$BBc                   @     e Zd ZdZdZed        Z fdZ fdZ xZ	S )_ProtoJsonApiToolsz&JSON encoder used by apitools clients.Nc                 J    | j                    |        | _         | j                   S N)	_INSTANCE)clss    r   Getz_ProtoJsonApiTools.Get   s    
}}ecm==r   c                     t        |t        j                        rddj                   fd|D              z  S t	        |      t
        j                  v r+t
        j                  t	        |         j                  |      S t        |      }t        t
        j                   /  |      }t        ||      }t        j                  t        j                  |      d      S )Nz[%s]z, c              3   @   K   | ]  }j                  |        y wri   )encode_message)r=   xselfs     r   r?   z4_ProtoJsonApiTools.encode_message.<locals>.<genexpr>   s      IA!4!4Q!7s   T)	sort_keys)
isinstancer   	FieldListr(   typer	   _CUSTOM_MESSAGE_CODECSencoder_EncodeUnknownFieldssuperrg   ro   _EncodeCustomFieldNamesjsondumpsloads)rq   rQ   result	__class__s   `  r   ro   z!_ProtoJsonApiTools.encode_message   s    '8--.tyy I IIJJ G}>>>33DMBJJ
  #7+G?55((/0 $Wf5F::djj(D99r   c                    t        |d      D ]'  } |||      }|j                  }|j                  s%|c S  t        |t        j
                        r|j                  rG|D cg c];  }t        j                  |j                  |j                        xs |j                  = }}n+t        j                  |j                  |j                        }|r|S t        |t        j                        r>t        |t        j                        s$t        j                  | j!                  |            }t"        t        j$                  | O  ||      S c c}w )Nrw   )python_name)_GetFieldCodecsvaluecompleters   r   	EnumFieldrepeatedr	   GetCustomJsonEnumMappingru   nameMessageFieldr   DateTimeFieldr{   r}   ro   ry   rg   encode_field)rq   rL   r   rw   r~   rd   remapped_valuer   s          r   r   z_ProtoJsonApiTools.encode_field	  s!   "5)4ue$flle		 5
 %++,	 DI
CHa 44

0 :3466:CH 	 

 )AAJJEJJ0	5(//0um99:jj,,U34e33$$)512
s   "A E
)
__name__
__module____qualname____doc__rj   classmethodrl   ro   r   __classcell__)r   s   @r   rg   rg      s,    .) 
:2 2r   rg   c                 b    d }d }t        j                  ||      | t        j                  <   | S )z(Registers custom field codec for int64s.c                 4    t        j                  |d      }|S NT)r   r   r^   CodecResult)unused_fieldr   	int_values      r   _EncodeInt64Fieldz8RegisterCustomFieldTypeCodecs.<locals>._EncodeInt64Field#  s    ((utDIr   c                 0    t        j                  |d      S r   r   )r   r   s     r   _DecodeInt64Fieldz8RegisterCustomFieldTypeCodecs.<locals>._DecodeInt64Field'  s    ##%$??r   )rw   decoder)r	   _Codecr   IntegerField)field_type_codecsr   r   s      r   RegisterCustomFieldTypeCodecsr   !  s7    @ .=-C-C):.<H))*	r   c                 R   t        j                  t        j                        }t	        t        j                  t        j
                              }t        |j                  |       |d       t        |j                  t        |             |d       g}|D cg c]  }||	 c}S c c}w ri   )	copydeepcopyr	   _CUSTOM_FIELD_CODECSr   _FIELD_TYPE_CODECSgetattrgetru   )rL   attrcustom_field_codecsr   r~   rp   s         r   r   r   0  s    o&J&JK3
mmO6679 !%%e,dD9##DK0$=& 	-Vq}!V	--	-s   B$B$c                 :   t         j                  j                  t        |             }|| S t        j                  |       }| j                  |      }t        |t        j                        st        j                  d|z        |j                  }|j                  d      }|j                  }t        | |      }t        j                         }|D ];  }	|j!                  ||	j"                        }
|j%                  |	j&                  |
|       = t)        ||g        |S )z6Remap unknown fields in message out of message.source.zInvalid pairs field %sr   )r	   _UNRECOGNIZED_FIELD_MAPPINGSr   ru   !_CopyProtoMessageVanillaProtoJsonfield_by_namers   r   r   r
   InvalidUserInputErrorrb   variantr   rg   rl   r   r   set_unrecognized_fieldkeysetattr)rQ   sourcer~   pairs_field
pairs_typevalue_fieldvalue_variantpairscodecpairencoded_values              r   rx   rx   <  s    77;;DMJ&^N <<WE&%%f-+	K!6!6	7

*
*+C+6,7 8 8''*((1+%%-
'6
"%

 
 
"%d&&{DJJ?M
!!$((M=I  
&&"	-r   c                 $   t        t        j                  j                  t	        |       i       j                               }|rMt        j                  |      }|D ]  \  }}||v s|j                  |      ||<     t        j                  |      }|S ri   )
r@   r	   _JSON_FIELD_MAPPINGSr   ru   itemsr{   r}   popr|   )rQ   r   field_remappingsdecoded_valuer   	json_names         r   rz   rz   T  s    **..tG}bAGGIKJJ}-M"2Y		%#0#4#4[#Ai  #3 JJ}-M	r   c                     t         j                         j                  |       }t        j                  t        j                  || d            }|rt        ||       t        j                  ||      S )a  Writes a message as YAML to a stream.

  Args:
    message: Message to write.
    stream: Output stream, None for writing to a string and returning it.
    schema_path: JSON schema file path. If None then all message fields are
      written, otherwise only fields in the schema are written.

  Returns:
    Returns the return value of yaml.dump(). If stream is None then the return
    value is the YAML data as a string.
  N)rc   )
rg   rl   ro   r{   r}   r	   _IncludeFieldsr[   r   dump)rQ   rc   r   r~   message_dicts        r   Exportr   `  s[     !!#227;&$$VWd;=,k*	<	//r   ri   )v1NF)NN)'r   
__future__r   r   r   r   r{   r&   rA   r   apitools.base.protorpcliter   r   apitools.base.pyr   r^   r	   googlecloudsdk.api_lib.dataprocr
   googlecloudsdk.corer   r   r   googlecloudsdk.core.utilr   r    r3   r8   rD   rM   rU   r[   re   rg   r   r   rx   rz   r   rF   r   r   <module>r      s     > &  '   	 	  4 / 5 , 6 # $ . -*6 <@ <> Q& M&8<.2;; .2b	.0	0r   