
    ]                       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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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K0J$r1  SSK2J3r3  SSK2J4r4  SSK2J5r5  SSK2J6r6  SSK7J8r8  SSK7J9r9  SSK7J:r:  SSK;J<r<  SSK=J>r>  SS K?J@r@  SS!K?JArA  SS"K?JBrB  SS#K?JCrC  SSK-r-S$rDS%rES&rFS'rGS(S(S)S*S+.rHS,rIS-rJS.rKS/S0S(S1.S2S3S)S1.S4S5S*S1.S6S7S(S1.S8.rLS9rMS:rNS;rOS<rPS= rQS> rRS? rSS@ rTSA rUSB rVSC rWSD rXSE rYSF rZSG r[SH r\SI r]SJ r^SK r_SL r`SM raSN rbSO rcSP rdSQ reSR rfSS rgST rhSU\i4SV jrjSW rkSX rlSY rmSZ rnS[ roS\ rpS] rqS^ rrS_ rsS` rtSa ruSb rvSc rwSd rxSe rySf rzSg r{\|" \4R                  R:                  Sh5      R                  5       rSi\;   a  SiOSjrS7S(\ Sk.S0S(S(\ \ 3Sk.S5S*S*\ \ 3Sk.S3S)Sl\ \ 3Sk./rSm rSn rSo rSp rSq rSr rSs rSt rSu rSSv jr  SSw jr   SSx jrSSy jrSz r    SS{ jrS| r    SS} jrS~ rS rS rS rS rS rS rS rg)z/Utility for forming Artifact Registry requests.    )absolute_import)division)unicode_literalsN)futures)encoding)
exceptions)docker_name)docker_http)docker_image)	artifacts)filter_rewriter)projects_api)util)common_args)waiter)base)docker_util)remote_repo_util)requests)upgrade_util)log)
properties)	resources)yaml)console_attr)
console_io)progress_tracker)resource_printer)universe_descriptor)edit)files)parallel)	platformsz}Names may only contain lowercase letters, numbers, and hyphens, and must begin with a letter and end with a letter or number.zNames may only contain lowercase letters, numbers, hyphens, underscores and dots, and must begin with a letter and end with a letter or number.z=GCR repository {} can only be created in the {} multi-region.z+GCR repository {} must be of DOCKER format.useuropeasia)gcr.io	us.gcr.io	eu.gcr.ioasia.gcr.ioz^[a-z]([a-z0-9-]*[a-z0-9])?$z^[a-z]([a-z0-9._-]*[a-z0-9])?$zUservice-{project_num}@gcp-sa-artifactregistry.{project_prefix}iam.gserviceaccount.comzus.artifacts.{}.appspot.comr(   )bucket
repositorylocationzeu.artifacts.{}.appspot.comr)   zasia.artifacts.{}.appspot.comr*   zartifacts.{}.appspot.comr'   )r$   r%   r&   globala0  Format of the repository. REPOSITORY_FORMAT must be one of:

 apt
    APT package format.
 docker
    Docker image format.
 go
    Go module format.
 kfp
    KFP package format.
 maven
    Maven package format.
 npm
    NPM package format.
 python
    Python package format.
 yum
    YUM package format.
a9  Format of the repository. REPOSITORY_FORMAT must be one of:

 apt
    APT package format.
 docker
    Docker image format.
 googet
    GooGet package format.
 kfp
    KFP package format.
 maven
    Maven package format.
 npm
    NPM package format.
 python
    Python package format.
 yum
    YUM package format.
aW  (Virtual Repositories only) is the upstreams for the Virtual Repository.
Example of the file contents:
[
  {
    "id": "test1",
    "repository": "projects/p1/locations/us-central1/repositories/repo1",
    "priority": 1
  },
  {
    "id": "test2",
    "repository": "projects/p2/locations/us-west2/repositories/repo2",
    "priority": 2
  }
]
z=Upstream Policies should contain id, repository and priority.c                 ^    [         R                  " U R                  5       R                  5      $ N)r   MessagesGetCollectionInfoapi_versionresource_refs    0lib/googlecloudsdk/command_lib/artifacts/util.py_GetMessagesForResourcer7      s"    			L::<HH	II    c                 ^    [         R                  " U R                  5       R                  5      $ r0   )r   Clientr2   r3   r4   s    r6   _GetClientForResourcer;      s"    			,88:FF	GGr8   c                 <    [         R                  " [        U 5      S L$ r0   )rematch_REPO_REGEX)	repo_names    r6   _IsValidRepoNamerA      s    	+y	)	55r8   c                 <    [         R                  " [        U 5      S L$ r0   )r=   r>   _RESOURCE_ID_REGEX)	rule_names    r6   _IsValidRuleNamerE      s    	$i	0	<<r8   c                     U R                   =(       d2    [        R                  R                  R                   R	                  5       $ )z=Gets project resource from either argument flag or attribute.)projectr   VALUEScore	GetOrFailargss    r6   
GetProjectrM      s,    		C**//77AACCr8   c                 <    SR                  U 5      nUb  U  SU 3nU$ )Nz{}/locations/)format)rG   r-   parents      r6   	GetParentrR      s+    ;;w&yH:.F	-r8   c                     U R                   =(       d2    [        R                  R                  R                   R	                  5       $ )z@Gets repository resource from either argument flag or attribute.)r,   r   rH   r   rJ   rK   s    r6   GetReporT      s,    		NJ--77BBLLNNr8   c                     U R                   =(       d2    [        R                  R                  R                   R	                  5       $ )z>Gets location resource from either argument flag or attribute.)r-   r   rH   r   rJ   rK   s    r6   GetLocationrV      s,    		J*++55>>HHJJr8   c                 V    [         R                  " [        U 5      U R                  5      $ r0   )ar_requestsListLocationsrM   	page_sizerK   s    r6   GetLocationListr[      s    		"	":d#3T^^	DDr8   c                     [         R                  U S5      nX$:w  a)  [        R                  " [        R                  X5      5      eX:w  a)  [        R                  " [        R                  U 5      5      eg)z(Validates input for a gcr.io repository. N)_ALLOWED_GCR_REPO_LOCATIONgetar_exceptionsInvalidInputValueError_INVALID_REPO_LOCATION_ERRORrP   _INVALID_GCR_REPO_FORMAT_ERROR)r@   repo_formatr-   docker_formatexpected_locations        r6   ValidateGcrReporg      sj    044YC"

.
.$++IIK K!

.
.&--i8: : "r8   c                    U R                   n[        U5      n[        U 5      nUR                  R                  R
                  nUR                  R	                  UR                  R                  5       5      nU[        ;   a  [        X7XF5        O4[        U R                   5      (       d  [        R                  " [        5      e[        R                  " U5      (       a  [        R                   " XQU5      n[#        US5      (       a  UR$                  (       a%  UR$                  UR&                  R(                  l        UR,                  (       a%  UR,                  UR&                  R(                  l        UR0                  (       a  SUR&                  R(                  l        U R5                  5       UR&                  l        U R                   Ul        XrR&                  l        U$ )zKAdds repository data to CreateRepositoryRequest or UpdateRepositoryRequest.alternative_hostnameT)repositoriesIdrV   r7   
RepositoryFormatValueValuesEnumDOCKERrepository_formatupperr^   rg   rA   r`   ra   _INVALID_REPO_NAME_ERRORr   IsRemoteRepoRequestAppendRemoteRepoConfigToRequesthasattrri   r,   networkConfigalternativeHostname alternative_hostname_path_prefixprefixalternative_hostname_default	isDefaultRelativeNamenamerepositoryIdrP   )repo_ref	repo_argsrequestr@   r-   messagesre   rd   s           r6   AppendRepoDataToRequestr      so   %%)#($X.(%%;;BB-##99!!'')++,,IHDH3344

.
./G
HH)))44>>WG Y.//%%

(
( &&: 11

4
4 &&- --37g&&0$113'!00')	.r8   c                 p  ^ [        U 5      nUR                  (       Ga  [        UUR                  5      (       a  SUl        [
        R                  " UR                  SS9n[        R                  " U5      nUR                  5       UR                  l        / UR                  R                  l        U H  m[        U4S jS 5       5      (       aK  UR                  TS   TS   TS   S9nUR                  R                  R                  R                  U5        Mh  [         R"                  " [$        5      e   U$ )	z2Adds upstream policies to CreateRepositoryRequest.NF)binaryc              3   ,   >#    U  H	  oT;   v   M     g 7fr0    ).0keypolicys     r6   	<genexpr>2AppendUpstreamPoliciesToRequest.<locals>.<genexpr>  s     G&FsF]&Fs   )idpriorityr,   r   r   r,   )r7   upstream_policy_file
isinstance9ArtifactregistryProjectsLocationsRepositoriesPatchRequest
updateMaskr   ReadFromFileOrStdinjsonloadsVirtualRepositoryConfigr,   virtualRepositoryConfigupstreamPoliciesallUpstreamPolicyappendr`   ra   _INVALID_UPSTREAM_POLICY)r}   r~   r   r   contentpoliciespr   s          @r6   AppendUpstreamPoliciesToRequestr   
  s   $X.(###JJ   g,,&&uG zz'"H((* . CEG..?	G&FG	G	G##d|J'l+ $ 

 	22CCJJ1M223KLL  
.r8   c                  X    [        5       [        5       -   [        R                  " 5       -   $ )zAdds additional flags.)UpstreamsArgsRepoFormatArgsr   Argsr   r8   r6   AddAdditionalArgsr   +  s!    	>+	+.>.C.C.E	EEr8   c                  8    [         R                  " SS[        S9/$ )z#Adds the upstream-policy-file flag.z--upstream-policy-fileFILE)metavarhelp)r   Argument%_REPO_CREATION_HELP_UPSTREAM_POLICIESr   r8   r6   r   r   0  s#     mm
"46
 r8   c                  8    [         R                  " SS[        S9/$ z Adds the repository-format flag.z--repository-formatT)requiredr   )r   r   _REPO_CREATION_HELP_TEXTr   r8   r6   r   r   =  s#    
 mm
$5MO
 r8   c                  8    [         R                  " SS[        S9/$ r   )r   r   _REPO_CREATION_HELP_TEXT_BETAr   r8   r6   AddRepositoryFormatArgBetar   G  s#    
 mm
,.
 r8   c                     UR                   (       d  U$ UR                   n [        R                  " UR                   5      nUR                  5       nSU S3Ul        U$ ! [        R
                   a     N#f = f)zIf the target field is set, adds it to the server side request.

Args:
  unused_repo_ref: Repo reference input.
  repo_args: User input arguments.
  request: ListAttachments request.

Returns:
  ListAttachments request.
ztarget="")targetr   ParseDockerVersionStrGetVersionNamer`   ra   filter)unused_repo_refr~   r   r   docker_versions        r6   AddTargetForAttachmentsr   S  sw     
		N&	 66y7G7GHN**,F fXQ''.	. 
	-	- 		s   0A A54A5c                     UR                   (       d  U$ UR                  (       a%  U=R                  SUR                    S3-  sl        U$ SUR                    S3Ul        U$ )zIf the type field is set, add it to the server side request.

Args:
  unused_repo_ref: Repo reference input.
  repo_args: User input arguments.
  request: ListAttachments request.

Returns:
  ListAttachments request.
z AND type="r   ztype=")attachment_typer   )r   r~   r   s      r6   AddTypeForAttachmentsr   j  s\     
	"	"N^^NNI$=$=#>a@@N 
. i778:GN	.r8   c                     [         R                  " U 5      n[        R                  " 5       R                  nU(       a  US-   n[
        R                  XS9$ )z0Returns the service agent for the given project..)project_numproject_prefix)project_utilGetProjectNumberr   GetUniverseDomainDescriptorr   _AR_SERVICE_ACCOUNTrP   )
project_idr   r   s      r6   _GetServiceAgentr   ~  sS    --j9+557FF  #c)N		#	# 
$ 
 r8   c                    UR                   (       d  U$  [        [        U5      5      n[        R                  " UR                   5      nUR
                   H<  nSU-   UR                  ;   d  M  UR                  S:X  d  UR                  S:X  d  M:  Us  $    [        R                  " SR                  X1R                   S9S9nU(       d  U$  [        R                  " UR                   SU-   5        [         R"                  R%                  SR                  UR                   S	95        U$ ! [        R                   a    Sn[        R                  " U5      ef = f! [        R&                   a    Us $ f = f)
a  Checks and grants key encrypt/decrypt permission for service account.

Checks if Artifact Registry service account has encrypter/decrypter or owner
role for the given key. If not, prompts users to grant key encrypter/decrypter
permission to the service account. Operation would fail if users do not grant
the permission.

Args:
  unused_repo_ref: Repo reference input.
  repo_args: User input arguments.
  request: Create repository request.

Returns:
  Create repository request.
zserviceAccount:z*roles/cloudkms.cryptoKeyEncrypterDecrypterzroles/ownerz
Grant the Artifact Registry Service Account {service_account} permission to encrypt/decrypt with the selected key [{key_name}])service_accountkey_name)prompt_stringzThe Artifact Registry service account might not exist, manually create the service account.
Learn more: https://cloud.google.com/artifact-registry/docs/cmekzBAdded Cloud KMS CryptoKey Encrypter/Decrypter Role to [{key_name}])r   )kms_keyr   rM   rX   GetCryptoKeyPolicybindingsmembersroler   PromptContinuerP   AddCryptoKeyPermissionapitools_exceptionsHttpBadRequestErrorr`   ArtifactRegistryErrorr   statusPrintHttpForbiddenError)r   r~   r   r   r   bindinggrant_permissionmsgs           r6   CheckServiceAccountPermissionr     sR     
		N"&z)'<=O++I,=,=>F??	_	,	?
,,F
F
,,-
'	 #
 "00OVO>O>OVP	 n5(():):):_)LN JJL	**	+-
 
. 22 5A 
 //445 
	/	/ Ns<   AE -E E 5E 
$D& .6E &-EE E/.E/c                 (   UR                   (       d  U$ [        U 5      n[        U 5      nU R                  R	                  SS5      R	                  SS5      nUR	                  SS5      n[
        R                  R                  SU R                  U R                  U R                  US9n[        R                  " X4UR                  5       5      nU H@  nUR                  UR                  :w  a  M  [        R                   " X4UR                  5        MB     U$ )	z2Deletes tags associate with the specified version./%2F+%2B^%5E9artifactregistry.projects.locations.repositories.packages
projectsIdlocationsIdrj   
packagesId)delete_tagsr;   r7   r   replacer   REGISTRYCreater   r   rj   rX   ListTagsrz   versionr{   	DeleteTag)	ver_refver_argsr   clientr   escaped_pkgpackagetag_listtags	            r6   DeleteVersionTagsr     s    			N )&$W-(""**36>>sEJ+##C/+%%A##%%++ & ' !!&")"6"6"8:(c
{{gll"&CHH5  
.r8   c                 (   UR                   R                  S5      nSR                  US[        U5      S-
   5      nXBl         [	        U 5      nUR                  U R                  5       US-   UR                  -   S9nXbl        U R                  Ul
        U$ )z"Adds tag data to CreateTagRequest.r   N   
/versions/r{   r   )rQ   splitjoinlenr7   Tagrz   r   r   tagsIdtagId)tag_reftag_argsr   partspkg_pathr   r   s          r6   AppendTagDataToRequestr    s    
..

s
#%XXeOSZ!^,-(.$W-(!%(8(88 	 	:# +..'-	.r8   c                    [        U 5      nUR                  R                  S5      nSR                  US[	        U5      S-
   5      nUR                  U R                  5       US-   UR                  -   S9nXbl        SUl	        U$ )z%Sets update mask to UpdateTagRequest.r   Nr   r   r   r   )
r7   r{   r   r   r   r   rz   r   r   r   )r  r  r   r   r  r  r   s          r6   SetTagUpdateMaskr    s    $W-(
,,

S
!%XXeOSZ!^,-(!%(8(88 	 	:# + '	.r8   c                     U R                   R                  SS5      R                  SS5      nUR                  SS5      nSR                  U R                  5       R	                  5       U5      Ul        U$ )zCEscapes slashes and pluses in package name for ListVersionsRequest.r   r   r   r   r   r   z{}/packages/{})r   r   rP   Parentrz   rQ   )pkg_refunused_argsr   r   s       r6   EscapePackageNamer    sh    ""**36>>sEJ+##C/+#**nn##%'. 
.r8   pkgc                 f    U R                  SS5      R                  SS5      R                  SS5      $ )z:Escapes slashes and pluses in package name of type string.r   r   r   r   r   r   )r   )r  s    r6   EscapePackageStrr    s-    	S%	 	(	(e	4	<	<S%	HHr8   c                     [         R                  " UR                  5      nSnUb  SU;  a  X2l        OSnUR                  b6  UR
                  c)  U(       a"  UR                  Ul        UR                  Ul        U$ )z6Adds order_by and page_size parameters to the request.T,F)r   ParseSortByArgsort_byorderBylimitr   pageSizerZ   )
unused_refr   r   order_by	set_limits        r6   AppendSortingToRequestr    si    ''(8(89() 
( oinn X__%<~~G!H	.r8   c                 >   / nU  H  n[         R                  R                  UR                  5      Ul        UR                  R	                  SS5      R	                  SS5      Ul        UR                  R	                  SS5      Ul        UR                  U5        M     U$ )zGUnescapes slashes and pluses in package name from ListPackagesResponse.r   r   r   r   r   r   )ospathbasenamer{   r   r   )responser  retvers       r6   UnescapePackageNamer"    sz    
#cww)CHxxs+33E3?CHxxs+CHJJsO	 
 
*r8   c                    UR                   R                  S5      nSR                  US[        U5      S-
   5      Ul         [	        U R
                  5      (       d  [        R                  " [        5      eU R
                  Ul	        U$ )z$Adds rule data to CreateRuleRequest.r   Nr   )
rQ   r   r   r   rE   rulesIdr`   ra   _INVALID_RULE_NAME_ERRORruleId)rule_refr  r   r  s       r6   AppendRuleDataToRequestr(  %  sk    
..

s
#%88E"2CJN34'.	(**	+	+

.
./G
HH##'.	.r8   c                     [         R                  R                  SR                  [	        U5      [        U5      5      5        U $ )zAAdds log to clarify parent resources for ListRepositoriesRequest.-Listing items under project {}, location {}.
)r   r   r   rP   rM   rV   r  rL   s     r6   #AppendParentInfoToListReposResponser,  /  s6    **CJJD)+ ,	/r8   c           	          [         R                  R                  SR                  [	        U5      [        U5      [        U5      5      5        U $ )z=Adds log to clarify parent resources for ListPackagesRequest.z<Listing items under project {}, location {}, repository {}.
)r   r   r   rP   rM   rV   rT   r+  s     r6   &AppendParentInfoToListPackagesResponser.  6  s>    **ELL
T
K-wt}>? 
/r8   c           	          [         R                  R                  SR                  [	        U5      [        U5      [        U5      UR                  5      5        U $ )zBAdds log to clarify parent resources for ListVersions or ListTags.zHListing items under project {}, location {}, repository {}, package {}.
)r   r   r   rP   rM   rV   rT   r   r+  s     r6   -AppendParentInfoToListVersionsAndTagsResponser0  >  sG    **f
T
K-wt}dllLM 
/r8   c           
          [         R                  R                  S[        U5       S[	        U5       S[        U5       S35        U $ )z:Adds log to clarify parent resources for ListRulesRequest.zListing items under project z, location z, repository z.
)r   r   r   rM   rV   rT   r+  s     r6   #AppendParentInfoToListRulesResponser2  G  sI    **$Z%5$6 7

d
	M'$-= 
/r8   c                 F    [        X5      nS n[        [        X25      5      $ )zAGets a list of GCR repositories given a list of GCR bucket names.c                     U S   $ )Nr,   r   )r+   s    r6   RepoMsgGetGCRRepos.<locals>.RepoMsgT  s    ,r8   )GetExistingGCRBucketslistmap)bucketsrG   existing_bucketsr5  s       r6   GetGCRReposr<  P  s$    *7<  
c',	--r8   c                 <   / nUnSU;   a$  UR                  S5      u  pESR                  XT5      nU R                  5        H>  n [        R                  " US   R                  U5      U5        UR                  U5        M@     U$ ! [        R                   a     M[  f = f)z<Gets the list of GCR bucket names that exist in the project.:z{}.{}.ar+   )r   rP   valuesrX   TestStorageIAMPermissionr   r   HttpNotFoundError)r:  rG   r;  project_id_for_bucketdomainr   r+   s          r6   r7  r7  Z  s    !G^ s+F%,,Z@ f**


!
!"7
8'Cf%	 ! 
 00 s   :BBBc           	      r  ^^^ [        U 5      nU R                  =(       d2    [        R                  R                  R                  R                  5       n/ mU(       aU  US:w  aO  [        R                  R                  SR                  X5      5        TR                  SR                  X5      5        Ou[        R                  " U5      n[        R                  R                  SR                  U5      5        TR                  U Vs/ s H  nSR                  X5      PM     sn5        T(       a  [        T5      OSm[        R                   R#                  5       [        R                   R$                  L a  T(       a  [&        R(                  " 5       OSmU R*                  n[,        R.                  " U R0                  5      n[2        R4                  " 5       R7                  U R8                  5      u  pxUb  SU;   a  SnU R:                  b0  U R8                  b#  Ub  U R:                  nU R:                  U l        OSn SS jmSUUU4S	 jjn	/ n
UUUS
.n[=        U	40 UD6u  pU H  nU
R                  U5        M     U(       d5  US   (       a  SU l        US   (       a  US   U R8                  :X  a  SU l        U
$ s  snf )zLists repositories in a given project.

If no location value is specified, list repositories across all locations.

Args:
  args: User input arguments.

Returns:
  List of repositories.
r   r*  zprojects/{}/locations/{}z6Listing items under project {}, across all locations.
   Nr  c                      [         R                  " U UUUS9$ ! [        R                   aB  nUR                  S:  a,  [
        R                  " SR                  U 5      5        / s SnA$ e SnAff = f)zbLists repositories in a given project and location, and if an error occurs, returns an empty list.rZ   r  server_filteri  z*Failed to list repositories for project {}N)rX   ListRepositoriesr   	HttpErrorstatus_coder   warningrP   )rG   rZ   r  rH  es        r6   ListLocationRepos+ListRepositories.<locals>.ListLocationRepos  sq    ))
%	  (( 		
	8??	

 		s     A/6A*#A/)A**A/c                 f  >^ ^^ [         R                  " T5      n UR                  5         UR                  U	UU U4S jT
5      n UR                  5         U$ ! [         R                   a  nT(       d  T(       aY  UR
                   HI  nUR                  S:X  d  M  [        R                  " UR                  UR                  UR                  5      e   [        S UR
                   5       5      nSR                  U5      n[        R                  " U5      eS nAff = f! UR                  5         f = f)Nc                    > T" U TTTS9$ )NrG  r   )xrN  r  rZ   rH  s    r6   <lambda>5ListRepositories.<locals>.ListRepos.<locals>.<lambda>  s    %!)	r8   i  c              3   8   #    U  H  oR                   v   M     g 7fr0   )r   )r   errs     r6   r   6ListRepositories.<locals>.ListRepos.<locals>.<genexpr>  s     6XckkX   
)r"   GetPoolStartMap
MultiErrorerrorsrK  r   r   r   urlsetr   r`   r   Join)rZ   r  rH  poolresultsrM  rV  	error_setr   rN  	loc_paths	pool_sizes   ```      r6   	ListRepos#ListRepositories.<locals>.ListRepos  s    I&D
jjl g( iikN  	5	(88C__#%99S__cgg  
 6QXX66iIIi c//44	5 iiks*   )A D,+DA;DDD D0)rH  rZ   r  r  rH  )NNN)rM   r-   r   rH   r   Getr   r   r   rP   r   rX   rY   extendr   r#   OperatingSystemCurrentWINDOWSmultiprocessing	cpu_countrZ   r   r  r  r   RewriterRewriter   r  RetryOnInvalidArguments)rL   rG   r-   location_listlocrZ   r  _rH  rg  reposserver_argsserver_args_skippedresultsublistrN  re  rf  s                  @@@r6   rI  rI  l  sQ    t']]Hj//99BBFFH()(e#JJELL /66wIJ--g6MJJAHH	 CPCPC"))'7=  !*c)nq)&&(I,E,E,M,MM/8))+aInn)''5($--/77D!
h h	ZZ 7 **izzdn i =A, 6 %$+
 !8!! g	LL 
 
:dlO$(DKK7dk	,Gs   J4c                 f    U " S0 UD6nSU4$ ! [         R                   a  n[        US5      (       af  UR                  (       aU   [        R
                  " UR                  5      nUS   S   S:X  a  UeO%! [        R                  [        [        4 a     Of = fUS   (       a;  SUS'   UR                  S5      (       a  SUS'   UR                  S	5      (       a  SUS	'   UR                  S
5      (       a  SUS
'   SU " S0 UD64s SnA$ SnAf[         a  n[        R                  " U5      eSnAff = f)ad  Retry the request on invalid arguments error.

If the request fails with 400 because of unsupported server-side filter or
sort-by, retry the request with no filter or sort-by.

Args:
  func: Retry function.
  **kwargs: User input arguments.

Returns:
  retried: If the request is retried without server-side filter or sort-by.
  results: List of results.

Fr   errorr   FAILED_PRECONDITIONrH  NrZ   r  r  Tr   )r   r   rs   r   r   r   JSONDecodeErrorKeyError	TypeErrorr_   	Exceptionr`   r   )funckwargsrc  rM  r   s        r6   rr  rr    s!   1nVnG'>		0	0  q)**QYY'7H%)>>' ?""Hi8 o $f_ 
K	 	 "{	G		wzz*fZ	 1

-
-a
001sK    D0"D.A43D4BDBA,DD0D0D++D0c                     U R                   (       a!  [        R                  R                  S5        U $ [        R                  R                  S5        U $ )z,Adds encryption info log to repository info.z Encryption: Customer-managed keyzEncryption: Google-managed key)
kmsKeyNamer   r   r   r  r  s     r6    AddEncryptionLogToRepositoryInfor    s?    JJ78 
/ JJ56	/r8   c           
      x   U R                   (       d  [        R                  R                  U R                  SS9n[
        R                  R                  SR                  UR                  [        U R                  5      R                  5       UR                  R                  SS5      UR                  5      5        U $ )zIAdds the base URL of the repo for registry operations to repository info.z0artifactregistry.projects.locations.repositories
collectionz!Registry URL: {}-{}.pkg.dev/{}/{}r>  r   )registryUrir   r   ParseRelativeNamer{   r   r   r   rP   r   strlowerr   r   rj   )r  r  r@   s      r6   AddRegistryBaseToRepositoryInfor    s    			""44E 5 I JJ+22!! &&(  ((c2$$		
 
/r8   c                    U R                   b<  [        R                  R                  SR	                  U R                   S-  5      5        O.[        R                  R                  SR	                  S5      5        S U l         U $ )NzRepository Size: {0:.3f}MBg    .Ar   )	sizeBytesr   r   r   rP   r  s     r6   ConvertBytesToMBr  0  sk    #JJ1889K9K9<:= > ? JJ188;<(	/r8   c                 *   U R                   R                  SS5      R                  SS5      nUR                  SS5      n[        R                  R	                  SU R
                  U R                  U R                  US9nUR                  5       Ul	        U$ )	.Escapes slashes and pluses from request names.r   r   r   r   r   r   r   r   )
r   r   r   r   r   r   r   rj   rz   r{   )refr  reqr   r   s        r6   EscapePackageNameHookr  :  s    &&sE2::3F+##C/+%%A//'' & ' !!##(	*r8   c                    U R                   R                  SS5      R                  SS5      nUR                  SS5      n[        R                  R	                  SU R
                  U R                  U R                  UU R                  R                  SS5      R                  SS5      S9nUR                  5       Ul
        U$ )	r  r   r   r   r   r   r   z>artifactregistry.projects.locations.repositories.packages.tags)r   r   rj   r   r   )r   r   r   r   r   r   r   rj   r   rz   r{   )r  r  r  r   r   s        r6   EscapeTagNameHookr  H  s    &&sE2::3F+##C/+!!F//''ZZU+33C? 	" 	A# #(	*r8   c           	         U R                   R                  SS5      R                  SS5      nUR                  SS5      nU R                  R                  SS5      R                  SS5      nUR                  SS5      n[        R                  R                  SU R                  U R                  U R                  UUS9nUR                  5       Ul
        U$ )	r  r   r   r   r   r   r   zBartifactregistry.projects.locations.repositories.packages.versions)r   r   rj   r   
versionsId)r   r   r  r   r   r   r   r   rj   rz   r{   )r  r  r  r   escaped_verr   s         r6   EscapeVersionNameHookr  W  s    &&sE2::3F+##C/+&&sE2::3F+##C/+%%J//'' & ' !!##(	*r8   gcr_host-r   )r,   r-   hosteuc                    0 nU (       d  U$ / n[         R                  " 5       nU  Hc  nUS/n/ n[         H2  nSR                  XGS   US   5      n [        R
                  " U5        M4     UR                  U5        U(       d  M_  XaU'   Me     [        R                  R                  S5        [        R                  " S[        R                  S9n	U	R                  UR                  S	S
S9UR                  SS
S9/5        U H  n
U	R!                  U
5        M     U	R#                  5         [        R                  R                  5         U$ ! [        R                   a#    US==   S-  ss'   UR                  U5         GMI  f = f)a  Prints a redirection enablement report and returns mis-configured repos.

This checks all the GCR repositories in the supplied project and checks if
they each have a repository in Artifact Registry create to be the redirection
target. It prints a report as it validates.

Args:
  projects: The projects to validate

Returns:
  A list of the GCR repos that do not have a redirection repo configured in
  Artifact Registry.
r   (projects/{}/locations/{}/repositories/{}r-   r,   rE  zProject Repository Report:
tableoutProjectTboldz)Missing Artifact Registry Repos to Create)r   GetConsoleAttr	gcr_reposrP   rX   GetRepositoryr   rA  r   r   r   r   r   Printer
AddHeading	Emphasize	AddRecordFinish)projectsmissing_reposrepo_reportconrG   report_linep_reposgcr_repoar_repo_nameprinterlines              r6   *GetMultiProjectRedirectionEnablementReportr    se    -	+##%# gA,KG?FF
J',)?l!!!,/  {#w&G   **12$$W#**='		mmIDm)	mm?dmK  dd 	..**	# !22 !A!x  !s   E2E>=E>c           
      ,   / n/ n[         R                  " 5       n[        [        R                  R
                  S5      R                  5       n[         H  n[        S:w  a  U(       a
  XES   :w  a  M  US   US   /nSR                  XS   US   5      n [        R                  " U5      nUR                  UR                  UR                  S5      5        UR                  U5        M     ["        R$                  R'                  S	U  S
35        [(        R*                  " S["        R$                  S9n	U	R-                  UR/                  SSS9UR/                  SSS9UR/                  SSS9/5        U H  n
U	R1                  U
5        M     U	R3                  5         ["        R$                  R'                  5         U$ ! [        R                    aH    UR                  UR                  SR                  US   5      S5      5        UR                  U5         GN>f = f)a  Prints a redirection enablement report and returns mis-configured repos.

This checks all the GCR repositories in the supplied project and checks if
they each have a repository in Artifact Registry create to be the redirection
target. It prints a report as it validates.

Args:
  project: The project to validate

Returns:
  A list of the GCR repos that do not have a redirection repo configured in
  Artifact Registry.
r-   r'   r  r  r,   greenz&None Found. Can create repo named "{}"yellowzRepository report for :
r  r  zContainer Registry HostTr  LocationzArtifact Registry Repository)r   r  getattrr   rH   r   ri  r  gcr_baserP   rX   r  r   Colorizer{   r   rA  r   r   r   r   r  r  r  r  r  )rG   r  r  r  r-   r  r  r  ar_repor  r  s              r6   GetRedirectionEnablementReportr    s    -+##%#Z&&00*=AAC( h8X*9M-MF#Xj%9:K=DD*%x'=?L%)),7ggllG<= {#) , **+G9C89$$W#**='		mm-Dm9	mmJTm*	mm2m> 
 dd 	..**	/ 00 	%
,,6==<( 	 8$	%s   AF77AHHc                 t   / n[        [        R                  R                  S5      R	                  5       n[
         H^  n[        S:w  a  U(       a
  X#S   :w  a  M  SR                  XS   US   5      n [        R                  " U5        UR                  U5        M`     U$ ! [        R                   a     M{  f = f)z5Gets the already created repos for the given project.r-   r'   r  r,   )r  r   rH   r   ri  r  r  rP   rX   r  r   r   rA  )rG   found_reposr-   r  r  s        r6   GetExistingReposr    s    +Z&&00*=AAC(h8X*9M-M=DD*%x'=L-"  
 00 s   2'BB76B7c                 .    UR                   S-   Ul         U$ )Nz/projectSettings)r{   )r  r  r  s      r6   UpdateSettingsResourcer    s    XX**#(	*r8   c                 Z    [        U5      n[        U5      n[        R                  " X#5      $ r0   )rM   rV   rX   GetVPCSCConfigr  rL   rG   r-   s       r6   r  r    s'    t'(		#	#G	66r8   c                 Z    [        U5      n[        U5      n[        R                  " X#5      $ r0   )rM   rV   rX   AllowVPCSCConfigr  s       r6   r  r    s'    t'(		%	%g	88r8   c                 Z    [        U5      n[        U5      n[        R                  " X#5      $ r0   )rM   rV   rX   DenyVPCSCConfigr  s       r6   r  r    s'    t'(		$	$W	77r8   c           	         [         R                  R                  R                  R	                  5       nUR                  S5      (       a  SnOSn[        R                  " 5       n[        R                  R                  UR                  SSS95        [        R                  R                  SU  SU S	U S
3R                  X!S95        g)zLogs a message about how to grant the user permission to perform migration steps.

Args:
  project: The project missing permission
zgserviceaccount.comserviceAccountuserz
You can get permission to perform all migration steps if a project owner grants you roles/artifactregistry.containerRegistryMigrationAdmin:Tr  z)  gcloud projects add-iam-policy-binding z
 --member=r>  zA --role='roles/artifactregistry.containerRegistryMigrationAdmin'
)rw   r  N)r   rH   rI   accountri  endswithr   r  r   r   r   r  rP   )rG   r  rw   r  s       r6   LogUserPermissionDeniedErrorr    s     
					'	'	+	+	-$	]]())FF##%#**	mmE 	   **1' ;4& bdvVv'r8   c                    Sn[        [        R                  R                  S5      nUR	                  5       nU(       a  SU;   a  SnUR                  S5        0 n U  H&  n [        R                  " U5      R                  XE'   M(     US:X  a  UR                  U5        U$ ! [        R                   a  n[        U5        UeSnAff = f! US:X  a  UR                  U5        f f = f)a5  Gets the redirection states for the given projects.

Args:
  projects: The projects to get the redirection states for

Returns:
  A dictionary of project to redirection state.
raises:
  apitools_exceptions.HttpForbiddenError: If the user does not have permission
  to get the redirection state for a project.
prodartifactregistrystaging(https://artifactregistry.googleapis.com/N)r  r   rH   api_endpoint_overridesri  SetrX   GetProjectSettingslegacyRedirectionStater   r   r  )r  envendpoint_propertyold_endpointredirection_statesrG   rM  s          r6   GetRedirectionStatesr  5  s     	#..0B #&&(,i</
C DE*&1&D&D'

 
  	#  iL)	 !33 $W- iL) s0   C  "BC C3C  CC C"c           	         [        [        R                  R                  S5      nUR	                  5       nSn U(       a  SU;   a  SnUR                  S5        [        R                  " XU5         US:X  a  UR                  U5        g! [        R                   a  n[        R                  " 5       n[        R                  " S[        U5      5      nU(       d  [        U 5        e [         R"                  R%                  UR'                  SS5      SR)                  US	   U S
9-   5         SnAUS:X  a  UR                  U5        ggSnAff = f! US:X  a  UR                  U5        f f = f)z2Sets the redirection status for the given project.r  r  r  r  &requires (.*) to have storage.objects.
ERROR:reda#   The Artifact Registry service account doesn't have access to {project} for copying images
The following command will grant the necessary access (may take a few minutes):
  gcloud projects add-iam-policy-binding {project} --member='serviceAccount:{p4sa}' --role='roles/storage.objectViewer'
rE  )p4sarG   NFT)r  r   rH   r  ri  r  rX   SetUpgradeRedirectionStater   r   r   r  r=   searchr  r  r   r   r   r  rP   )	rG   r   pull_percentr  r  r  rM  r  r>   s	            r6   SetRedirectionStatusr  [  sO   ..0B #&&(,#*	\1c FG**7LI& iL)	) 
	/	/ 

%
%
'CII>AGE"7+JJZ'1 28q7 28 2
	
	 
iL) %$ iL) s*   7B E	BE'E E		E E&c                 
   [         R                  " 5       nUR                  (       a  UR                  n	[        R
                  " U5      S   n
[        R                  " SU
05      n[        R                  " [        R
                  " U 5      5      R                  SS5      S   nU(       a	  SU SU 3nOASU S3nO:[        R
                  " U 5      n[        R                  " U5      nU(       d  US-  nSn	S	U S
U SU S3nU(       a  [        R                  R                  SU S
U S35        U(       a^  [        R                  R                  UR                  SS5       SU 35        SSR                  UR                  S5      5      -   nU SU 3n[        R                  R                  XsU S35      n[         R"                  " [         R$                  " U5      USS9  g[        R                  R                  UR'                  SR)                  XC5      SS95        [        R                  R                  U5        SnU(       a  USUR                  SS5       SU S3-  n[*        R,                  " 5       (       d>  [        R                  R                  U5        [        R                  R                  S5        Sn[         R                  " 5       n / n/ nU(       a$  SR)                  U(       a  SOSX45      S S!S"/n/ S#QnOtSR)                  U(       a  SOSX45      UR                  S$S%5      -   S S!UR                  S&U S
UR/                  S'S
5       S(3S5      -   S)UR                  S*S5      -   S"/n/ S+Qn[*        R0                  " UUSS,9nUS-:  d  U[3        U5      :  a  [5        S.U 35      eUU   S/:X  a  [        R                  R                  S0R)                  X45      5        [        R6                  " [8        R:                  " 5       R<                  [        R>                  " U5      5      nU	(       a  U	Ul         [8        R@                  " S1R)                  X2U5      U5        gUU   S6:X  a=  [L        RN                  " U5      nUR'                  S7SS9S8R)                  U5      -   nSnGM  UU   S9:X  a  gUU   S::X  a  gUU   S;:X  a  [*        RP                  " 5       e[5        S<UU    35      e! [B        RD                   aY  n[        R                  R                  S2R)                  [F        RH                  " URJ                  5      S3   S4   5      5        UeS5nAff = f)=z@Prompts the user to possibly change the repository's iam policy.r   rY  rE  z# Existing repository policy:
z
# New additions:
z
# No new bindings addedz
# No bindings neededr]   zGenerated bindings for r   z` may be insufficient because you do not have access to analyze IAM for the following resources: z`
See https://cloud.google.com/policy-intelligence/docs/analyze-iam-policies#required-permissionsz
Writing bindings for z...Warning:r   z# z
# 

.yamlT)create_pathz7
Potential IAM change for {} repository in project {}:
r  zThis IAM policy will grant users the ability to perform all actions in Artifact Registry that they can currently perform in Container Registry. This policy may allow access that was previously prevented by deny policies or IAM conditions.z
Prompting is disabled. To make interactive iam changes, enable prompting. Otherwise, manually add any missing Artifact Registry permissions and rerun using --skip-iam-update.Fz9Apply {} policy to the {}/{} Artifact Registry repositoryeditedabovezEdit policyz%Do not copy permissions for this repoExit)applyr    skipexitz" (preserves accesss for GCR users)r  z (users may lose access to r>  )z/Skip permission copying for all remaining reposz/ (users may lose access to all remaining repos))r  r    r  skip_allr  )messageoptionsdefaultr   zUnknown option: r  z#Applying policy to repository {}/{}r  !
Failed to update iam policy:
{}
r|  r  Nr    z
Edited policy:z

{}
r  r  r  zUnknown choice: ))r   r  r   etagr   MessageToDictr   dumpr   r   r   r   r  r   r  r  r!   WriteFileContentsExpandHomeDirr  rP   r   	CanPromptr   PromptChoicer   
ValueErrorPyValueToMessagerX   GetMessagesPolicyloadSetIamPolicyr   rJ  r   r   r   r    
OnlineEditOperationCancelledError)policy_additionexisting_policyr-   rG   repofailurespkg_devoutput_iam_policy_dirr  r  existing_policy_bindingsexisting_string
new_stringstring_policydwarning_messagecommented_warningoutfiler  r  cchoicesr  optionnew_bindingrM  s                             r6   RecommendAuthChanger#    s_    	##%#D  (55oF  ii-E FGO811/BCIIa	J +O+< =$'  ,O+< =  
 	/AIIaLM//mD 	 y$ 0'jee  JJ.wiqcBC	jj#,,z59:!O;LMN_-B-B4-H!II*+4?mggll0dV5>JG 
G$m **	mm
E
L
L 	   **=!* 
 cll:u56a7HMMG					JJWJJ	 &!!#!GG
E
L
L hgw 
1
g 2g F
L
L hgw JJ;WEF 
1JJ+D67??33L2MQO
 <JJ? g" >g$$F
 zVs7|+)&233v'!	jj
/
6
6w
E --

!
!
#
*
*DIIm,Dk 
  6==4 		
  
F	"oom4m
4  


M
*+g f	F	"	J	&	F	"..00)'&/):;<<1 !** 

299

199%g.y9	

 s   8'S) )U=AUUc                 N   SnU H6  nUS   U;   n[        U U US   UUUUUS9u  pU	(       a  SnU
(       a  M2  US4s  $    U(       d]  U(       dV  [        R                  " 5       n[        R                  R                  UR                  SS5      SR                  U 5      -   5        US4$ )z0Sets up auth for all repos in the given project.Fr,   r  input_iam_policy_diruse_analyzeTOK: r  z`All Container Registry repositories have equivalent Artifact Registry permissions for project {})SetupAuthForRepositoryr   r  r   r   r   r  rP   )rG   rv  repos_with_bucketsr  r&  r'  diffs_foundr  
has_bucket
repo_diffscontinue_auth_checkr  s               r6   SetupAuthForProjectr/  2  s     +dl#'99J&<\31	'#J k%   
1

%
%
'CJJVW%//5vg	?
 
d	r8   c                 N    U (       a  SnOSn[         R                  " SU 3SSS9  g )Nr]   z@ If you continue, users may lose access to *gcr.io repositories.zCannot generate a new IAM policy because you do not have permission to view existing policies. See https://cloud.google.com/policy-intelligence/docs/analyze-iam-policies#required-permissions for required permissions.z%Continue without updating IAM policy?T)cancel_on_no)r   r   )r  rL  s     r6   WarnNoAuthGeneratedr2  V  s6    GPG# $+)- .r8   c                 r   [         R                  " [        5      n[        R                  " U5      n[         R                  " [        5        U R                  5        HX  u  pVUR                  X   5      X5'   X5   R                  XE   5      X5'   [        [        S X5   5      5      X5'   X5   (       a  MV  X5	 MZ     U$ )zGCalculates auth that should be added to a Repository to match GCR auth.c                     U R                  S5      (       + =(       a3    U R                  S5      (       + =(       a    U R                  S5      (       + $ )Nz*@containerregistry.iam.gserviceaccount.comz/gcp-sa-artifactregistry.iam.gserviceaccount.comz@artifact-registry-same-project-copier@system.gserviceaccount.com)r  )members    r6   rS  &CalculateMissingAuth.<locals>.<lambda>q  sP    v<    OOA  OOR r8   )collectionsdefaultdictr`  r   map_from_policyitems
differencer   )gcr_authar_non_repo_authar_repo_policymissing_authar_repo_mapr   gcr_memberss          r6   CalculateMissingAuthrB  e  s    ((-,,,^<+##>>+d$//0@0FGL%+66{7HIL  	
L 

) ,* 
r8   c	                 V   U(       Ga   [         R                  " [        R                  R	                  [         R
                  " U5      UUS    S35      5      n	[        R                  " 5       n
[        R                  R                  U
R                  SU SUS    3S5      5        [        R                  " [        R                   " 5       R"                  [$        R&                  " U	5      5      n [        R(                  " S	R+                  XS
   US   5      U5        g[6        R8                  " [:        R<                  " U(       a  UOSU U(       + SSUS95      u  pU(       d  U(       a
  [?        US9  g[6        R8                  " [:        R<                  " SUSSSUS95      u  nn[        R@                  " S	R+                  XS
   US   5      5      n[C        XU5      nU(       d  U(       a.  [E        [:        RF                  " U5      UUS
   UUS   UUUS9nSU4$ U(       aZ  [        R                  " 5       n
SU SUS    SU S3n[        R                  R                  SU
R                  SS5       SU 35        gg! [         R                   a,    [        R                  R                  SU SUS    S35         gf = f! [,        R.                   aY  n[        R                  R                  SR+                  [0        R2                  " UR4                  5      S   S   5      5        UeSnAff = f)a  Checks permissions for a repository and prompts for changes if any is missing.

Checks permission for a repository and provides a list of users/roles that had
permissions in GCR but are missing equivalent roles in AR. Prompts the user to
add these roles, edit them, or keep permissions the same.

Args:
  gcr_project: The GCR project
  ar_project: The AR project
  host: The GCR host (like gcr.io)
  repo: The AR repo being copied to
  has_bucket: Whether a GCR bucket exists for this repository
  pkg_dev: If true, this is for a single pkg.dev repo (prompts are different)
  output_iam_policy_dir: If set, output iam files to this dir
  input_iam_policy_dir: If set, use iam files from this dir
  use_analyze: If true, use AnalyzeIamPolicy to generate the policy

Returns:
  A tuple of (diffs_found, should_continue) where diffs_found is true if
  there were auth diffs found between GCR + AR and should_continue is true
  if the tool should continue recommending auth changes for subsequent
  repos.
r,   r  zNo policy change found for r   z. Skipping this repository.)FTzApplying policy to repository r  r  r-   )TTr  r|  r  Nr]   FT)skip_bucketfrom_ar_permissionsbest_effortr'  )r  )TF)r  r  r  z#Unable to confirm IAM bindings for za are sufficient because you do not have access to view IAM bindings for the following resources: z'
Use --log-http to see detailed errors.rY  r  r  r  )$r!   ReadFileContentsr  r  r   r  MissingFileErrorr   r   r   r   r  r  r   r
  rX   r  r  r   r  r  rP   r   rJ  r   r   r   copydeepcopyr   iam_mapr2  GetIamPolicyrB  r#  policy_from_map)gcr_project
ar_projectr  r  r,  r  r  r&  r'  r  r  r"  rM  r<  r  r=  ru  r>  r?  continue_checking_authr  s                        r6   r)  r)    s#   F ,,
'',,!!"67l#$E*m 
%
%
'CJJ,ZL$|:L9MN	
 ++!(($))M*BK
4
;
;z*D,> 	  }}$"
%~#!	( 
h(

"!	A ++077
:&\(:.
 &., *0$$\2Z\3	 '''

%
%
'C	<ql+, -:=	?  JJr#,,z59:!O;LMN	u !! 	jj'
|1T,5G4H I' ' 0 (( 	jj
0
7
7jj#G,Y7
 gs+   AI8 /-J; 8=J87J8;L(AL##L(c                 h'   UR                   (       a1  UR                   R                  S5      n[        R                  " 5         OFUR                  =(       d2    [
        R                  R                  R                  R                  5       /n/ nU Hn  nUR                  5       (       aE  UR                  [        R                  " [        R                  " U5      5      R                  5        M]  UR                  U5        Mp     UnUR                   nUR"                  nUR$                  nUR&                  nUR(                  n	UR*                  n
UR,                  nUR.                  nUR0                  nUR2                  nU(       a<  U(       d5  [4        R6                  R9                  S5        [:        R<                  " S5        UbA  US:  d  US:  a5  [4        R6                  R9                  S5        [:        R<                  " S5        UR>                  nUR@                  nU(       aC  U(       d  U	(       a5  [4        R6                  R9                  S5        [:        R<                  " S5        U(       aC  U(       d  U	(       a5  [4        R6                  R9                  S	5        [:        R<                  " S5        U(       a<  U(       a5  [4        R6                  R9                  S
5        [:        R<                  " S5        U(       am  [B        RD                  RG                  [H        RJ                  " U5      5      (       d5  [4        R6                  R9                  S5        [:        R<                  " S5        U
bA  U
S:  d  U
S:  a5  [4        R6                  R9                  S5        [:        R<                  " S5        UR                   (       d  UR                  (       aC  U(       d  U(       a5  [4        R6                  R9                  S5        [:        R<                  " S5        [M        U5      [M        U5      :w  a5  [4        R6                  R9                  S5        [:        R<                  " S5        U(       a<  U(       a5  [4        R6                  R9                  S5        [:        R<                  " S5        U(       Ga  UR                  SS5      n[O        U5      S:w  a5  [4        R6                  R9                  S5        [:        R<                  " S5        Uu  nnUR                  SS5      n[O        U5      S:w  a5  [4        R6                  R9                  S5        [:        R<                  " S5        Uu  nnSU;   a5  [4        R6                  R9                  S5        [:        R<                  " S5        U[P        RS                  5       ;  ad  [4        R6                  R9                  SRU                  USRW                  [P        RS                  5       5      S95        [:        R<                  " S5        [P        U   nU(       a  UnSRU                  [
        R                  RX                  RZ                  R                  5       U5      nU	(       d  []        UUUU5        [_        [`        Rc                  5        VVs0 s H  u  nnUS   U:X  d  M  UU_M     snnU5      nU(       d  U(       a'  [d        Rf                  " SU SU SU S3S S!9nU(       d  g[i        UUUUUS".US UUUS#9	u  nnU(       aK  U(       a$  [4        R6                  R9                  S$U S%35        g[4        R6                  R9                  S&5        g[k        U/UUUUURl                  S'9(       d  gU	(       d3  [4        R6                  R9                  S(RU                  UUS-   U-   S)95        g[n        Rp                  " 5       nU	(       a  Un/ n / n!/ n"/ n#GO[s        U5      n$/ n / n!/ n/ n"/ n#U$Rc                  5        H  u  nn%U%URt                  Rv                  Rx                  :X  a  U R                  U5        M=  U%URt                  Rv                  Rz                  :X  a  UR                  U5        Mt  U%URt                  Rv                  R|                  :X  a  U!R                  U5        M  U%URt                  Rv                  R~                  :X  a  U#R                  U5        M  U"R                  U5        M     U"(       a\  [4        R6                  R9                  S*RU                  U"5      5        [O        U"5      [O        U5      :X  a  [:        R<                  " S5        [O        U 5      [O        U5      :X  aA  U
S:w  a;  U
S:w  a5  [4        R6                  R9                  S+5        [:        R<                  " S5        U (       a:  U
S:w  a4  U
S:w  a.  [4        R6                  R9                  S,RU                  U 5      5        U
S:X  d  U
S:X  a'  U#R                  U5        / nU#R                  U 5        / n O/U
b,  U(       a%  [4        R6                  R9                  S-U S.35        / nU!(       a  U(       d  [        U!S S/S09(       d  g0 n&U!U-   U#-    H  n[        U5      U&U'   M     / n'/ n(0 n)U! H  nU&U   (       d0  [4        R6                  R9                  S1RU                  U5      5        M=  / n*[_        [`        U5      n+U+U)U'   U+ H3  n,U,U&U    V-s/ s H  n-U-S   PM
     sn-;  d  M"  U*R                  U,5        M5     U*(       a  U(R                  U5        M  U'R                  U5        M     U'(       d  U#(       a8  U( H1  n[4        R6                  R9                  S2RU                  U5      5        M3     OmU((       af  [        R                  " 5       n.[d        Rf                  " S3RU                  [O        U(5      S:X  a  S4OS5S69S7U.R                  S8S95      -   S/S!9nU(       d  gU(n'U	(       d  U(       d  U'(       a  U(       d  / n/[4        R6                  R9                  S:5        U' Ha  nU&U    V-s/ s H  n-U-S   PM
     n0n-Sn1U(       a  [        UU15      n1[k        U0US;U1S URl                  S S<9(       d  MP  U/R                  U5        Mc     U/n'U(       Gd  U(       a#  [d        Rf                  " S=U S>U' 3S S!9nU(       d  gS/n/ n2U' H  n [        UU&U   U)U   UUUS?9u  n3n4U3(       a  S nOU(       a  [B        RD                  RG                  [B        RD                  RW                  [H        RJ                  " U5      U5      5      (       d4  [4        R6                  R9                  S@U SD35        U2R                  U5        U4(       a  M    O   U2 H  nU'R                  U5        M     U(       aK  U(       a$  [4        R6                  R9                  S$U S%35        g[4        R6                  R9                  S&5        gU(       a?  U(       d8  [4        R6                  R9                  SEU 35        [:        R<                  " S5        U'R                  U#5        U
b  U'(       a  [4        R6                  R9                  SFU
 SG35        [d        Rf                  " SHRU                  U'5      S S!9n6U6(       d  gU' Hm  n[        UURt                  Rv                  R~                  U
SI9(       d  M3  UR                  U5        [4        R6                  R9                  SJU
 SKU SLU SM35        Mo     gU'(       a^  SNn7U(       a  SOU SP3n7[4        R6                  R9                  SQU7 SR35        [d        Rf                  " SHRU                  U'5      S S!9n6U6(       d  gU' Hz  n[        UURt                  Rv                  Rz                  5      (       d  M4  UR                  U5        SSU ST3n8U#(       d	  U8SUU SJ3-  n8[4        R6                  R9                  U85        M|     U(       d  gU	(       a   [4        R6                  R9                  SV5        O[4        R6                  R9                  SW5        / n9/ n:[        5       n;U	(       a~  [s        U5      Rc                  5        Ha  u  nn%U%URt                  Rv                  R|                  :X  d&  U%URt                  Rv                  R~                  :X  d  MP  U;R                  U5        Mc     U H  nU&U    V-s/ s H  n-U-SX   PM
     n0n-UU;;   n<U<(       a  U&U    V-s/ s H  n-U-S   PM
     n0n-[k        U0UUUU<URl                  SY9(       a  U:R                  U5        Mo  U9R                  U5        M     U	(       a  gU9(       aN  U:(       a   [4        R6                  R9                  SZ5        O'[d        Rf                  " S[S\S/S!9nU(       a  U9n:U(       d  g[4        R6                  R9                  5         U: Hq  n[        UURt                  Rv                  Rx                  5      (       d  M4  [4        R6                  R9                  S]RU                  US^95        U R                  U5        Ms     [4        R6                  R9                  S_RU                  U 5      5        [        [        U5      [        U 5      -
  5      n=U=(       aN  [4        R6                  R9                  S`RU                  U=5      5        [4        R6                  R9                  Sa5        ggs  snnf s  sn-f s  sn-f ! [        R                   af  n5U2R                  U5        [4        R6                  R9                  S@U SA[        R                  " U5R                  5      SB   SC    35         Sn5A5GM  Sn5A5ff = fs  sn-f s  sn-f )bz4Runs the automigrate wizard for the current project.r  z?--pkg-dev-location is only used when migrating to pkg.dev reposrE  N      z4--recent-images must be between 30 and 180 inclusivez@--output-iam-policy-dir is only used when determining iam policyz?--input-iam-policy-dir is only used when determining iam policyz^--input-iam-policy-dir and --output-iam-policy-dir should not be called in the same invocationz*--input-iam-policy-dir must be a directoryr   d   z2--canary-reads must be between 0 and 100 inclusivezLProjects argument may not be used when providing --from-gcr and --to-pkg-devz<--from-gcr and --to-pkg-dev-repo should be provided togetherzDOnly one of --last-uploaded-versions and --recent-images can be usedr   r   z/--from-gcr must be of the form {host}/{project}z1--to-pkg-dev must be of the form {project}/{repo}r'   zW--to-pkg-dev is only used for pkg.dev repos. Use --projects to migrate to a gcr.io repoz8{gcr_host} is not a valid gcr host. Valid hosts: {hosts}z, )r  hostsz{}{}-docker.pkg.devr,   z
Continuing will update z IAM policy based on r   Tr   r-   r,   )	rN  rO  r  r  r,  r  r&  r  r'  za
All policies written. After verifying IAM policies, rerun this tool with --input-iam-policy-dir=z to complete migrationz\No IAM changes are needed. Rerun this tool without --output-iam-policy to complete migration)last_uploaded	copy_frommax_threadszG
Any reference to {gcr} will still need to be updated to reference {ar})gcrarz8Skipping migration for projects in unsupported state: {}zArtifact Registry is already handling all requests for *gcr.io repos for the provided projects. If there are images you still need to copy, use the --copy-only flag.z'Skipping already migrated projects: {}
z$Skipping projects in final copying: zd
Only --canary-reads=100 (safer) or --canary-reads=0 are allowed for projects with migrated writes.
F)automigratedry_runzKSkipping project {} because it has no Artifact Registry repos to migrate toztSkipping project {} because it has a Container Registry bucket without a corresponding Artifact Registry repository.z
{project_str} has Container Registry buckets without corresponding Artifact Registry repositories. Existing Container Registry data will become innacessible.zThis projectzEach project)project_strzDo you wish to continue z(not recommended)r  zD
Copying initial images (additional images will be copied later)...
   )recent_imagesrX  convert_to_pkg_devrZ  pre_copyzf
Continuing will update IAM policies for repositories in the following projects based on the files in r  r%  z	Skipping z due to error setting policy: r|  r  z" because no policy directory foundzNo IAM policies found at z
The next step will redirect z% of *gcr.io read traffic to Artifact Registry. All pushes will still write to Container Registry. While canarying, Artifact Registry will attempt to copy missing images from Container Registry at request time.
zProjects to redirect: {})r  rY  zG% of *gcr.io read traffic is now being served by Artifact Registry for z. Missing images are copied from Container Registry.
To send traffic back to Container Registry, run:
  gcloud artifacts settings disable-upgrade-redirection --project=zT
To send all traffic to Artifact Registry, re-run this script without --canary-readsr]   z- that have been pulled or pushed in the last z dayszj
The next step will redirect all *gcr.io traffic to Artifact Registry. Remaining Container Registry imagesa   will be copied. During migration, Artifact Registry will serve *gcr.io requests for images it doesn't have yet by copying them from Container Registry at request time. Deleting images from *gcr.io repos in the middle of migration might not be effective.

IMPORTANT: Make sure to update any relevant VPC-SC policies before migrating. Once *gcr.io is redirected to Artifact Registry, the artifactregistry.googleapis.com service will be checked for VPC-SC instead of containerregistry.googleapis.com.
z=*gcr.io traffic is now being served by Artifact Registry for z. Missing images are being copied from Container Registry
To send all write traffic back to Container Registry, re-run this command with --canary-reads=100
zTo send all read and write traffic to  Container Registry, instead run:
  gcloud artifacts settings disable-upgrade-redirection --project=z
Copying images...
z
Copying remaining images...
r  )rX  rb  rZ  z2
Only completing migration for successful projectszj
All projects had image copy failures. Continuing will disable further copying and images will be missing.zContinue anyway?z*gcr.io traffic is now being fully served by Artifact Registry for {project}. Images will no longer be copied from Container Registry for this project.)rG   z.
The following projects are fully migrated: {}z>The following projects still need to finish being migrated: {}zI
This script can be re-run to migrate any projects that haven't finished.)Rr  r   r   DisableUserProjectQuotarG   r   rH   rI   rJ   	isnumericr   r   ri  r   ParseProject	projectIdra  last_uploaded_versionsfrom_gcr
to_pkg_dev	copy_onlycanary_readsskip_iam_updatepkg_dev_locationskip_pre_copyuse_analyze_iamr   r   r   sysr  r  r&  r  r  isdirr!   r  boolr   r^   keysrP   r   r   registry_endpoint_prefixCreatePkgDevIfMissingr<  _GCR_BUCKETSr:  r   r   r)  WrappedCopyImagesFromGCRrZ  rX   r  r  ProjectSettings%LegacyRedirectionStateValueValuesEnumREDIRECTION_FROM_GCR_IO_ENABLED+REDIRECTION_FROM_GCR_IO_ENABLED_AND_COPYING REDIRECTION_FROM_GCR_IO_DISABLED+REDIRECTION_FROM_GCR_IO_PARTIAL_AND_COPYINGrj  MaybeCreateMissingReposr  r   r  r  minr/  r   rJ  r   r   r   remover  r`  addr8  )>r  rL   r  project_idsrG   ra  rh  ri  rj  rk  rl  skip_iamar_locationro  r'  r  r&  sr  rN  rO  r  r-   r  kvr,  contr+  ru  r   copying_projectsenabled_projectsdisabled_projectsinvalid_projectspartial_projectsredirection_statestateexisting_reposprojects_to_redirectdangerous_projectsrepo_bucket_mapmissing_bucket_reposrepos_with_gcr_bucketsgrr  pre_copied_projects	gcr_hostslast_uploaded_for_precopyneeds_removalproject_diffsrP  rM  updatecaveatrollback_commandfailed_copies	to_enableunredirected_copying_projectsrb  remaining_projectss>                                                                 r6   MigrateToArtifactRegistryr    sL   	]]}}""3'H  "J
 1 1 6 6 > > H H JKH+g


<44W=
>
H
H !  ($$-66]](*nn)"",!!(%%+$$-$$+JJI HHQKMB$6-#:MJJKLHHQK4422IJJJ HHQKx9JJI HHQK3JJ	) HHQK77==,,-ABCC	jjCD	hhqk<!#3|c7IJJIJHHQK
mmt||(jJJ	 HHQK	(^tJ''JJF HHQKJJN HHQKsAA
1v{	jjHI	hhqkHka A
1v{	jjJK	hhqkJ7	jj& 
hhqk16688	jj
D
K
KII8==?@ L  
hhqk)(3Hh ''##<<@@BHD D(J@ )..00&1a<H, ad0
 j **)*Qwi @/03$
 /#!&g>!!5"7#

Q !JJ++@*A B 	 JJ= #	,$$ 	jj77=vtczJ6 8> 8 $$&(,X6+113
%%KKkkl 	(
%%KKwwx 	(
%%KKllm 	  )
%%KKwwx 	((- 40 JJBII	

 H-	hhqk 

s8},
#

!
JJ	+
 HHQK,#-,!2CJJ299:JK SLA-,-,-$4JJ
./?.@ A8 	8
  3"tU  ."%558HHg.w7N7 I /"g'"	jjw (w?5OG#	
N7,CD,Cq1\?,CD	D##A& $ (!!'*% #( -%	jj & ##%A$$	3396%&!+ ' 4: 4

 	#QZZ0CU%KK
D - #
JJP (,:7,CD,Cq1\?,CiD"%	$'(>(A%C!	!

 1!&&
 
 	""7+) (* /	&&"#3';&<> 	d KM'0C7#G$"7!5#1
-- 
ww}}GGLL,,-ABGL
 
 **

'"DE 

w
'##9 (: !!!'* !	

11F0G H""	
 	 	

9	
 K	jj23G2HIJ	hhqk./"6JJ
( 7M 	M &&"))*>?F '	


"
"
H
H
t
t#
 

 	(

 &&-Y / " #C	C	
 ( F9-
N  JJ	BBH J:	: &&"))*>?F %g  FFrr  g&Y ;;   ""&	
 
jj'(- &0 
JJ,-JJ67
 -)"%%.x8>>@
%%KKllm%%KKwwx 	&))'2 A "g$27$;<$;q6$;I< !$AA -;7,CD,Cq1\?,CiD,-$$ w7#' "* 	jjLM&&9
	d 
!	**g  FFff  
jj%vgv6
 g&  **7>>?OP CMC0@,AABJJHOO	

 JJ	 iZ Ed EX !** W%

y !

199%g.y9:<	
 	f = EsL   AL
*AL
<AL#
AL(,AL-DAN*D1AN/L-AN'MAAN"N"AN'c                 $   UnUR                  SS5      n [        R                  " [        5      n	US:X  a#  [	        U 5      S:X  a  SU S    SU S3n
O)SU S3n
O"[	        U 5      S:X  a  SU S    SU S3n
OSU S3n
[
        R                  " U
S	S
S9   [        R                  " US9 n/ n[        U 5       H  nU(       aH  [        R                  R                  R                  R                  5       n[        U   nU U SU SU 3nOU SU 3nUUS:  a  UOSUUUUU	/nUS:  a(  UR!                  UR"                  " [$        /UQ76 5        M  [%        U6   M     U(       a)  UR'                  5       nUR)                  5         U(       a  M)  SSS5        SSS5        [*        R,                  R/                  SR1                  UU	S   U	S   U	S   U	S   -   S95        U	S   U	S   -   (       a  [*        R,                  R/                  S5        U	S    H"  n[*        R,                  R/                  U5        M$     U	S   S:  ay  [*        R,                  R/                  SR1                  U	S   S95        [*        R,                  R/                  S5        U	S    H"  n[*        R,                  R/                  U5        M$     U$ g
! , (       d  f       GN4= f! , (       d  f       GN>= f! [2        R4                   a  n[6        R8                  " S[;        U5      5      nU(       d  e [<        R>                  " 5       nUnUS:w  a  URA                  S5      S   n[*        R,                  R/                  URC                  SS5      S U S!U S"US    S#3-   5         SnAg$SnAff = f)%z<Copies images from GCR for all hosts and handles auth error.r>  r   samerE  zCopying images for r   z... zCopying images to r   T)
tick_delay
no_spacing)max_workersz-docker.pkg.dev/Nz|
{project}: Successfully copied {tags} additional tags and {manifests} additional manifests. There were {failures} failures.
tagsCopiedmanifestsCopied
tagsFailedmanifestsFailed)rG   tags	manifestsr  z$
Example images that failed to copy:example_failuresmanifestsFailedWithNotFounda  
Among those failures, there are {not_found} image copy failures due to parts of the image missing from GCR. You may try pulling the images directly from GCR to confirm. Because the images are already currupted in GCR, there's no action required for these images.)	not_foundz?
Example images that failed to copy due to missing data in GCR:not_found_failuresr  r  r  z> The Artifact Registry service account doesn't have access to z for copying images
The following command will grant the necessary access (may take a few minutes):
  gcloud projects add-iam-policy-binding z --member='serviceAccount:zW' --role='roles/storage.objectViewer'
You can re-run this script after granting access.F)"r   r7  r8  intr   r   ProgressTrackerr   ThreadPoolExecutorsortedr   rH   r   ru  ri  r^   r   submitCopyImagesFromGCRpopry  r   r   r   rP   r
   V2DiagnosticExceptionr=   r  r  r   r  r   r  )rU  project_repora  rX  rY  rb  rZ  rc  original_project_reporc  r  executorthread_futuresr  endpoint_prefixr-   r_  	copy_argsfutureexample_failureexample_not_foundrM  r>   r  rG   s                            r6   rx  rx  \  s    '%%c3/,o%%c*GF	Uq'az<.E'~T:	Uq&uQxj,tD&|nD9 
	)	)

 %%+>(5MD!!++DDHHJ  2$7H$%hZ/?~QtfUCF!L>*C%/ht) 1_!! 1>I> y)/ "0 !%%'&
--/ n5 ?
F JJ	M	 &/0\*W5F-GG	 
 

	 |w'899	jj>?$%78/

) 9 
.	/!	3

1 28!"?@ 28 2	
 	

N	
 "))=!>
**

,
- "?o} ?>
 
H 
	*	* II>AGE

%
%
'C#GF$R(gJJZ'9  9.uQxj 9"	"	"	 %sK   A;K K&C J5KD#K 5
K	?K
KK N-BN

Nc                    [         R                  " SS9n[        R                  " U5      nSn	Sn
  [        R
                  " [         R                  " 5       UUS9 nSU 3nU(       a  USU 3-  nU(       a  USU 3-  nU	(       a  US	U	 3-  n[        R                  " UR                  S
U 35      R                  S5      5      nUR                  S5      (       a  US   n	O
 SSS5        O SSS5        M  US==   UR                  SS5      -  ss'   US==   UR                  SS5      -  ss'   US==   UR                  SS5      -  ss'   US==   UR                  SS5      -  ss'   US==   UR                  SS5      -  ss'   UR                  S/ 5      nU(       a  US   (       d  / US'   US   U-   SS US'   UR                  S/ 5      nU(       a  US   (       d  / US'   US   U-   SS US'   US    HI  nU UUS-   U-   UUUU/nU(       a(  U R-                  UR.                  " [0        /UQ76 5        MA  [1        U6   MK     U$ ! , (       d  f       GNb= f! [        R                  R                   a     GMK  [        R                    aj  nUR"                  S:X  a   SnAGMu  UR"                  S:X  a=  U
S:  a  U
[$        R&                  " SS5      -  n
[(        R*                  " U
5         SnAGM  e SnAff = f) z#Recursively copies images from GCR.iX  )timeoutr]      )basic_credsr{   	transportz?CopyFromGCR=z
&PullDays=z&MaxVersions=z
&NextPage=z	tags/listutf8nextPageNi  i  rT  rE     r  r   r  r  r  r  exampleFailuresr  
   exampleFailuresWithNotFoundr  childr   )r   Httpr	   rk   r   FromRegistryCredentialProviderr   r   _contentdecoder_   r   r   ReadTimeoutr
   r  r   random	randrangetimesleepr   r  r  )r  r  	repo_pathra  rX  rY  rc  http_objr,   	next_pagebackoffimagequerytags_payloadrM  r  r  r  r  s                      r6   r  r    s%    YYw'(%%i0*)'#$$--/ 	{+
Z/
/%
]=/2
2%
Z	{+
+%zzNNYug./66v>
 J''":.)
' " # 	J 

 0 01BA FF	,<++L!<<	
 0 01BA FF	
'(L,<,<#Q- ( 
,<++L!<</4(%&$&g !#*+=#>#I1R"PG#''(ErJ'(&(g"#$%(::%G ! G$eC%I HOO,=J	JK# % 
.I ( ** ,, 	
S	
S S=
V%%a,
,'

7sO   )I BI!I +I 
II I K7:K7K2$AK21K22K7c                    [        U 5      S:X  a  U S   [        U S   5      0nO[        U 5      nU(       a   [        R                  R                  S5        g[        S UR                  5        5       5      nU(       a|  [        R                  " 5       nUS:  a  SOSn[        R                  " SU S	U S
3SUR                  SS5      -   US9nU(       d  gUR                  5        H  u  p[        X5        M     g[        R                  " 5       n[        R                  R                  UR                  SS5      S-   5        g)z:Creates missing repos if needed and requested by the user.rE  r   z!Dry run enabled, no changes made.Fc              3   8   #    U  H  n[        U5      v   M     g 7fr0   )r   )r   r  s     r6   r   *MaybeCreateMissingRepos.<locals>.<genexpr>>	  s     A*@Q#a&&*@rX  r  r]   z%
gcloud can automatically create the z missing repozr in Artifact Registry.
If you would like to setup CMEK for these repos, exit now and create them manually instead.zCreate missing repos z(recommended)r  rV  Tr(  zSAll Container Registry repositories have equivalent Artifact Registry repostories.
)r   r  r  r   r   r   sumr?  r   r  r   r   r  r:  CreateRepositories)
r  r]  r^  r  num_missing_reposr  r  create_reposrG   rv  s
             r6   r  r  3	  s3   ]aa["@!"MNM>xHMJJ89A-*>*>*@AA

%
%
'C!A%2A,,
01B0C Ds C	C 	 #,,"HHL '--/( 0 
 
%
%
'CJJVW%	 
r8   c                      [         R                  " SU SU SU 35        g! [        R                   aW    [        R
                  " 5       n[        R                  " UR                  SU  SU SU 3S5      SSSS	9  [        X!US
./5         gf = f)zCreate a pkg.dev repository if it doesn't exist.

Args:
  host: AR hostname (string)
  location: repo location (string)
  project: project id of the repo (string)
  repo: repo_id to be created (string)
z	projects/rO   z/repositories/z
No repository found at r   r  zCreate missing repository?T)r   r1  rW  N)
rX   r  r   rA  r   r  r   r   r  r  )r  r-   rG   r  r  s        r6   rv  rv  Y	  s    N
G9KzvF 
	.	. 
N

%
%
'C'vQwiq?	
 	% wd!K LM
Ns   " A(BBc           
         [         R                  " 5       n/ nU H  nUR                  SR                  XS   US   5      SUR                  R                  R
                  S9n [         R                  " XS   U5      nUR                  [        R                  R                  UR                  SS95        M     [         R,                  " 5       nU H7  n	[.        R0                  " [.        R2                  " UR4                  5      U	SS9  M9     g! [        R                   ad  n[        R                  R!                  SUS    S	["        R$                  " UR&                  5      S
   S    S35        [)        U 5         SnAGMd  SnAf[        R*                   aY  n[        R                  R!                  SUS    S	["        R$                  " UR&                  5      S
   S    S35         SnAGM  SnAff = f)z*Creates repositories in Artifact Registry.r  r-   r,   zCreated by gcloud)r{   descriptionrP   z.artifactregistry.projects.locations.operationsr  zFailed to create repository z: r|  r  rY  Nz(Waiting for repo creation to complete...)r  )rX   r  rk   rP   rl   rm   CreateRepositoryr   r   r   r  r{   r   r   r   r   r   r   r   r   r  rJ  	GetClientr   WaitForCloudOperationPollerNoResourcesprojects_locations_operations)
rG   rv  r   op_resourcesr  repository_messageoprM  r   resources
             r6   r  r  s	  s   $$&(,d!,,7>>*%tL'9
 (""88?? - ''

#%7b 



.
.ggI /  <   "&h
NN..00	
 	:  11 ,	jj(j)9(: ;jj#G,Y78< #7++(( 	jj(j)9(: ;jj#G,Y78< s'   #ADG.AE>>G.AG))G.c                 d   [        U5      nUR                  n[        R                  R	                  S5        [
        R                  " 5       n[
        R                  " U5      nUR                  nUUR                  R                  R                  :X  d  XdR                  :X  a$  [        R                  R	                  SU S35        OHUUR                  R                  R                  :X  a$  [        R                  R	                  SU S35        g[        U/SU5      (       d  g[        R                  " 5       n[         R"                  " SS	U S3-   UR%                  S
S5      -   SU S3-   SS9nU(       d   [        R                  R	                  S5        g[
        R&                  " [        U5      5      $ )z3Enables upgrade redirection for the active project.z,Performing redirection enablement checks...
zProject z< is already using Artifact Registry for all *gcr.io traffic.z;Redirection is already enabled (and finalized) for project r   NFzF
This action will redirect all Container Registry traffic to Artifact zRegistry for project z; Your existing images and IAM policies will NOT be copied.
r  zgTo preserve existing GCR behavior, consider running `gcloud artifacts docker upgrade migrate --project=z
` instead.TrV  No changes made.)rM   r^  r   r   r   rX   r  r  r  ry  rz  r{  !REDIRECTION_FROM_GCR_IO_FINALIZEDr  r   r  r   r   r  EnableUpgradeRedirection)	r  rL   rG   r^  r   settingscurrent_statusr  r  s	            r6   r  r  	  s   t'LL'**BC$$&(++G4(22.		!	!	G	G	g	gh	33	3JJ
7)  	
 		!	!	G	G	i	ij JJ
EgYaP 	 'E7	;	;##%#$$O
y*+
H%	
	++2):	?? 	& 
JJ'(		-	-j.>	??r8   c                    [        U5      n[        R                  " 5       n[        R                  " 5       n[
        R                  R                  S5        [
        R                  R                  S5        [        R                  " [        U5      5      nUR                  nXcR                  R                  R                  :X  aB  [
        R                  R                  UR                  SS5      SR                  U5      -   5        g[        R                   " SU S3UR                  S	S5      -   S
U SU S3-   SS9nU(       d   [
        R                  R                  S5        g[        R"                  " U5      $ )z4Disables upgrade redirection for the active project.z!Disabling upgrade redirection...
z'Checking current redirection status...
zFAIL:r  zy Redirection has already been finalized for project {}. Disabling redirection is not possible once it has been finalized.NzhThis action will disable the redirection of Container Registry traffic to Artifact Registry for project r  zWARNING:z` This will disable redirection for both read and write traffic to Artifact Registry for project z and you may lose access to images pushed to Artifact Registry. To disable redirection for write traffic only, run:
  gcloud artifacts docker upgrade migrate --project=z --canary-reads=100TrV  r  )rM   rX   r  r   r  r   r   r   r  r  ry  rz  r  r  rP   r   r   DisableUpgradeRedirection)r  rL   rG   r   r  r  r  r  s           r6   r  r  	  sK   t'$$&(##%#**78 **=>++Jt,<=(22.00,,-N-NOJJWe$ (&&,fWo	67 $$**1$8Z'(	((/y 1 9/		11 
& 
JJ'(		.	.w	77r8   c                 :   UR                   (       a  SUR                  R                  l        SUR                  R                  l        SUR                  R                  l        SUR                  R                  l        SUR                  R                  l        U$ UR                  (       a  SUR                  R                  l	        SUR                  R                  l        SUR                  R                  l        SUR                  R                  l        SUR                  R                  l        U$ UR                  (       a  SUR                  R                  l        SUR                  R                  l	        SUR                  R                  l        SUR                  R                  l        SUR                  R                  l        U$ UR                  (       a  SUR                  R                  l        SUR                  R                  l        SUR                  R                  l	        SUR                  R                  l        SUR                  R                  l        U$ UR                  (       a  SUR                  R                  l        SUR                  R                  l	        SUR                  R                  l        SUR                  R                  l        SUR                  R                  l        U$ UR                  (       a  SUR                  R                  l        SUR                  R                  l	        SUR                  R                  l        SUR                  R                  l        SUR                  R                  l        U$ )z>Make sure that only one remote source is set at the same time.N)remote_mvn_repor,   remoteRepositoryConfigdockerRepositorynpmRepositorypythonRepositoryaptRepositoryyumRepositoryremote_docker_repomavenRepositoryremote_npm_reporemote_python_reporemote_apt_reporemote_yum_repo)r  rL   r   s      r6   SanitizeRemoteRepositoryConfigr  	  s   	AEG-->>BG--;AEG-->>BG--;>BG--;@ 
.? @DG--=>BG--;AEG-->>BG--;>BG--;4 
.3 AEG-->@DG--=AEG-->>BG--;>BG--;( 
.' AEG-->>BG--;@DG--=>BG--;>BG--; 
. AEG-->@DG--=>BG--;AEG-->>BG--; 
. AEG-->@DG--=>BG--;AEG-->>BG--;	.r8   c                 H    [         R                  " U 5      u  pU=(       d    S$ )Nzapplication/octet-stream)	mimetypes
guess_type)r  	mime_typeru  s      r6   GetMimetyper  !
  s     %%d+,)		000r8   r0   )FN)NNT)F)FNNT)r  F   F)__doc__
__future__r   r   r   r7  
concurrentr   rI  encodings.idna	encodingsr   r  rn  r  r  r=   rq  r  apitools.base.pyr   r   r   containerregistry.clientr	   containerregistry.client.v2_2r
   r   googlecloudsdk.api_libr    googlecloudsdk.api_lib.artifactsr`   r   +googlecloudsdk.api_lib.cloudresourcemanagerr   'googlecloudsdk.api_lib.container.imagesr   googlecloudsdk.api_lib.utilr   r   googlecloudsdk.callioper   $googlecloudsdk.command_lib.artifactsr   r   r   rX   r   #googlecloudsdk.command_lib.projectsr   googlecloudsdk.corer   r   r   r   googlecloudsdk.core.consoler   r   r   googlecloudsdk.core.resourcer   'googlecloudsdk.core.universe_descriptorr   googlecloudsdk.core.utilr    r!   r"   r#   rp   r%  rb   rc   r^   r?   rC   r   rw  r   r   r   r   r7   r;   rA   rE   rM   rR   rT   rV   r[   rg   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r  r"  r(  r,  r.  r0  r2  r<  r7  rI  rr  r  r  r  r  r  r  r  rH   ri  r  host_seperatorr  r  r  r  r  r  r  r  r  r  r  r#  r/  r2  rB  r)  r  rx  r  r  rv  r  r  r  r  r  r   r8   r6   <module>r*     s   6 &  '        	  	 
  % > 0 5 6 , H < D 8 3 . ( < A H = D # * ) $ 4 2 8 9 G ) * - . ; 
N !3  "O  	  -5 m  0! 0! 2# -!. (! () %", JH6=D
O
K
E:DBF

	.(
7t.
I# I
(.${|(1V$$ :$$..
;??AxS (E!^$XJ/ $~&xj1 "^$XJ/	(1h8v(
7986#L"X o=l !HF FRN	l |~Tp#LN4*Z.@b#8L'T1r8   