
    B                        S 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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rSr\R,                  " SSS/5      rSr " S S\R2                  5      r " S S\5      r\R:                  R<                  4S j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-S$ jr-\R:                  R<                  4S% jr.S& r/S' r0S( r1S) r2S* r3S+ r4g).z6Common utility functions for Image Version validation.    )absolute_import)division)unicode_literalsN)environments_util)image_versions_util)base)flags)util)semverz1.0.0z2.1.12UpgradeValidatorupgrade_validerror   c                       \ rS rSrSrSrg)InvalidImageVersionError,   zEClass for errors raised when an invalid image version is encountered. N)__name__
__module____qualname____firstlineno____doc____static_attributes__r       >lib/googlecloudsdk/command_lib/composer/image_versions_util.pyr   r   ,   s    Mr   r   c                   (    \ rS rSrSrSS jrS rSrg)_ImageVersionItem0   zGClass used to dissect and analyze image version components and strings.Nc                 ,   SnSnSnUb-  [         R                  " XA5      S   nUS   U l        US   U l        Ub  X l        Ub  X0l        [         R                  " UU R                  5      U l        [         R                  " UU R                  5      U l        g )Nz]^composer-(\d+(?:(?:\.\d+\.\d+(?:-[a-z]+\.\d+)?)?)?|latest)-airflow-(\d+(?:\.\d+(?:\.\d+)?)?)z^(\d+|latest)$z^(\d+|\d+\.\d+)$r      )refindallcomposer_verairflow_vermatchcomposer_contains_aliasairflow_contains_alias)self	image_verr#   r$   image_version_regexcomposer_version_alias_regexairflow_version_alias_regexiv_partss           r   __init___ImageVersionItem.__init__3   s    z#4 "5/;A>h"1+d!!d&$ $&88,H,0,=,=$?D "$((+F+/+;+;#=Dr   c                 N    SR                  U R                  U R                  5      $ )Nzcomposer-{}-airflow-{})formatr#   r$   )r(   s    r   GetImageVersionString'_ImageVersionItem.GetImageVersionStringI   s!    #**4+<+<d>N>NOOr   )r'   r$   r&   r#   )NNN)r   r   r   r   r   r.   r2   r   r   r   r   r   r   0   s    O=,Pr   r   c                     [         R                  " X5      nU R                  5       nUR                  R                  R
                  nUR                  R                  R                  n[        X4XQ5      $ )z>List of available image version upgrades for provided env_ref.)environments_api_utilGetParentconfigsoftwareConfigimageVersionpythonVersion_BuildUpgradeCandidateList)env_refrelease_trackenv_detailsproj_location_refcur_image_version_idcur_python_versions         r   ListImageVersionUpgradesrC   M   sd    %))'A+nn&$++::GG"))88FF	#$5$6
G Gr   c                     [        U S9n[        U 5      nU(       d)  [        [        UR                  5      S::  d  [        S5      e[        U U5      $ )zEChecks if image version candidate is a valid upgrade for environment.r)   r   +This environment does not support upgrades.)r   IsVersionComposer3CompatibleCompareVersionsMIN_UPGRADEABLE_COMPOSER_VERr#   r    _ValidateCandidateImageVersionId)cur_image_version_strimage_version_idcur_image_veris_composer3s       r   IsValidImageVersionUpgraderO   X   sc     $%'- ., 
2M4N4NO	
 #57 7	)
 r   c                     U=(       a    [        U5      nU(       a  [        U5      R                  OSn[        UU S9R                  5       $ )z<Converts airflow-version string into a image-version string.latest)r#   r$   )rG   r   r#   r2   )new_airflow_versioncur_image_versionrN   r#   s       r   ImageVersionFromAirflowVersionrT   o   sU     # 'C(,
 
 )*77  
%
''<'<'>?r   c                 j    U SL=(       a)    U R                  S5      =(       d    U R                  S5      $ )zEChecks if string composer-X.Y.Z-airflow-A.B.C is Composer v1 version.Nzcomposer-1.zcomposer-1-
startswithimage_versions    r   IsImageVersionStringComposerV1rZ      5    	d	" 
}- 1		!	!-	0r   c                 j    U SL=(       a)    U R                  S5      =(       d    U R                  S5      $ )zEChecks if string composer-X.Y.Z-airflow-A.B.C is Composer v2 version.Nzcomposer-2.zcomposer-2-rV   rX   s    r   IsImageVersionStringComposerV2r]      r[   r   c                 j    U SL=(       a)    U R                  S5      =(       d    U R                  S5      $ )zEChecks if string composer-X.Y.Z-airflow-A.B.C is Composer v3 version.Nzcomposer-3.zcomposer-3-rV   rX   s    r   IsImageVersionStringComposerV3r_      r[   r   c                 :    U S L =(       d    U R                  S5      $ )Nzcomposer-latestrV   rX   s    r   IsDefaultImageVersionra      s    	$		M-":":;L"MMr   c                     SnU(       a  UR                  S5      $ U (       a  UR                  S5      $ UR                  S5      $ )z<Builds warning message about using default Composer version.a7  {} resolves to Cloud Composer current default version, which is presently Composer 2 and is subject to further changes in the future. Consider using --image-version=composer-A-airflow-X[.Y[.Z]]. More info at https://cloud.google.com/composer/docs/concepts/versioning/composer-versioning-overview#version-aliasesz!Using --airflow-version=X[.Y[.Z]]z7Using --image-version=composer-latest-airflow-X[.Y[.Z]]zNot defining --image-version)r1   )rY   airflow_versionmessages      r   "BuildDefaultComposerVersionWarningre      sK    q 
 >>=>>>>A  
6	77r   c                     X:X  a  gX:  a  gg)zCompares versions.r   r    r   v1v2s     r   _CompareVersionsrk      s    X	wr   c                 B    [        U 5      [        U5      p[        X5      $ )zCompares loose version strings.

Args:
  v1: first loose version string
  v2: second loose version string

Returns:
  Value == 1 when v1 is greater; Value == -1 when v2 is greater; otherwise 0.
)_VersionStrToLooseVersionrk   rh   s     r   CompareLooseVersionsrn      s!     %R(*CB*Gb	"	!!r   c                 B    [        U 5      [        U5      p[        X5      $ )zCompares semantic version strings.

Args:
  v1: first semantic version string
  v2: second semantic version string

Returns:
  Value == 1 when v1 is greater; Value == -1 when v2 is greater; otherwise 0.
)_VersionStrToSemanticVersionrk   rh   s     r   rH   rH      s!     (+-I"-Mb	"	!!r   c                     U (       a^  [        U 5      nU(       aL  UR                  (       a;  UR                  nUS:X  a  gUS:X  a  [        n[        U[        R
                  SS5      $ g)zChecks if given `image_version` is compatible with Composer 3.

Args:
  image_version: image version str that includes Composer version.

Returns:
  True if Composer version is greater than or equal to 3.0.0 or its prerelease
  variant, otherwise False.
3TrQ   NF)r   r#   #COMPOSER_LATEST_VERSION_PLACEHOLDERIsVersionInRanger	   MIN_COMPOSER3_VERSIONrY   version_itemcomposer_versions      r   rG   rG      sc     $]3L11%22	S	 	X	%>
E77
  
r   c                     U (       aK  [        U 5      nU(       a9  UR                  (       a(  UR                  n[        U[        R                  SS5      $ g)zChecks if given `version` is compatible with Composer Airflow Commands API.

Args:
  image_version: image version str that includes Composer version.

Returns:
  True if Composer version is compatible with Aiflow Commands API,
  otherwise False.
NTF)r   r#   rt   r	   $MIN_COMPOSER_RUN_AIRFLOW_CLI_VERSIONrv   s      r   %IsVersionAirflowCommandsApiCompatibler{      sL     $]3L11%22


4
4

	  
r   c                 b   U (       a  [        U 5      n[        U 5      (       a  gU(       a  UR                  (       at  UR                  (       ac  UR                  nUR                  nUS:X  a  [        n[        U[        R                  SS5      =(       a    [        U[        R                  SS5      $ g)a  Checks if given `version` is compatible with triggerer .

Args:
  image_version: image version str that includes airflow version.

Returns:
  True if given airflow version is compatible with Triggerer(>=2.2.x)
  and Composer version is >=2.0.31 otherwise False
TrQ   NF)	r   rG   r$   r#   rs   rt   r	   MIN_TRIGGERER_COMPOSER_VERSIONMIN_TRIGGERER_AIRFLOW_VERSION)rY   rw   rc   rx   s       r   IsVersionTriggererCompatibler     s     $]3L#M2200\5N5N$00o%22	X	%>
E@@$ 
5>>d
 
r   c                     U(       a  [         O[        nUSL =(       d    U" X5      S:*  =(       a    USL =(       d    U" X5      S:  $ )az  Checks if given `version` is in range of (`range_from`, `range_to`).

Args:
  version: version to check
  range_from: left boundary of range (inclusive), if None - no boundary
  range_to: right boundary of range (exclusive), if None - no boundary
  loose: if true use LooseVersion to compare, use SemVer otherwise

Returns:
  True if given version is in range, otherwise False.
Nr   )rn   rH   )version
range_fromrange_toloose
compare_fns        r   rt   rt   "  sH     (-#/*EJ!@A!E Bt@z'<q@Cr   c                    [         R                  " U5      n[        U5      n/ n[        U5      (       d  [	        [
        UR                  5      S::  ai  UR                  U 5       HR  n[        XR                  5      R                  (       d  M)  U(       a  X'R                  ;   d  MA  UR                  U5        MT     U$ [        S5      e)z1Builds a list of eligible image version upgrades.r   rF   )image_version_api_utilImageVersionServicer   rG   rH   rI   r#   ListrJ   imageVersionIdr   supportedPythonVersionsappendr   )location_refrL   python_versionr>   image_version_serviceimage_version_itemavailable_upgradesr   s           r   r<   r<   3  s    
 1DD()9: ##344	
&(:(G(G
 

 )--l;	)
22

 >>>!!'* < 
 #57 7r   c                 0    U S:X  a  [         $ [        U 5      $ )NrQ   )COMPOSER_LATEST_MAJOR_VERSIONint)composer_ver_aliass    r   _GetComposerMajorVersionr   U  s    8#((		  r   c                    U R                   (       a  [        U R                   S   5      nO*[        R                  " U R                  5      R
                  nUR                   (       a  [        UR                   S   5      nO*[        R                  " UR                  5      R
                  n[        X#:H  =(       d    US:H  =(       a    US:H  S5      $ )zDValidates whether Composer major only version upgrade is compatible.r   r      N)r&   r   r   SemVerr#   majorr   )parsed_currparsed_candmajor_version_currmajor_version_cands       r   ,_IsComposerMajorOnlyVersionUpgradeCompatibler   [  s     ((1++A.  {'?'?@FF((1++A.  {'?'?@FF 
. ?

!
=&8A&=

 r   c                    [        SS5      nX:X  a  SR                  U 5      n[        SU5      n[        U S9n[        US9nUR                  =(       d    UR                  nU(       a  [	        XE5      nO2UR
                  (       a!  [        UR                  UR                  S5      nUR
                  (       a2  UR                  (       d!  [        UR                  UR                  S5      nU$ )a  Determines if candidate version is a valid upgrade from current version.

Args:
  current_image_version_id: current image version
  candidate_image_version_id: image version requested for upgrade

Returns:
  UpgradeValidator namedtuple containing True and None error message if
  given version upgrade between given versions is valid, otherwise False and
  error message with problems description.
TNzqExisting and requested image versions are equal ({}). Select image version newer than current to perform upgrade.FrE   ComposerAirflow)
r   r1   r   r&   r   r   _IsVersionUpgradeCompatibler#   r'   r$   )current_image_version_idcandidate_image_version_idupgrade_validatorerror_messager   r   $has_alias_or_major_only_composer_vers          r   rJ   rJ   s  s     'tT2; !'(@!A  )>!,DE+!,FG+ )) -		,	, ' *D %%3  +":":J
 $$[-O-O3K4K4K4?4K4K4=?
 
r   c                 .    [         R                  " U 5      $ )z)Parses version_str into semantic version.)r   r   version_strs    r   rp   rp     s    	{	##r   c                 .    [         R                  " U 5      $ )z&Parses version_str into loose version.)r   LooseVersionr   s    r   rm   rm     s    			[	))r   c                 x   US;   d   e[        U 5      n[        U5      nX4:  a  SR                  UUU UUS9n[        SU5      $ UR                  S:w  d  UR                  S:w  aM  UR                  UR                  :w  a3  SR                  UUR                  UR                  5      n[        SU5      $ [        SS	5      $ )
a6  Validates whether version candidate is greater than or equal to current.

Applicable both for Airflow and Composer version upgrades. Composer supports
both Airflow and self MINOR and PATCH-level upgrades.

Args:
  cur_version: current 'a.b.c' version
  candidate_version: candidate 'x.y.z' version
  image_version_part: part of image to be validated. Must be either 'Airflow'
    or 'Composer'

Returns:
  UpgradeValidator namedtuple containing boolean value whether selected image
  version component is valid for upgrade and eventual error message if it is
  not.
)r   r   zUpgrade cannot decrease {composer_or_airflow1}'s version. Current {composer_or_airflow2} version: {cur_version}, requested {composer_or_airflow3} version: {req_version}.)composer_or_airflow1composer_or_airflow2cur_versioncomposer_or_airflow3req_versionFr   r   zwUpgrades between different {}'s major versions are not supported. Current major version {}, requested major version {}.TN)rp   r1   r   r   )r   candidate_versionimage_version_partcurr_semantic_versioncand_semantic_versionr   s         r   r   r     s    $ 
6	66	66{C67HI2& (.v.@.@%0.@%6 (. (8  E=11 ""a'+@+F+F!+K

%
%)>)D)D
D	 f####	  E=11	$	%%r   )N)F)5r   
__future__r   r   r   collectionsr!   googlecloudsdk.api_lib.composerr   r5   r   r   googlecloudsdk.callioper   #googlecloudsdk.command_lib.composerr	   r
   command_utilgooglecloudsdk.core.utilr   rI   rs   
namedtupler   r   Errorr   objectr   ReleaseTrackGArC   rO   rT   rZ   r]   r_   ra   re   rk   rn   rH   rG   r{   r   rt   r<   r   r   rJ   rp   rm   r   r   r   r   <module>r      s   = &  '  	 V Y ( 5 D +  '  '/ #))*<+:G*DF  !" N|11 NP P: 594E4E4H4H G.?"N8$""20:C( .2->->-A-AD!00f$
*
2&r   