
    &+              
         S 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\#\RH                  S9r% " S S\%5      r& " S S\%5      r'\&" / 5      \&" S/5      \&" / 5      \&" S/5      \&" SS/5      \'" 5       \&" SS/5      S.r(S)S jr) S*     S+S  jjr*S,S! jr+ S*     S-S" jjr,S.S# jr-  S/       S0S$ jjr.S1S% jr/        S2S& jr0    S3S' jr1 S*       S4S( jjr2g)5z4Version-agnostic utilities for function source code.    )annotationsN)Dict)
exceptions)http_wrapper)transfer)util)storage_api)storage_util)gcloudignore)log)	resources)
transports)archive)filesc                  @    \ rS rSrSr\R                  SS j5       rSrg)RequiredFilesStrategy2   z;Abstract base class for required files validation strategy.c                    [        5       eN)NotImplementedErrorselffiles_in_source_dirruntimes      7lib/googlecloudsdk/command_lib/functions/source_util.pyValidateRequiredFilesStrategy.Validate5   s    

     Nr   	list[str]r   strreturnNone)	__name__
__module____qualname____firstlineno____doc__abcabstractmethodr   __static_attributes__r   r   r   r   r   2   s    C   r   r   )	metaclassc                  :   ^  \ rS rSrSrSU 4S jjrSS jrSrU =r$ )AllFilesPresentStrategy:   z9Strategy that requires all specified files to be present.c                6   > [         [        U ]  5         Xl        g r   )superr/   __init___required_files)r   required_files	__class__s     r   r3    AllFilesPresentStrategy.__init__=   s    	
!413)r   c                n    U R                    H%  nX1;  d  M
  [        R                  " SU SU S35      e   g )Nz.Provided source directory does not have file [z] which is required for [$]. Did you specify the right source?)r4   r   SourceArgumentError)r   r   r   fs       r   r    AllFilesPresentStrategy.ValidateA   sF    !!	
	%,,<QC @$I%IK
 	
 "r   )r4   )r5   r!   r    )	r%   r&   r'   r(   r)   r3   r   r,   __classcell__)r6   s   @r   r/   r/   :   s    A*
 
r   r/   c                  "    \ rS rSrSrSS jrSrg)PythonRequiredFilesStrategyJ   z6Strategy for Python runtime required files validation.c                    SU;  a  [         R                  " SU S35      eSU;  a!  SU;  a  [         R                  " SU S35      eg g )Nzmain.pyzNProvided source directory does not have file [main.py] which is required for [r9   zrequirements.txtzpyproject.tomlziProvided source directory does not have file [requirements.txt or pyproject.toml] which is required for [)r   r:   r   s      r   r   $PythonRequiredFilesStrategy.ValidateM   sv    ++**")#GI 
 	"55$77**44;9 =&&  8 	6r   r   Nr    )r%   r&   r'   r(   r)   r   r,   r   r   r   r?   r?   J   s
    >r   r?   zgo.modzpackage.jsonz	index.phpzcomposer.jsonzapp.rbGemfile)dotnetgojavanodejsphppythonrubyc                T    [         R                  " U [         R                  S/-   5      $ )Nnode_modules)r   AnyFileOrDirExists	GIT_FILES	directorys    r   _GcloudIgnoreCreationPredicaterQ   i   s(    		(	(''>*::
 r   c                ^    [         R                  S-   n[         R                  " U U[        US9$ )Nz
node_modules
)default_ignore_file gcloud_ignore_creation_predicateignore_file)r   DEFAULT_IGNORE_FILEGetFileChooserForDirrQ   )pathrU   rS   s      r   _GetChooserrY   o   s5     %88;MM		*	*
-'E	
 r   c                    [         R                  R                  U 5      (       d  [        R                  " S5      e[         R                  R                  U 5      (       d  [        R                  " S5      eg)zValidates that the given directory exists.

Args:
  directory: a local path to the directory provided by user.

Returns:
  The argument provided, if found valid.
Raises:
  SourceArgumentError: If the user provided an invalid directory.
z!Provided directory does not existz+Provided path does not point to a directoryN)osrX   existsr   r:   isdirrO   s    r   _ValidateDirectoryExistsOrRaiser^   |   sW     
		"	"

(
()L
MM	y	!	!

(
(5  
"r   c                <   [        X5      nUR                  n [        R                  " XS9nSnUS-  nXG:  a/  [
        R                  " [        U5      S-   [        U5      S-   5      eg! [         a(  n[
        R                  " SR                  XS95      eSnAff = f)z'Validate size of unpacked source files.	predicatezError building source archive from path [{path}]. Could not validate source files: [{error}]. Please ensure that path [{path}] contains function code or specify another directory with --source)rX   errorNi   i   B)
rY   
IsIncluded
file_utilsGetTreeSizeBytesOSErrorr   FunctionsErrorformatOversizedDeploymentErrorr"   )rX   rU   chooserra   size_besize_limit_mbsize_limit_bs           r   _ValidateUnpackedSourceSizerp      s     *'  )((CF -&,

-
-Fc3|,s2   
 

#
#	2 39&d&2L	 s   A) )
B3#BBc                    [        U 5        [        R                  " SSU5      n[        R                  " U 5      n[
        R                  U5      nU(       a  UR                  X15        gg)zDValidates the given source directory has the required runtime files.z[0-9] N)r^   resubr[   listdir_REQUIRED_SOURCE_STRATEGIESgetr   )sourcer   versionless_runtimer   strategys        r   (ValidateDirectoryHasRequiredRuntimeFilesr{      sT    !&)xW5

6*(,,-@A()3 r   c           	     6   [        U5        U(       af  [        R                  R                  [        R                  R	                  X5      5      (       d%  [
        R                  " SR                  U5      5      eU(       a  [        X5        [        R                  R	                  U S5      n [        X5      nUR                  n[        R                  " XAUS9  U$ ! [         a4  n[
        R                  " SR                  U[        U5      5      5      eSnAff = f)a  Prepare zip file with source of the function to upload.

Args:
  zip_dir: str, directory in which zip file will be located. Name of the file
    will be `fun.zip`.
  source_path: str, directory containing the sources to be zipped.
  ignore_file: custom ignore_file name. Override .gcloudignore file to
    customize files to be skipped.
  enforce_size_limit: if set, enforces that the unpacked source size is less
    than or equal to 512 MB.

Returns:
  Path to the zip file.
Raises:
  FunctionsError
z4File {0} referenced by --ignore-file does not exist.zfun.zipr`   zHError creating a ZIP archive with the source code for directory {0}: {1}N)r^   r[   rX   r\   joinr   IgnoreFileNotFoundErrorri   rp   rY   rd   r   MakeZipFromDir
ValueErrorrh   r"   )zip_dirsource_pathrU   enforce_size_limitzip_file_namerk   ra   rm   s           r   CreateSourcesZipFiler      s    , "+.[(NOO

,
,>EE	
 
 9'',,w	2-+3G""I=K 
 
 

#
#	!!'SV!< s   ,,C 
D$/DDc                    U R                   nU R                  nSR                  S [        S5       5       5      nSR	                  XU5      $ )Nrr   c              3  j   #    U  H)  n[         R                  " [        R                  5      v   M+     g 7fr   )randomchoicestringascii_lowercase).0_s     r   	<genexpr>-_GenerateRemoteZipFileName.<locals>.<genexpr>   s"     L)Q6==!7!788)s   13   z{0}-{1}-{2}.zip)locationsIdfunctionsIdr}   rangeri   )function_refregionnamesuffixs       r   _GenerateRemoteZipFileNamer      sC    ##&		!	!$77L%)LL&		!	!&	77r   c                \   [        U5      n[        R                  R                  U5      n[        R                  R                  XC5      n [        R                  " 5       R                  X5        U$ ! [        R                   a&    [        R                  " SR                  U5      5      ef = f)a0  Uploads the given source ZIP file to the provided staging bucket.

Args:
  source_zip: the source ZIP file to upload.
  function_ref: the function resource reference.
  stage_bucket: the name of GCS bucket to stage the files to.

Returns:
  dest_object: a reference to the uploaded Cloud Storage object.
z;Failed to upload the function source code to the bucket {0})r   r
   BucketReferenceFromArgumentObjectReferenceFromBucketRefr	   StorageClientCopyFileToGCScalliope_exceptionsBadFileExceptionr   SourceUploadErrorri   )
source_zipr   stage_bucketzip_file
bucket_refdest_objects         r   UploadToStageBucketr      s     (5(++88F*,,:::P+--jF 
 
	-	- 

&
&ELL	
 s   $A1 1:B+c                    U R                   [        R                  R                  :X  a  [        R
                  R                  U 5      e[        R                  " U 5      $ r   )	status_codehttp
HTTPStatus	FORBIDDENhttp_exceptionsHttpForbiddenErrorFromResponser   CheckResponse)responses    r   &_UploadFileToGeneratedUrlCheckResponser      sD     T__666

,
,
9
9(
CC		#	#H	--r   c                V  ^ U=(       d    0 n[         R                  R                  U SS9mSU4S jjn [        R                  " USSS0UES9nTR
                  R                  5       Ul        [        R                  " [        R                  " 5       UU[        TR                  S9nTR
                  R                  5         UR                  S-  S	:w  a8  [        R                   " S
R#                  XR                  UR$                  S95      eg! TR
                  R                  5         f = f)zUpload the given source ZIP file to provided generated URL.

Args:
  source_zip: the source ZIP file to upload.
  url: the signed Cloud Storage URL to upload to.
  extra_headers: extra headers to attach to the request.
zapplication/zip)	mime_typec                b  > [        U R                  [        R                  5      (       at  [        R
                  " S5        [        R                  " U R                  5        [        R                  " [        R                  " U R                  U R                  S95        g TR                  U 5        g )Nz5Caught delayed permission propagation error, retrying)max_wait)
isinstanceexcr   r   r   debugr   RebuildHttpConnectionsr   timesleep	http_utilCalculateWaitForRetrynum_retriesmax_retry_wait
retry_func)
retry_argsuploads    r   _UploadRetryFunc.UploadToGeneratedUrl.<locals>._UploadRetryFunc  st    *../"D"DEE	iiGH))*//:
jj

)
)$$z/H/H 
#r   PUTzcontent-type)http_methodheaders)r   check_response_funcretriesd      zYFailed to upload the function source code to signed url: {url}. Status: [{code}:{detail}])urlcodedetailN)r   zhttp_wrapper.ExceptionRetryArgsr#   r$   )r   UploadFromFiler   RequeststreamreadbodyMakeRequestr   GetApitoolsTransportr   r   closer   r   r   ri   content)r   r   extra_headersr   upload_requestr   r   s         @r   UploadToGeneratedUrlr     s     %2-??##J:K#L&
$!))!2DmDN
 !--,,.N'''')#B""H MMS A%

&
&	$$*F..x7G7G %+ %
  & MMs   A2D D()rP   r"   r#   boolr   )rX   r"   rU   
str | Noner#   zgcloudignore.FileChooser)rP   r"   r#   r$   )rX   r"   rU   r   r#   r$   )rx   r"   r   r"   r#   r$   )NF)r   r"   r   r"   rU   r   r#   r"   )r   resources.Resourcer#   r"   )r   r"   r   r   r   r"   r#   zstorage_util.ObjectReference)r   zhttp_wrapper.Responser#   zhttp_wrapper.CheckResponse)r   r"   r   r"   r   zDict[str, str] | Noner#   r$   )3r)   
__future__r   r*   r   r[   r   rs   r   r   typingr   apitools.base.pyr   r   r   r   r   r   googlecloudsdk.api_lib.storager	   r
   googlecloudsdk.callioper   $googlecloudsdk.command_lib.functionsgooglecloudsdk.command_lib.utilr   googlecloudsdk.corer   r   r   googlecloudsdk.core.utilr   r   re   objectABCMetar   r/   r?   rv   rQ   rY   r^   rp   r{   r   r   r   r   r   r   r   r   <module>r      s   ; " 
  	  	    : ) % . 6 7 E ; 8 # ) * , 8 Fckk  
3 
 "7 * &b)
!8*
-#B'%~&67"K#AB)+#Xy$9:  *.


&

( *.
&	.4 #	))) )
 	)X8#5EH!6.#.. GK000.C0	0r   