
    +?                     `   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J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\R.                  5      r " S S\R.                  5      r " S S\5      rS rS rS rS rS r S r!S r"S r#S r$g)z-Utilities for dealing with version resources.    )absolute_import)division)unicode_literalsN)
exceptions)env)metric_names)operations_util)log)metrics)retry)text)times)mapc                       \ rS rSrSrg)VersionValidationError&    N__name__
__module____qualname____firstlineno____static_attributes__r       .lib/googlecloudsdk/api_lib/app/version_util.pyr   r   &       r   r   c                       \ rS rSrSrg)VersionsDeleteError*   r   Nr   r   r   r   r   r   *   r   r   r   c                   |    \ rS rSrSrSrSrSr     SS jr\	S 5       r
\	S	 5       rS
 rS rS rS rS rS rSrg)Version.   zValue class representing a version resource.

This wrapper around appengine_<API-version>_messages.Version is necessary
because Versions don't have traffic split, project, or last_deployed_time as a
datetime object.
g-C6?   zFapps/(?P<project>.*)/services/(?P<service>.*)/versions/(?P<version>.*)Nc	                 d    Xl         X l        X0l        Xpl        X@l        XPl        X`l        Xl        g N)projectserviceidversiontraffic_splitlast_deployed_timeenvironmentservice_account)	selfr&   r'   
version_idr*   r+   r,   version_resourcer-   s	            r   __init__Version.__init__B   s0     LLG#L&0"*r   c                     UR                  S5      nS[        U5      s=:  a  U R                  ::  d  O  [        S5      eS /U R                  [        U5      -
  -  U-   nU " U6 $ )N/r   zJ[{0}] is not a valid resource path. Expected <project>/<service>/<version>)splitlen_RESOURCE_PATH_PARTSr   )clspathpartss      r   FromResourcePathVersion.FromResourcePathT   sg    JJsOEs5z5S555" $L M M Fc..U;<uDE;r   c           
      t   [         R                  " U R                  UR                  5      R	                  5       u  p4nU=(       a&    UR
                  R                  UR                  S5      nSn UR                  (       aC  [        R                  " UR                  5      R                  SS9n[        R                  " U5      nUR                  S:X  a  [        R                  n	O2UR                   (       a  [        R"                  n	O[        R$                  n	U " X4UR                  UXyUS9$ ! [         a     Nsf = f)zFConvert appengine_<API-version>_messages.Version into wrapped Version.g        Nr   )microsecondflexible)r*   r+   r,   r0   )rematch_VERSION_NAME_PATTERNnamegroupsr5   getr(   
createTimer   ParseDateTimereplaceLocalizeDateTime
ValueErrorr   FLEXvmMANAGED_VMSSTANDARD)
r8   r)   r'   r&   
service_id_r*   last_deployedlast_deployed_dtr,   s
             r   FromVersionResourceVersion.FromVersionResource^   s      XXc&?&?&-ll44:FH GB 1 1'**c BMM			 ..w/A/ABJJ K ../?@ {{j HHk	OOkLLkwGJJm"/ ') )  
s   /AD* *
D76D7c                 L    [        U R                  S-
  5      U R                  :  $ )Ng      ?)absr*   _ALL_TRAFFIC_EPSILONr.   s    r   IsReceivingAllTrafficVersion.IsReceivingAllTrafficv   s#    t!!C'(4+D+DDDr   c           	         U R                   (       dn   UR                  U R                  U R                  5      U l         U R                   (       d%  [        R
                  " SR                  U 5      5        U R                   $ U R                   $ ! [        R                   ac  n[        R                  " SR                  [        R                  " U 5      [        R                  " U5      5      5         SnAU R                   $ SnAff = f)a+  Attempts to load the Version resource for this version.

Returns the cached Version resource if it exists. Otherwise, attempts to
load it from the server. Errors are logged and ignored.

Args:
  api_client: An AppengineApiClient.

Returns:
  The Version resource, or None if it could not be loaded.
z-Failed to retrieve resource for version [{0}]z,Error retrieving Version resource [{0}]: {1}N)r)   GetVersionResourcer'   r(   r
   infoformatapitools_exceptionsErrorwarningsix	text_type)r.   
api_clientes      r   r\   Version.GetVersionResourcey   s     <<	D!44T\\477K||
((BII$O
P <<4<< !&& D 	BVCMM$/q1AB	D 	D<<Ds   A!B D AC>>Dc                     [        U5      [        L =(       aY    U R                  UR                  :H  =(       a9    U R                  UR                  :H  =(       a    U R                  UR                  :H  $ r%   )typer!   r&   r'   r(   r.   others     r   __eq__Version.__eq__   sT    K7"  LLEMM) LLEMM)  GGuxx!r   c                     X:X  + $ r%   r   ri   s     r   __ne__Version.__ne__   s    r   c                     [        U R                  U R                  U R                  4UR                  UR                  UR                  45      $ r%   )cmpr&   r'   r(   ri   s     r   __cmp__Version.__cmp__   s:    dllDGG4u}}ehh79 9r   c                 d    SR                  U R                  U R                  U R                  5      $ )Nz{0}/{1}/{2})r^   r&   r'   r(   rX   s    r   __str__Version.__str__   s#    dllDGGDDr   )r,   r(   r+   r&   r'   r-   r*   r)   )NNNNN)r   r   r   r   __doc__rW   r7   rB   r1   classmethodr;   rS   rY   r\   rk   rn   rr   ru   r   r   r   r   r!   r!   .   s{     6 ""& $#+$   ) ).E2!9Er   r!   c                 $   U  H  nUR                   U Vs/ s H  o3R                   PM     sn;  a$  [        SR                  UR                   5      5      eX!;  d  MX  [        SR                  UR                   UR                  5      5      e   gs  snf )aH  Validate that each version in filtered_versions is also in all_versions.

Args:
  filtered_versions: list of Version representing a filtered subset of
    all_versions.
  all_versions: list of Version representing all versions in the current
    project.

Raises:
  VersionValidationError: If a service or version is not found.
Service [{0}] not found.zVersion [{0}/{1}] not found.Nr'   r   r^   r(   )filtered_versionsall_versionsr)   vs       r   _ValidateServicesAreSubsetr      s{     #g,?,Qyy,??"
$
+
+GOO
<> >""
(
/
/07

<= = #?s   Bc                    [        [        [        R                  U 5      5      nU Hb  nUR                  (       d  UR
                  (       d  [        S5      eUR                  (       a  UR                  U:w  a  [        S5      eXl        Md     U$ )a3  Parse the list of resource paths specifying versions.

Args:
  paths: The list of resource paths by which to filter.
  project: The current project. Used for validation.

Returns:
  list of Version

Raises:
  VersionValidationError: If not all versions are valid resource paths for the
    current project.
zTIf you provide a resource path as an argument, all arguments must be resource paths.z,All versions must be in the current project.)listr   r!   r;   r&   r'   r   )pathsr&   versionsr)   s       r   ParseVersionResourcePathsr      st     #g..67(gOOw" $, - - 7??g5"
8: :O  
/r   c                 B   U nU(       a\  X  Vs/ s H  oDR                   PM     sn;  a  [        SR                  U5      5      eU  Vs/ s H  oDR                   U:X  d  M  UPM     nnU(       a#  U Vs/ s H  oDR                  U;   d  M  UPM     nnU$ s  snf s  snf s  snf )a  Return a list of versions to act on based on user arguments.

Args:
  all_versions: list of Version representing all services in the project.
  versions: list of string, version names to filter for.
    If empty, match all versions.
  service: string or None, service name. If given, only match versions in the
    given service.

Returns:
  list of matching Version

Raises:
  VersionValidationError: If an improper combination of arguments is given.
rz   r{   )r}   r   r'   r|   r~   s        r   GetMatchingVersionsr      s      #,7,Qyy,77"#=#D#DW#MNN$0ILqII4HLI$5J$5q9I$5J	 8I Ks   BBB1BBc                    0 nU H`  nSR                  UR                  UR                  5      n [        R                  " U R
                  UR                  UR                  5        Mb     U(       a  0 nUR                  5        H  u  pGSR                  UU5      Xd'   M     [        SR                  [        R                  " [        U5      S5      SR                  [        UR!                  5       5      5      5      SR                  [        UR#                  5       5      5      -   5      eg! [        R                   a$  n[        R                  " U5      X$'    SnAGMV  SnAff = f)z/Delete the given version of the given services.z{0}/{1}Nz
[{0}]: {1}zIssue deleting {0}: [{1}]

r)   z, z

)r^   r'   r(   r	   CallAndCollectOpErrorsDeleteVersionMiscOperationErrorrb   rc   itemsr   r   	Pluralizer6   joinr   keysvalues)rd   r   errorsr)   version_patherrprintable_errors	error_msgs           r   DeleteVersionsr      s+   &g##GOOWZZ@L0,,

"
"GOOWZZA  #)<<>'3':':<;D(F$ $2 '..NN3/0)<IId+00234	6 	D)00234	56 6  -- 0 ]]3/f0s   6D((E <EE c                    SnU(       a  [        XU5      nUR                  U5      nUR                  R                  R                  nU(       am  UR
                  UR                  :X  aS  [        R                  R                  SR                  U5      5        UR                  UR                  UR                  SS9  [        X5        U(       a  [        XRU5        gg)a  Promote the new version to receive all traffic.

First starts the new version if it is not running.

Additionally, stops the previous version if stop_previous_version is True and
it is possible to stop the previous version.

Args:
  all_services: {str, Service}, A mapping of service id to Service objects
    for all services in the app.
  new_version: Version, The version to promote.
  api_client: appengine_api_client.AppengineApiClient to use to make requests.
  stop_previous_version: bool, True to stop the previous version which was
    receiving all traffic, if any.
  wait_for_stop_version: bool, indicating whether to wait for stop operation
  to finish.
Nz+Starting version [{0}] before promoting it.T)block)_GetPreviousVersionr\   messagesr!   ServingStatusValueValuesEnumservingStatusSTOPPEDr
   statusPrintr^   StartVersionr'   r(   _SetDefaultVersion_StopPreviousVersionIfApplies)all_servicesnew_versionrd   stop_previous_versionwait_for_stop_versionold_default_versionnew_version_resourcestatus_enums           r   PromoteVersionr     s    &  .:/ %77
C##++HH+((K,?,??JJBf[)+K//tL[-!"5"79 r   c                 .    U R                   R                  $ r%   )r)   
versionUrl)r)   s    r   GetUrir   3  s    		#	##r   c                     U R                  UR                  S5      nU(       d  gUR                  U/5       H8  nUR                  5       (       d  M  UR                  UR                  :w  d  M6  Us  $    g)a  Get the previous default version of which new_version is replacing.

If there is no such version, return None.

Args:
  all_services: {str, Service}, A mapping of service id to Service objects
    for all services in the app.
  new_version: Version, The version to promote.
  api_client: appengine_api_client.AppengineApiClient, The client for talking
    to the App Engine Admin API.

Returns:
  Version, The previous version or None.
N)rE   r'   ListVersionsrY   r(   )r   r   rd   r'   old_versions        r   r   r   7  s`     [00$7'	,,gY7k 	))+++..( 8r   c                    [         R                  " [        R                  5        S n [        R
                  " SSS9nUR                  UR                  U R                  U R                  /USS9  [         R                  " [        R                  5        g	! [        R                   aO  nUR                  u  pVU(       a   [        R                  " US   US   S9   S	nANn[        R                  " 5       eS	nAff = f)
zSets the given version as the default.

Args:
  new_version: Version, The version to promote.
  api_client: appengine_api_client.AppengineApiClient to use to make requests.
c                 6    [        U [        R                  5      $ r%   )
issubclassr_   	HttpError)exc_typeunused_exc_valueunused_tracebackunused_states       r   ShouldRetry'_SetDefaultVersion.<locals>.ShouldRetry[  s    h 3 = =>>r   r#      )max_retrialsexponential_sleep_multiplieri  )should_retry_ifsleep_ms   )tbN)r   CustomTimedEventr   SET_DEFAULT_VERSION_API_STARTr   RetryerRetryOnExceptionSetDefaultVersionr'   r(   MaxRetrialsExceptionlast_resultr   reraiseInternalErrorSET_DEFAULT_VERSION_API)r   rd   r   retryerre   unused_resultexc_infos          r   r   r   R  s     
<EEF?'mmKG$${':':KNN&K#d  4 
<??@ 
	#	# ' !]!!5 $$&&'s   AB C8)0C3C33C8c           	      (   U R                   nUR                  R                  R                  nUR                  UR
                  :w  a&  [        R                  " SR                  U 5      5        gUR                  =(       d%    UR                  S:H  =(       d    UR                  S:H  (       + nU(       aH  UR                  (       d7  UR                  (       d&  [        R                  " SR                  U 5      5        g[        R                  R                  SR                  U 5      5         [        R                   " UR"                  U R$                  U R&                  US9  U(       d/  [        R                  R                  SR                  U 5      5        gg! [        R(                   ai  n[        R*                  " S	R                  U [,        R.                  " U5      5      5        [        R*                  " S
R                  U 5      5         SnAgSnAff = f)a  Stop the previous default version if applicable.

Cases where a version will not be stopped:

* If the previous default version is not serving, there is no need to stop it.
* If the previous default version is an automatically scaled standard
  environment app, it cannot be stopped.

Args:
  old_default_version: Version, The old default version to stop.
  api_client: appengine_api_client.AppengineApiClient to use to make requests.
  wait_for_stop_version: bool, indicating whether to wait for stop operation
  to finish.
z?Previous default version [{0}] not serving, so not stopping it.Nflexr?   zgPrevious default version [{0}] is an automatically scaled standard environment app, so not stopping it.zStopping version [{0}].)service_namer/   r   zSent request to stop version [{0}]. This operation may take some time to complete. If you would like to verify that it succeeded, run:
  $ gcloud app versions describe -s {0.service} {0.id}
until it shows that the version has stopped.z!Error stopping version [{0}]: {1}zVersion [{0}] is still running and you must stop or delete it yourself in order to turn it off. (If you do not, you may be charged.))r)   r   r!   r   r   SERVINGr
   r]   r^   rL   r   basicScalingmanualScalingr   r   r	   r   StopVersionr'   r(   r   ra   rb   rc   )r   rd   r   version_objectr   is_standardr   s          r   r   r   n  s     '...##++HH+!![%8%88HH	f()+ #&& 6.*<*<*F 6#'':57+.55

&
&HH	88>9!" **,334GHI$ **(00&))#	% ! 
jj9 :@!:#	$ ! 
	+	+ 9KK3::;N;>==;MO PKK "F#679 99s   (5F H(AHH)%rw   
__future__r   r   r   r@   apitools.base.pyr   r_   googlecloudsdk.api_lib.appr   r   r	   googlecloudsdk.corer
   r   googlecloudsdk.core.utilr   r   r   rb   	six.movesr   r`   r   r   objectr!   r   r   r   r   r   r   r   r   r   r   r   r   <module>r      s     4 &  ' 	 > * 3 6 * # ' * ) * 
 Z-- *** rEf rEj=,886.(9V$6A8<$r   