
    +              
         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
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\&\RN                  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-     S0S% jjr/S1S& jr0  S2       S3S' jjr1S4S( jr2        S5S) jr3    S6S* jr4 S-       S7S+ jjr5g)8z4Version-agnostic utilities for function source code.    )absolute_import)annotations)division)unicode_literalsN)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)RequiredFilesStrategy5   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.Validate8   s    

     Nr   	list[str]r   strreturnNone)	__name__
__module____qualname____firstlineno____doc__abcabstractmethodr   __static_attributes__r"   r!   r   r   r   5   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   )superr2   __init___required_files)r   required_files	__class__s     r   r6    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?)r7   r   SourceArgumentError)r   r   r   fs       r   r    AllFilesPresentStrategy.ValidateD   sF    !!	
	%,,<QC @$I%IK
 	
 "r!   )r7   )r8   r$   r#   )	r(   r)   r*   r+   r,   r6   r   r/   __classcell__)r9   s   @r   r2   r2   =   s    A*
 
r!   r2   c                  "    \ rS rSrSrSS jrSrg)PythonRequiredFilesStrategyM   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 [r<   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.ValidateP   sv    ++**")#GI 
 	"55$77**44;9 =&&  8 	6r!   r"   Nr#   )r(   r)   r*   r+   r,   r   r/   r"   r!   r   rB   rB   M   s
    >r!   rB   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   _GcloudIgnoreCreationPredicaterT   l   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GetFileChooserForDirrT   )pathrX   rV   s      r   _GetChooserr\   r   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)osr[   existsr   r=   isdirrR   s    r   _ValidateDirectoryExistsOrRaisera      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)r[   errorNi   i   B)
r\   
IsIncluded
file_utilsGetTreeSizeBytesOSErrorr   FunctionsErrorformatOversizedDeploymentErrorr%   )r[   rX   chooserrd   size_besize_limit_mbsize_limit_bs           r   _ValidateUnpackedSourceSizers      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)ra   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.ziprc   zHError creating a ZIP archive with the source code for directory {0}: {1}N)ra   r^   r[   r_   joinr   IgnoreFileNotFoundErrorrl   rs   r\   rg   r   MakeZipFromDir
ValueErrorrk   r%   )zip_dirsource_pathrX   enforce_size_limitzip_file_namern   rd   rp   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      $ )Nru   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   rangerl   )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   SourceUploadErrorrl   )
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   rl   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()rS   r%   r&   boolr   )r[   r%   rX   
str | Noner&   zgcloudignore.FileChooser)rS   r%   r&   r'   )r[   r%   rX   r   r&   r'   )r{   r%   r   r%   r&   r'   )NF)r   r%   r   r%   rX   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'   )6r,   
__future__r   r   r   r   r-   r   r^   r   rv   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   rh   objectABCMetar   r2   rB   ry   rT   r\   ra   rs   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!   