
    =                        d Z ddlmZ ddlmZ ddlmZ ddlZddlZddlmZ	 ddl
Z
ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddl m!Z" ddl#m$Z$ ddl%m&Z&  e
j                  ddddd      Z'dZ(dZ)dZ*e(e)e*fZ+dZ,dZ- e
j                  e*e*e)e(d      Z.de*fde)fde(fgZ/d Z0d! Z1d" Z2d# Z3d$ Z4d1d%Z5d& Z6d' Z7 ejp                  d(      	 	 d2d)       Z9d* Z:d+ Z;	 d3d,Z<d4d-Z=d1d.Z>d/ Z?d0 Z@y)5zFUtility for interacting with `artifacts docker upgrade` command group.    )absolute_import)division)unicode_literalsN)
exceptions)ResourceExhausted)client_util)organizations)projects_api)folders)storage_api)storage_util)apis)requests)util)log)console_attr zus.zasia.zeu.)zgcr.ioz	us.gcr.iozasia.gcr.ioz	eu.gcr.ioz roles/artifactregistry.repoAdminzroles/artifactregistry.writerzroles/artifactregistry.reader)zstorage.objects.getzstorage.objects.listzstorage.objects.createzstorage.objects.delete)/artifactregistry.repositories.downloadArtifacts-artifactregistry.repositories.uploadArtifacts-artifactregistry.repositories.deleteArtifactsr   r   r   z:Too many IAM policies. Analysis cannot be fully completed.c                 |    | j                  dd      }t        |      dk(  rdj                  |d   |d         S | dz   S )N:      z{0}.{1}.a.appspot.comr   z.appspot.com)splitlenformat)projectchunkss     8lib/googlecloudsdk/command_lib/artifacts/upgrade_util.pybucket_suffixr!   X   sD    ==a &[A"))&)VAY??	>	!!    c                 N    t         |    }t        |      }dj                  ||      S )Nz)//storage.googleapis.com/{0}artifacts.{1})_DOMAIN_TO_BUCKET_PREFIXr!   r   domainr   prefixsuffixs       r    bucket_resource_namer)   `   s)    #F+&!&	4	;	;FF	KKr"   c                 :    t         |    }t        |      }d| d| S )Nzgs://z
artifacts.)r$   r!   r%   s       r    
bucket_urlr+   g   s)    #F+&!&
6(	++r"   c                 $    dj                  |       S )Nz2//cloudresourcemanager.googleapis.com/projects/{0})r   )r   s    r    project_resource_namer-   m   s    	=	D	DW	MMr"   c                 >    t        | |dd|      \  }}t        |      S )aU  Generates an AR-equivalent IAM policy for a GCR registry.

  Args:
    domain: The domain of the GCR registry.
    project: The project of the GCR registry.
    use_analyze: If true, use AnalyzeIamPolicy to generate the policy

  Returns:
    An iam.Policy.

  Raises:
    Exception: A problem was encountered while generating the policy.
  F)skip_bucketfrom_ar_permissionsuse_analyze)iam_mappolicy_from_map)r&   r   r1   m_s        r    
iam_policyr6   r   s.      

$!Q 
	r"   c                     t        j                  t              }| j                  D ]*  }||j                     j                  |j                         , |S )zConverts an iam.Policy object to a map of roles to sets of users.

  Args:
    policy: An iam.Policy object

  Returns:
    A map of roles to sets of users
  )collectionsdefaultdictsetbindingsroleupdatemembers)policyrole_to_membersbindings      r    map_from_policyrB      sC      ++C0/gGLL!((9 !	r"   c                    t        j                         }t               }| j                         D ]9  \  }}|j	                  |j                  |t        t        |                         ; t        |d       }|j                  |      S )zConverts a map of roles to sets of users to an iam.Policy object.

  Args:
    role_to_members: A map of roles to sets of users

  Returns:
    An iam.Policy.
  )r<   r>   c                     | j                   S N)r<   )bs    r    <lambda>z!policy_from_map.<locals>.<lambda>   s    AFFr"   )key)r;   )		artifactsGetMessageslistitemsappendBindingtuplesortedPolicy)r@   messagesr;   r<   r>   s        r    r3   r3      s~     ""$(V(&,,.mdGOO&/* 	 	
 / H"23(	(	++r"   )maxsizec                    d}g }|r,|rt        |      }nt        | |      }t        ||||      \  }}nR|rt        |t        |      \  }}n:|rt        |t
        |      \  }}n"t        | |      }	t        |t
        |	|      \  }}|d|fS t        j                  t              }
|rP|t        d   d      }t        D ]4  \  }}|j                  ||         }|D ]  }|
|   j                  |        6 |
|fS |j                         D ]"  \  }}t        |   }|
|   j                  |       $ t               }t        j                  t              }t         D ]a  }|
|   }|D ch c]  }|j#                  d      r| }}|j%                  |       |s=|j                  |       ||   j                  |       c ||fS c c}w )a3  Generates an AR-equivalent IAM mapping for a GCR registry.

  Args:
    domain: The domain of the GCR registry.
    project: The project of the GCR registry.
    skip_bucket: If true, get iam policy for project instead of bucket. This can
      be useful when the bucket doesn't exist.
    from_ar_permissions: If true, use AR permissions to generate roles that
      would not need to be added to AR since user already has equivalent access
      for docker commands
    best_effort: If true, lower the scope when encountering auth errors
    use_analyze: If true, use AnalyzeIamPolicy to generate the policy

  Returns:
    (map, failures) where map is a map of roles to sets of users and
    failures is a list of scopes that failed

  Raises:
    Exception: A problem was encountered while generating the policy.
  N)best_effortr   zdeleted:)r-   r)   get_permissions_using_analyzeget_permissions_with_ancestors_AR_PERMISSIONS_PERMISSIONSr+   r8   r9   r:   _AR_PERMISSIONS_TO_ROLESintersectionaddrL   _PERMISSION_TO_ROLEr=   	_AR_ROLES
startswithdifference_update)r&   r   r/   r0   rU   r1   perm_to_membersfailuresresource
gcs_bucketr@   r>   needed_permr<   memberpermupgraded_members	final_mapr4   s                      r    r2   r2      s   : /(&w/h%fg6h =.!OX "@
?#ox 
$B\{%
!  0
$B\:;%
! >++C0/ 6q9!<=G5T$$_[%ABg&!!&)  6 H$$ ',,.mdGt$DD  ) /
 U%%c*)dd#G "B'Qj)Aq'GB./G$dO7#  
H	 Cs    F<7F<c                    t        j                  |       }g }d}t        t        |j                              D ]7  \  }}t        |      }		 |rt        t        ||	      }nt        t        ||	      } n |j                  r|j                  j                  st        d |j                  j                   D              }
dj#                  |
      }|st%        j&                  |      d| }t)        j*                         }t,        j.                  j1                  |j3                  dd       d	|        t5        j6                  t8              }|j                  j:                  D ]  }|j                  st%        j&                  t<              |j>                  j@                  |st%        j&                  d
      t9               }|j>                  jB                  D ]  }tE        |      r|jG                  |       ! |jH                  D ]3  }|jJ                  D ]"  }|jL                  }||   jO                  |       $ 5  ||fS # t        j                  $ r; |j                  |	       |s |t        |j                        dz
  k(  rd|fcY c S Y Rw xY w)z?Returns a map of permissions to members using AnalyzeIamPolicy.
project_idNr   c              3   4   K   | ]  }|j                     y wrE   )cause).0errs     r    	<genexpr>z0get_permissions_using_analyze.<locals>.<genexpr>*  s     O'N#))'Ns   
zVEncountered errors when analyzing IAM policy. This may result in incomplete bindings: zWarning:red z)Conditional IAM binding is not supported.)(crmGetAncestry	enumeratereversedancestorresource_from_ancestoranalyze_iam_policyrX   rY   apitools_exceptionsHttpForbiddenErrorrM   r   fullyExploredmainAnalysisrK   nonCriticalErrorsjoinar_exceptionsArtifactRegistryErrorr   GetConsoleAttrr   statusPrintColorizer8   r9   r:   analysisResults_ANALYSIS_NOT_FULLY_EXPLORED
iamBinding	conditionr>   is_conveniencer\   accessControlListsaccesses
permissionr=   )r   rc   r0   rU   ancestryrb   analysisnumry   scopeerrors	error_msgwarning_msgconra   resultr>   rf   aclaccessrg   s                        r    rV   rV     sL    __0((( (*;*;!<=mc8"8,E	%oxG%lHeD >$ 
		x'<'<'J'JOx'<'<'N'NOOF		&!I//	::	!!*	-  
%
%
'CJJZ67qFG++C0/%%55f//0LMM"".{//
5  eG##++		kk&	 , ((LL&  $$W- ! )# 6, 
(	""[ 11 ooe	H%%&*	*X~ 
+	s   %H>>AJJc                 p    | j                  d      xs$ | j                  d      xs | j                  d      S )NzprojectOwner:zprojectEditor:zprojectViewer:)r_   )ss    r    r   r   O  s7    ll?# (	
&	'(	
&	'r"   c                 P    t        | ||      \  }}t        |||      \  }}|||z   fS rE   )recursive_get_rolesget_permissions)rl   permissionsrd   rU   rolesrb   permsperm_failuress           r    rW   rW   W  s9     (
KL/%(e[I%	=(	((r"   c                    t        j                  |       }t        j                  t              }|rwt        j                         j                  t        j                  j                  |            j                  D ]*  }||j                     j                  |j                         , g }t        |j                         D ](  }g }	 |j"                  j$                  dk(  r3t        j                  t'        j(                  |             j                  }n|j"                  j$                  dk(  r4t+        j                  |j"                  j,                        j                  }nZ|j"                  j$                  dk(  rAt/        j0                         j                  |j"                  j,                        j                  }|D ]*  }||j                     j                  |j                         , + ||fS # t2        j4                  $ rg |j7                  |j"                  j$                  dz   |j"                  j,                  z          |s |j"                  j$                  dk(  rd|fcY c S Y w xY w)z]Returns a map of roles to members for the given project + ancestors (and bucket if provided).rk   r   folderorganizationzs/N)ru   rv   r8   r9   r:   r   StorageClientGetIamPolicyr   BucketReferenceFromUrlr;   r<   r=   r>   rx   ry   
resourceIdtypeprojects_utilParseProjectr   idr	   Clientr|   r}   rM   )	rl   rU   rd   r   r@   rA   rb   rc   r;   s	            r    r   r   _  s   __
3(++C0/!!#	l22:::F	G		 	
 gll#**7??;		 (8,,-hH				!	!Y	.##&&z2

( 	 ##x/''(;(;(>(>?HH##~5  "//0C0C0F0FGPP 	 '%,,W__=  .* 
(	"" 11 ooh))..58K8K8N8NNO				!	!Y	.X~ 
/	s   D"G00A2I*)I*c                 0   g }t        j                  t              }t        j                  dd      }|j                         D ]  \  }}|D cg c]  }t        |      r| }}|j                  |      }		 t        t        j                  dd      j                  j                  |	      j                        }
| D ]  }||
v s||   j                  |         ||fS c c}w # t        j                  $ r}|j                  |       |s|Y d}~d}~ww xY w)a  Returns a map of permissions to members for the given roles.

  Args:
    permissions: The permissions to look for. All other permissions are ignored.
    role_map: A map of roles to members.
    best_effort: If true, warn instead of failing on auth errors.

  Returns:
    (map, failures) where map is a map of permissions to members and failures
    is a list of roles that failed
  iamv1)nameN)r8   r9   r:   r   GetMessagesModulerL   r   IamRolesGetRequestGetClientInstancer   GetincludedPermissionsr|   r}   rM   r=   )r   role_maprU   rb   permission_mapiam_messagesr<   r>   r4   requestrole_permissionseps                r    r   r     s    (**3/.''t4,~~'mdG!;'Q):q'G; --4-8G


 
 
-5W 	
	q  ) ! (& 
	!!% < 11 ood	s%   CC6AC##D6DDc                 l   t        j                         }|j                  }t        j                         }	 |j	                  |j                  | ||            S # t        j                  $ r*}|j                  dk(  rt        j                  d       d}~wt        $ r t        j                  d      w xY w)a0  Calls AnalyzeIamPolicy for the given resource.

  Args:
    permissions: for the access selector
    resource: for the resource selector
    scope: for the scope

  Returns:
    An CloudassetAnalyzeIamPolicyResponse.
  Raises:
    ResourceExhausted: If the request fails due to analyzeIamPolicy quota.
  )(analysisQuery_accessSelector_permissions/analysisQuery_resourceSelector_fullResourceNamer   i  zzInsufficient quota for AnalyzeIamPolicy. Use --no-use-analyze-iam to generate IAM policies without using AnalyzeIamPolicy.N)asset	GetClientr   rJ   AnalyzeIamPolicy!CloudassetAnalyzeIamPolicyRequestr|   	HttpErrorstatus_coder   r   r   )r   rc   r   clientservicerR   r   s          r    r{   r{     s     ??&II' (##225@<D 	3 	
  
	&	& 
}}//C  
	 

-
-	A s   "A B3,%B"B3c                 x   | j                   j                  dk(  r%dj                  | j                   j                        S | j                   j                  dk(  r%dj                  | j                   j                        S | j                   j                  dk(  r%dj                  | j                   j                        S y)zConverts an ancestor to a resource name.

  Args:
    ancestor: an ancestor proto return from GetAncestry

  Returns:
    The resource name of the ancestor
  r   zorganizations/{0}r   zfolders/{0}r   zprojects/{0}N)r   r   r   r   )ry   s    r    rz   rz     s     /%%h&9&9&<&<==) 3 3 6 677*  !4!4!7!788 +r"   )T)FT)NTrE   )A__doc__
__future__r   r   r   r8   	functoolsapitools.base.pyr   r|   
frozendictgoogle.api_core.exceptionsr    googlecloudsdk.api_lib.artifactsr   googlecloudsdk.api_lib.assetr   r   +googlecloudsdk.api_lib.cloudresourcemanagerr	   r
   ru   'googlecloudsdk.api_lib.resource_managerr   googlecloudsdk.api_lib.storager   r   googlecloudsdk.api_lib.utilr   $googlecloudsdk.command_lib.artifactsr   rI   #googlecloudsdk.command_lib.projectsr   r   googlecloudsdk.corer   googlecloudsdk.core.consoler   r$   _REPO_ADMIN_WRITER_READERr^   rY   rX   r]   rZ   r   r!   r)   r+   r-   r6   rB   r3   	lru_cacher2   rV   r   rW   r   r   r{   rz    r"   r    <module>r      sh   M &  '   >  8 H = E K ; 6 7 , F E # 40:00	2   1
)
) '7+	 ,j++"#%)	-   7@4g>4kB  A 
"L,N
4 ,0 T" W #Wt=#@ ;?)"#J""J$N9r"   