
    w                        S 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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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/J0r0  SSK1J2r2  S r3S!r4S"r5S#r6S$r7S%r8S&r9S'r:S(r;S)r<S*r=S+r>S,r?S-r@\3\4-   \5-   \6-   \7-   \8-   \9-   rA\:\;-   \<-   \=-   \>-   \?-   \@-   rB\" \A\B5      rC\" \3\:5      rD\" \4\;5      rE\" \5\<5      rF\" \6\=5      rG\" \7\>5      rH\" \8\?5      rI\" \9\@5      rJ " S. S/\5      rKg)0zEImplementation of Retention Policy configuration command for buckets.    )absolute_importN)encoding)metrics)AccessDeniedException)Preconditions)Command)CommandArgument)ApiSelector)CommandException)NO_URLS_MATCHED_TARGET)CreateHelpText)NameExpansionIterator)SeekAheadNameExpansionIterator)StorageUrlFromString)storage_v1_messages)MetadataMessage)GetCloudApiInstance)NO_MAX)PutToQueueWithTimeout)ConfirmLockRequest)ReleaseEventHoldFuncWrapper)ReleaseTempHoldFuncWrapper)RetentionInSeconds)RetentionPolicyToString)SetEventHoldFuncWrapper)SetTempHoldFuncWrapper)$UpdateObjectMetadataExceptionHandler)GcloudStorageMap)PreconditionsFromHeaderszA
  gsutil retention set <retention_period> gs://<bucket_name>...
z0
  gsutil retention clear gs://<bucket_name>...
z.
  gsutil retention get gs://<bucket_name>...
z/
  gsutil retention lock gs://<bucket_name>...
zF
  gsutil retention event-default (set|release) gs://<bucket_name>...
zL
  gsutil retention event (set|release) gs://<bucket_name>/<object_name>...
zK
  gsutil retention temp (set|release) gs://<bucket_name>/<object_name>...
a	  
<B>SET</B>
  You can configure a data retention policy for a Cloud Storage bucket that
  governs how long objects in the bucket must be retained. You can also lock the
  data retention policy, permanently preventing the policy from being reduced or
  removed. For more information, see `Retention policies and Bucket Lock
  <https://cloud.google.com/storage/docs/bucket-lock>`_.

  The ``gsutil retention set`` command allows you to set or update the
  retention policy on one or more buckets.

  To remove an unlocked retention policy from one or more
  buckets, use the ``gsutil retention clear`` command.

  The ``set`` sub-command can set a retention policy with the following formats:

<B>SET FORMATS</B>
  Formats for the ``set`` subcommand include:

  <number>s
      Specifies retention period of <number> seconds for objects in this bucket.

  <number>d
      Specifies retention period of <number> days for objects in this bucket.

  <number>m
      Specifies retention period of <number> months for objects in this bucket.

  <number>y
      Specifies retention period of <number> years for objects in this bucket.

  GCS JSON API accepts retention periods as number of seconds. Durations provided
  in terms of days, months or years are converted to their rough equivalent
  values in seconds, using the following conversions:

  - A month is considered to be 31 days or 2,678,400 seconds.
  - A year is considered to be 365.25 days or 31,557,600 seconds.

  Retention periods must be greater than 0 and less than 100 years.
  Retention durations must be in only one form (seconds, days, months,
  or years), and not a combination of them.

  Note that while it is possible to specify retention durations
  shorter than a day (using seconds), enforcement of such retention periods is not
  guaranteed. Such durations may only be used for testing purposes.

<B>EXAMPLES</B>
  Setting a retention policy with a duration of 1 year on a bucket:

    gsutil retention set 1y gs://my-bucket

  Setting a retention policy with a duration of 36 months on a bucket:

    gsutil retention set 36m gs://some-bucket

  You can also provide a precondition on a bucket's metageneration in order to
  avoid potential race conditions. You can use gsutil's '-h' option to specify
  preconditions. For example, the following specifies a precondition that checks
  a bucket's metageneration before setting the retention policy on the bucket:

    gsutil -h "x-goog-if-metageneration-match: 1" \
      retention set 1y gs://my-bucket
a4  
<B>CLEAR</B>
  The ``gsutil retention clear`` command removes an unlocked retention policy
  from one or more buckets. You cannot remove or reduce the duration of a locked
  retention policy.

<B>EXAMPLES</B>
  Clearing an unlocked retention policy from a bucket:

    gsutil retention clear gs://my-bucket
z
<B>GET</B>
  The ``gsutil retention get`` command retrieves the retention policy for a given
  bucket and displays a human-readable representation of the configuration.
a1  
<B>LOCK</B>
  The ``gsutil retention lock`` command PERMANENTLY locks an unlocked
  retention policy on one or more buckets.

  CAUTION: A locked retention policy cannot be removed from a bucket or reduced
  in duration. Once locked, deleting the bucket is the only way to "remove" a
  retention policy.
a  
<B>EVENT-DEFAULT</B>
  The ``gsutil retention event-default`` command sets the default value for an
  event-based hold on one or more buckets.

  By setting the default event-based hold on a bucket, newly-created objects
  inherit that value as their event-based hold (it is not applied
  retroactively).

<B>EXAMPLES</B>
  Setting the default event-based hold on a bucket:

    gsutil retention event-default set gs://my-bucket

  Releasing the default event-based hold on a bucket:

    gsutil retention event-default release gs://my-bucket

  You can also provide a precondition on a bucket's metageneration in order to
  avoid potential race conditions. You can use gsutil's '-h' option to specify
  preconditions. For example, the following specifies a precondition that checks
  a bucket's metageneration before setting the default event-based hold on the bucket:

    gsutil -h "x-goog-if-metageneration-match: 1" \
      retention event-default set gs://my-bucket
a[  
<B>EVENT</B>
  The ``gsutil retention event`` command enables or disables an event-based
  hold on an object.

<B>EXAMPLES</B>
  Setting the event-based hold on an object:

    gsutil retention event set gs://my-bucket/my-object

  Releasing the event-based hold on an object:

    gsutil retention event release gs://my-bucket/my-object

  You can also provide a precondition on an object's metageneration in order to
  avoid potential race conditions. You can use gsutil's '-h' option to specify
  preconditions. For example, the following specifies a precondition that checks
  an object's metageneration before setting the event-based hold on the object:

    gsutil -h "x-goog-if-metageneration-match: 1" \
      retention event set gs://my-bucket/my-object

  If you want to set or release an event-based hold on a large number of objects, then
  you might want to use the top-level '-m' option to perform a parallel update.
  For example, the following command sets an event-based hold on objects ending
  with .jpg in parallel, in the root folder:

      gsutil -m retention event set gs://my-bucket/*.jpg
aA  
<B>TEMP</B>
  The ``gsutil retention temp`` command enables or disables a temporary hold
  on an object.

<B>EXAMPLES</B>
  Setting the temporary hold on an object:

    gsutil retention temp set gs://my-bucket/my-object

  Releasing the temporary hold on an object:

    gsutil retention temp release gs://my-bucket/my-object

  You can also provide a precondition on an object's metageneration in order to
  avoid potential race conditions. You can use gsutil's '-h' option to specify
  preconditions. For example, the following specifies a precondition that checks
  an object's metageneration before setting the temporary hold on the object:

    gsutil -h "x-goog-if-metageneration-match: 1" \
      retention temp set gs://my-bucket/my-object

  If you want to set or release a temporary hold on a large number of objects, then
  you might want to use the top-level '-m' option to perform a parallel update.
  For example, the following command sets a temporary hold on objects ending
  with .jpg in parallel, in the root folder:

    gsutil -m retention temp set gs://bucket/*.jpg
c                     ^  \ rS rSrSr\R                  " S/ \S\SSS\	R                  /\	R                  \R                  " 5       /\R                  " 5       /\R                  " S5      /\R                  " 5       /\R                  " 5       /\R                  " 5       /S.\R                  " 5       /\R                  " 5       /S.\R                  " 5       /\R                  " 5       /S.S.S	9r\R                   " S/ S
S\\\\\\\\S.S9rU 4S jrS rS r SS jrS rS rS r S r!S r"S r#S r$S r%S r&S r'S r(Sr)U =r*$ )RetentionCommandi  z+Implementation of gsutil retention command.	retention   F   setrelease)r&   cleargetlockevent-defaulteventtemp)
command_name_aliasesusage_synopsismin_argsmax_argsfile_url_okprovider_url_okurls_start_arggs_api_supportgs_default_apiargparse_argumentscommand_helpz=Provides utilities to interact with Retention Policy feature.)r)   r&   r(   r*   r+   r,   r-   )	help_namehelp_name_aliases	help_typehelp_one_line_summary	help_textsubcommand_help_textc                 $  > U R                   S   S:X  ab  [        S[        SSSSR                  [        U R                   S   5      5      /U R                   SS  -   0 S	900 S	9nU R                   S S U l         O[        [        / S
Q0 S	9[        [        / SQ0 S	9[        / SQ0 S	9S.0 S	9[        [        / SQ0 S	9[        / SQ0 S	9S.0 S	9[        / SQ0 S	9[        / SQ0 S	9[        [        / SQ0 S	9[        / SQ0 S	9S.0 S	9S.0 S	9n[        TU ]  U5      $ )Nr   r&   storagebucketsupdatez--retention-period={}sr$   r#   )gcloud_commandflag_map)r@   rA   rB   z--clear-retention-period)r@   objectsrB   z--event-based-hold)r@   rE   rB   z--no-event-based-holdr%   )r@   rA   rB   z--default-event-based-hold)r@   rA   rB   z--no-default-event-based-hold)r@   rA   describez--format=yaml(retentionPolicy)z--raw)r@   rA   rB   z--lock-retention-period)r@   rE   rB   z--temporary-hold)r@   rE   rB   z--no-temporary-hold)r(   r,   r+   r)   r*   r-   )argsr   formatr   superget_gcloud_storage_args)selfgcloud_storage_map	__class__s     +platform/gsutil/gslib/commands/retention.pyrJ   (RetentionCommand.get_gcloud_storage_argsI  s   yy|u+"#Y29901>@& ))AB-	&(
  "#	  ))BQ-di+ #&  " # /2$ ,.  /2$ ,. &$  "', # /2$ ,.  /2$ ,. &$  "', # 3 -/	0 #&  " # /2$ ,.  /2$ ,. &$  "'IYt w\z 7*+=>>    c                    U R                   R                  S5      [        R                  :w  a$  [	        SR                  U R                  5      5      e[        U R                  5      U l	        U R                  R                  S5      nU R                  SS9  US:X  a  U R                  nOUS:X  a  U R                  nOUS:X  a  U R                  nOqUS	:X  a  U R                   nO^US
:X  a  U R"                  nOKUS:X  a  U R$                  nO8US:X  a  U R&                  nO%[	        SR                  UU R                  5      5      e[(        R*                  " U/U R,                  S9  U" 5       $ )z.Command entry point for the retention command.gszThe {} command can only be used with the GCS JSON API. If you have only supplied hmac credentials in your boto file, please instead supply a credential type that can be used with the JSON API.r   T)
check_argsr&   r(   r)   r*   r+   r,   r-   zHInvalid subcommand "{}" for the {} command.
See "gsutil help retention".)subcommandssub_opts)
gsutil_apiGetApiSelectorr
   JSONr   rH   command_namer   headerspreconditionsrG   popParseSubOpts_SetRetention_ClearRetention_GetRetention_LockRetention_DefaultEventHold
_EventHold	_TempHoldr   LogCommandParamsrU   )rK   action_subcommandfuncs      rN   
RunCommandRetentionCommand.RunCommand  sN   
 %%d+{/?/?? . 06vd6G6G/H	J J 2$,,?D		a(&E!d	g	%!!d	e	#d	f	$  d	o	-##d	g	%__d	f	$^^d*+162C262C2C,EF F *;)<&*mm56MrP   c           
         [        U R                  R                  S9nSnU Hw  nU R                  US/S9nU H]  n	U	R                  n
SnU R
                  R                  XI5        U R                  R                  U
R                  UUU
R                  US9  M_     My     U(       d  [        [        [        U5      -  5      eg )N)meta_gen_matchFidbucket_fieldsT)r[   providerfields)r   r[   rk   GetBucketUrlIterFromArgstorage_urlloggerinforV   PatchBucketbucket_nameschemer   r   list)rK   url_argsbucket_metadata_updaterp   log_msg_templater[   some_matchedurl_strbucket_iterblrurls              rN   BucketUpdateFunc!RetentionCommand.BucketUpdateFunc  s    !))88:M
 L000Ok#oo)/##COO$:2?-0ZZ+1	 	$ 	3	   3d8nDEE rP   c           
      z   [        XS9nUR                  nU R                  R                  X&5        [        R
                  " [        R                  UR                  5      n[        U R                  R                  U R                  R                  S9nUR                  c  UR                  Ul        UR                  c  UR                  Ul        UR                  UR                   UR"                  UUR                  UUR$                  S/S9  ['        UR(                  [+        [,        R,                  " 5       S95        g)a  Updates metadata on an object using PatchObjectMetadata.

Args:
  patch_obj_metadata: Metadata changes that should be applied to the
                      existing object.
  log_template: The log template that should be printed for each object.
  name_expansion_result: NameExpansionResult describing target object.
  thread_state: gsutil Cloud API instance to use for the operation.
)thread_state)	gen_matchrk   Nrl   )
generationr[   ro   rp   )message_time)r   expanded_storage_urlrs   rt   r   JsonToMessageapitools_messagesObjectexpanded_resultr   r[   r   rk   r   metagenerationPatchObjectMetadatarv   object_namerw   r   status_queuer   time)	rK   patch_obj_metadatalog_templatename_expansion_resultr   rV   exp_src_urlcloud_obj_metadatar[   s	            rN   ObjectUpdateMetadataFunc)RetentionCommand.ObjectUpdateMetadataFunc  s    %TEJ'<<KKK\/!//  "7"G"GI "$$..))88:M & 2 = =m##+%7%F%Fm""";#:#:#.#:#:#5.9.D.D1>,7,>,>+/& # 2 *11)tyy{CErP   c                     [        U R                  U R                  U R                  U R                  UU R
                  U R                  U R                  SS/S9	$ )Nr   r   )all_versionscontinue_on_errorbucket_listing_fields)r   rY   debugrs   rV   recursion_requestedr   parallel_operationsrK   ry   s     rN   _GetObjectNameExpansionIterator0RetentionCommand._GetObjectNameExpansionIterator!  sV     

  &&22+-=>	@ 	@rP   c           
          [        U R                  U R                  U R                  5       UU R                  U R
                  U R                  S9$ )N)r   
project_id)r   rY   r   GetSeekAheadGsutilApir   r   r   r   s     rN   "_GetSeekAheadNameExpansionIterator3RetentionCommand._GetSeekAheadNameExpansionIterator-  sH    )$*;*;*.***.*D*D*F*2*.*B*B7;7H7H59__F FrP   c                     [        U R                  S   5      n[        R                  R	                  US9nSn[        R                  " US9nU R                  SS nU R                  UUSS/US	9  g)
z6Set retention retention_period on one or more buckets.r   retentionPeriodz!Setting Retention Policy on %s...retentionPolicyr$   Nrl   r   rp   r{   )r   rG   r   BucketRetentionPolicyValuer   )rK   secondsretention_policyr{   rz   ry   s         rN   r^   RetentionCommand._SetRetention6  s     !1.G)00EE F ! ;.55(*yy}H(0"&(9!:+;  = rP   c                     [         R                  R                  SS9nSn[         R                  " US9nU R                  nU R	                  UUSS/US9  g)	z8Clear retention retention_period on one or more buckets.Nr   z"Clearing Retention Policy on %s...r   rl   r   r   r   )r   r   r   rG   r   )rK   r   r{   rz   ry   s        rN   r_    RetentionCommand._ClearRetentionG  sn    )00EE F ;.55(*yyH(0"&(9!:+;  = rP   c                     U R                  U R                  S   S/S9u  p[        [        UR                  U5      5        g)z)Get Retention Policy for a single bucket.r   r   rm   )GetSingleBucketUrlFromArgrG   printr   r   )rK   
bucket_urlbucket_metadatas      rN   r`   RetentionCommand._GetRetentionU  sE    "&"@"@		!%6$7 #A #9J	
!/"A"A:
NOrP   c                    U R                   nSnU GH  nU R                  US/S9nU GHq  nUR                  nSnU R                  R	                  UR
                  UR                  / SQS9nUR                  (       a  UR                  R                  (       d$  [        SR                  UR
                  5      5      eUR                  R                  SL a  U R                  R                  SU5        M  [        UR
                  UR                  5      (       aX  U R                  R                  S	U5        U R                  R!                  UR
                  UR"                  UR                  S
9  GMG  U R                  R                  SR                  U5      5        GMt     GM     U(       d  [        [$        ['        U5      -  5      eg)z-Lock Retention Policy on one or more buckets.Frl   rm   T)rl   r   r   )ro   rp   z7Bucket "{}" does not have an Unlocked Retention Policy.z+Retention Policy on "%s" is already locked.z!Locking Retention Policy on %s...)ro   z&  Abort Locking Retention Policy on {}r   )rG   rq   rr   rV   	GetBucketrv   rw   r   r   r   rH   isLockedrs   errorr   rt   LockRetentionPolicyr   r   rx   )rK   ry   r|   r}   r~   r   r   r   s           rN   ra   RetentionCommand._LockRetention\  s~   yyH L000Ok#oo//33OOZZ> 4 @ !00 00@@ GNN//#$ $ ,,55=
++

I3
O / ? ?A A
++

>
D
//
-
-coo.=.L.L7:zz . C ++

6==cBD/  6 3d8nDEErP   c                    SnU R                   (       al  U R                   S   R                  5       S:X  a  SnOHU R                   S   R                  5       S:X  a  SnO$[        SR                  U R                  5      5      eU(       a  SOS	nS
R                  U5      n[
        R                  " US9nU R                   SS nU R                  UUSS/US9  g)z?Sets default value for Event-Based Hold on one or more buckets.Nr   r&   Tr'   FzeInvalid subcommand "{}" for the "retention event-default" command.
See "gsutil help retention event".Setting	Releasingz${} default Event-Based Hold on %s...)defaultEventBasedHoldr$   rl   r   r   )rG   lowerr   rH   rU   r   r   r   )rK   holdverbr{   rz   ry   s         rN   rb   "RetentionCommand._DefaultEventHold  s    Dyy	1				&99Q<9,=>Df? ! 	!
 9+D=DDTJ.55"$yy}H(0"&(?!@+;  = rP   c                     SnSnU R                  U5      nU R                  SS nU(       a  [        O[        nU R	                  XTU5        g)z7Sets or unsets Event-Based Hold on one or more objects.r,   zEvent-Basedr$   Nr   )_ProcessHoldArgsrG   r   r   _SetHoldrK   sub_command_namesub_command_full_namer   ry   obj_metadata_update_wrappers         rN   rc   RetentionCommand._EventHold  sQ    )  !12Dyy}H&* $;0K  MM-9NOrP   c                     SnSnU R                  U5      nU R                  SS nU(       a  [        O[        nU R	                  XTU5        g)z5Sets or unsets Temporary Hold on one or more objects.r-   	Temporaryr$   Nr   )r   rG   r   r   r   r   s         rN   rd   RetentionCommand._TempHold  sQ    '  !12Dyy}H&* $:0J  MM-9NOrP   c                     SnU R                   S   R                  5       S:X  a  SnU$ U R                   S   R                  5       S:X  a  SnU$ [        SR                  U R                   S   UU5      5      e)zProcesses command args for Temporary and Event-Based Hold sub-command.

Args:
  sub_command_name: The name of the subcommand: "temp" / "event"

Returns:
  Returns a boolean value indicating whether to set (True) or
  release (False)the Hold.
Nr   r&   Tr'   FzWInvalid subcommand "{}" for the "retention {}" command.
See "gsutil help retention {}".)rG   r   r   rH   )rK   r   r   s      rN   r   !RetentionCommand._ProcessHoldArgs  s     Dyy|u$d K 
1				*d K -.4fTYYq\5E5E/GH HrP   c                 ,   [        U5      S:X  af  U R                  (       dU  [        US   5      nUR                  5       (       a  UR	                  5       (       d  [        SR                  US   5      5      eU R                  U5      nU R                  U5      nSU l	         U R                  UU[        SUS9  U R                  (       d  [        SR                  U5      5      eg! [         a&  nUR                  S:X  a  U R                  5         e SnAff = f)	aT  Common logic to set or unset Event-Based/Temporary Hold on objects.

Args:
  obj_metadata_update_wrapper: The function for updating related fields in
                               Object metadata.
  url_args: List of object URIs.
  sub_command_full_name: The full name for sub-command:
                         "Temporary" / "Event-Based"
r$   r   zURL ({}) must name an objectT)fail_on_errorseek_ahead_iteratori  Nz*{} Hold for some objects could not be set.)lenr   r   
IsCloudUrlIsObjectr   rH   r   r   everything_set_okayApplyr   r   status_WarnServiceAccounts)rK   r   ry   r   r   name_expansion_iteratorr   es           rN   r   RetentionCommand._SetHold  s    8}$":": !-cnn3<<>>=DDQK   	 #BB8LAA(K  $D jj,(5#%8	  : ##
6
=
=#%& & $ ! 	
S!!#s    C# #
D-!DD)rG   r   r[   )N)+__name__
__module____qualname____firstlineno____doc__r   CreateCommandSpec	_SYNOPSISr   r
   rX   r	   %MakeZeroOrMoreCloudBucketURLsArgumentMakeNCloudBucketURLsArgumentMakeZeroOrMoreCloudURLsArgumentcommand_specHelpSpec_DETAILED_HELP_TEXT_get_help_text_set_help_text_clear_help_text_lock_help_text_event_default_help_text_event_help_text_temp_help_text	help_specrJ   rh   r   r   r   r   r^   r_   r`   ra   rb   rc   rd   r   r   __static_attributes____classcell__)rM   s   @rN   r!   r!     s   3 **!&&' %%!GGIJ#IIKL!>>qAB"HHJK%EEGH)IIKL
 &EEGH)IIKL
 &EEGH)IIKL	,> 
I##!3#!)$n?`(TF4 -1	&EP
@F"#J2		.+& +&rP   r!   )Lr   
__future__r   r   apitools.base.pyr   gslibr   gslib.cloud_apir   r   gslib.commandr   gslib.command_argumentr	   gslib.cs_api_mapr
   gslib.exceptionr   r   gslib.help_providerr   gslib.name_expansionr   r   gslib.storage_urlr   "gslib.third_party.storage_apitoolsr   r   gslib.thread_messager   gslib.utils.cloud_api_helperr   gslib.utils.constantsr   &gslib.utils.parallelism_framework_utilr   gslib.utils.retention_utilr   r   r   r   r   r   r   r   gslib.utils.shim_utilr   gslib.utils.translation_helperr   _SET_SYNOPSIS_CLEAR_SYNOPSIS_GET_SYNOPSIS_LOCK_SYNOPSIS_EVENT_DEFAULT_SYNOPSIS_EVENT_SYNOPSIS_TEMP_SYNOPSIS_SET_DESCRIPTION_CLEAR_DESCRIPTION_GET_DESCRIPTION_LOCK_DESCRIPTION_EVENT_DEFAULT_DESCRIPTION_EVENT_DESCRIPTION_TEMP_DESCRIPTIONr   _DESCRIPTIONr   r   r   r   r   r   r   r   r!    rP   rN   <module>r     s   L &  %  1 ) ! 2 ( , 2 . 6 ? 2 W 0 < ( H 9 B A 9 > > = K 2 C > @
    6 < < _,}<~M$%'679GH	 !#558HH!"$>?"#%67 %Y= /?@!/3EF /?@ 1BC)*A*DF !/3EF  1BC^&w ^&rP   