
                            S r SSKJr  SSKJr  SSKJr  SSKrSSKrSSKrSSKrSSK	J
r
  SSK	Jr  SSKJr  SS	KJr  SS
KJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJ r   SSKJ!r"  SSK#J$r$  SSK#J%r%  SSK&J'r'  SSK&J!r(  SSK&Jr  SSK)Jr*  SSK+J,r,  SSK+J-r-  SSK+J.r.  SSK/J0r0  SSK!r!SSK1r1SSK2J3r3  Sr4Sr5Sr6Sr7Sr8Sr9Sr:S r;S!r<S"r=S#r>S$r?S%r@S&rAS'rBS(rCS)rDS*rES+rFS,rGS-rHS.rIS/ rJS0 rKS1 rLS2 rMS3 rNS4 rOS5 rPS6 rQS7 rRS8 rSS9 rTS: rUS; rVS< rWS= rXS> rYSNS? jrZS@ r[SA r\SB r]SC r^SD r_SE r`SF raSG rb " SH SI\c5      rd " SJ SK\c5      re " SL SM\c5      rfg)Oz Utility for handling SBOM files.    )absolute_import)division)unicode_literalsN)encoding)
exceptions)docker_creds)docker_name)docker_http)docker_image)docker_image_list)base)util)filter_util)requests)storage_api)storage_util)docker_util)log)	resources)
transports)files)urllibspdx	cyclonedxzRThe file is not in a supported SBOM format. Only spdx and cyclonedx are supported.zapplication/vnd.in-toto+jsonz!https://in-toto.io/Statement/v0.1z+https://bcid.corp.google.com/reference/v0.1zapplication/spdx+jsonzapplication/jsonzapplication/vnd.cyclonedx+jsonz>https://containeranalysis.googleapis.com/ArtifactAnalysis@v0.1z	spdx.jsonjsonzbom.json$abcdefghijklmnopqrstuvwxyz0123456789   zregistry.hub.docker.comlibraryhttphttpsartifactregistrygcrotherc                    U S   nSn[        U[        R                  5      (       a+  [        R                  " SU5      nUb  UR                  S5      nU(       d%  [        R                  " SR                  U5      5      e[        [        US9$ )Retrieves version from the given SBOM dict.

Args:
  data: Parsed json content of an SBOM file.

Raises:
  ar_exceptions.InvalidInputValueError: If the sbom format is not supported.

Returns:
  A SbomFile object with metadata of the given sbom.
spdxVersionNz^SPDX-([0-9]+[.][0-9]+)$   zUnable to read spdxVersion {0}.sbom_formatversion)
isinstancesixstring_typesrematchgroupar_exceptionsInvalidInputValueErrorformatSbomFile_SBOM_FORMAT_SPDX)dataspdx_versionr*   rs       5lib/googlecloudsdk/command_lib/artifacts/sbom_util.py
_ParseSpdxr:   Y   s}     m$,'c..//
,l;A}
g	

.
.)00>  
/	AA    c                 r   SU ;  a  [         R                  " S5      eSn[        U S   [        R                  5      (       a-  [
        R                  " SU S   5      nUb  UR                  5       nU(       d6  [         R                  " SR                  U S   R                  5       5      5      e[        [        US9$ )r%   specVersionz1Unable to find specVersion in the CycloneDX file.Nz^[0-9]+[.][0-9]+$zUnable to read specVersion {0}.r(   )r1   r2   r+   r,   r-   r.   r/   r0   r3   __str__r4   _SBOM_FORMAT_CYCLONEDX)r6   r*   r8   s      r9   _ParseCycloneDxr@   s   s     $

.
.;  ']#S%5%566
%tM':;A}	g	

.
.)00m1D1L1L1NO  
4g	FFr;   c                 4    [         R                  " U 5      n[        R                  " U5      nSU;   a  [        U5      nO;UR                  S5      S:X  a  [        U5      nO[
        R                  " [        5      e[        R                  " [        R                  " U5      5      R!                  5       nXTR"                  S'   U$ ! [         a  n[
        R                  " SU5      eSnAf[         R                   a  n[
        R                  " SU5      eSnAff = f)a  Retrieves information about a docker image based on the fully-qualified name.

Args:
  file_path: str, The sbom file location.

Raises:
  ar_exceptions.InvalidInputValueError: If the sbom format is not supported.

Returns:
  An SbomFile object with metadata of the given sbom.
z!The file is not a valid JSON fileNzFailed to read the sbom filer&   	bomFormat	CycloneDXsha256)r   ReadFileContentsr   loads
ValueErrorr1   r2   Errorr:   getr@   _UNSUPPORTED_SBOM_FORMAT_ERRORhashlibrD   r,   ensure_binary	hexdigestdigests)	file_pathcontentr6   eressha256_digests         r9   ParseJsonSbomrT      s    
$$Y/G::gD d
T
Cxx+
$
C

.
./M
NN..!2!27!;<FFH-'++h	*# 
 

.
.+Q  
 

.
.& s#   ,C 
DC$$D;DDc           	          [         R                  " U 5      u  pUR                  nSUR                  R	                  SS5      0n[        UR                  5       UR                  UR                  U[        [        S9$ )zRetrieves metadata from the given AR docker image.

Args:
  uri: Uri of the AR docker image.

Raises:
  ar_exceptions.InvalidInputValueError: If the uri is invalid.

Returns:
  An Artifact object with metadata of the given artifact.
rD   sha256: resource_uriprojectlocationrN   artifact_typescheme)r   DockerUrlToVersiondocker_repodigestreplaceArtifactGetDockerStringrZ   r[   ARTIFACT_TYPE_AR_IMAGE_REGISTRY_SCHEME_HTTPS)uriimagedocker_versionreporN   s        r9   _GetARDockerImagerj      so     &88=%			$~,,44YCD'	!113ll}}*#
 r;   c           
         SSSSS.n [         R                  " U 5      nSnSn[        R                  " [        R                  U 5      nU(       a$  XR                  S5         nUR                  S5      n[        R                  " [        R                  U 5      nU(       a5  XR                  S5         nUR                  S5      R                  S	S
S5      nU(       a  U(       d  [        R                  " S5      e[        UR                  5       UUSUR                  R                  SS5      0[         ["        S9$ ! [         R                   a*  n[        R                  " SR                  U5      5      eSnAff = f)zRetrieves information about the given GCR image.

Args:
  uri: str, The artifact uri.

Raises:
  ar_exceptions.InvalidInputValueError: If the uri is invalid.

Returns:
  An Artifact object with metadata of the given artifact.
useuropeasia)z	us.gcr.iozgcr.ioz	eu.gcr.iozasia.gcr.ioz-Failed to resolve digest of the GCR image: {}Nri   rZ   /:r'   z8Failed to parse project and location from the GCR image.rD   rV   rW   rX   )gcr_utilGetDigestFromNameInvalidImageNameErrorr1   r2   r3   r.   r/   r   GCR_DOCKER_REPO_REGEXr0   #GCR_DOCKER_DOMAIN_SCOPED_REPO_REGEXra   rb   r>   r`   ARTIFACT_TYPE_GCR_IMAGEre   )rf   location_mapdocker_digestrQ   rZ   r[   matchess          r9   _GetGCRImagerz      sM    	,..s3M
 '(HH[66<'MM&12HmmI&GHH[DDcJ'MM&12HmmI&..sC;G	

.
.B  
 ((*--55iDE+#
 % 
	'	' 

.
.7>>qA s   D8 8E6%E11E6c                 6   [         R                  " [        R                  " 5       U [        R
                  " 5       S9 nUR                  5       (       a  UR                  5       sSSS5        $  SSS5        [        R                  " [        R                  " 5       U [        R
                  " 5       [        R                  S9 nUR                  5       (       a  UR                  5       sSSS5        $  SSS5        g! , (       d  f       N= f! , (       d  f       g= f)zReturns Digest of the given Docker image.

Lookup registry to get the manifest's digest. If it returns a list of
manifests, will return the first one.

Args:
  image: docker_name.Tag or docker_name.Digest, Docker image.

Returns:
  An str for the digest.
)basic_credsname	transportN)r|   r}   r~   accepted_mimes)v2_2_image_listFromRegistryr   	Anonymousr   GetApitoolsTransportexistsr`   
v2_2_imagev2_2_docker_httpSUPPORTED_MANIFEST_MIMES)rg   manifest_listv2_2_imgs      r9   _ResolveDockerImageDigestr      s     ##((*//1 !!# 
  ((*//1%>>	
 __     s   %C9 %D
/D
9
D

Dc           	          [         R                  " U 5      n[        U[         R                  5      (       a.  [	        U SUR
                  R                  SS5      0[        SSSS9$  U nSU ;  a  U S-   n[         R                  " US	9n[        R                  " UR                   5      n [#        U5      nU(       d%  [        R                  " S
R                  U 5      5      eSR                  UR                   UR.                  US9n[	        USUR                  SS5      0[        SSUS9$ ! [         R                  4 a4  n[        R                  " SR                  U [        U5      5      5      eSnAff = f! [        R$                  [&        R(                  R*                  [        R,                  4 a4  n[        R                  " SR                  U [        U5      5      5      eSnAff = f)a*  Retrieves information about the given docker image.

Args:
  uri: str, The artifact uri.

Raises:
  ar_exceptions.InvalidInputValueError: If the artifact is with tag, and it
  can not be resolved by querying the docker http APIs.

Returns:
  An Artifact object with metadata of the given artifact.
rD   rV   rW   NrY   rN   r\   rZ   r[   r]   zFailed to resolve {0}: {1}rp   z:latestr}   zFailed to resolve {0}.z{registry}/{repo}@{digest})registryri   r`   )r	   from_stringr+   Digestrb   r`   ra   ARTIFACT_TYPE_OTHERBadNameExceptionr1   r2   r3   strTagr   Schemer   r   V2DiagnosticExceptionr   r   
InvalidURLBadStateException
repository)rf   image_digestrQ   	image_uri	image_tagr]   r`   rY   s           r9   _GetDockerImager     s   **3/L, 2 233\0088BGH+  4 )^iIoo9-)""9#5#56&	&y1F 


.
. '',  .44!!	(<(<V 5 , 
	267'
 7 
&
&	( 

.
.$++CQ8  ,,$$((
 
 
.
.$++CQ8 s0   A"D( (E4 (E1=/E,,E14=G%1/G  G%c           
      b   [         R                  " U 5      (       a  [        U 5      $ [         R                  " U 5      (       a  [	        U 5      $  [        U 5      $ ! [        R                   aA  n[        R                  " SR                  U5      5        [        U 0 [        SSSS9s SnA$ SnAff = f)zRetrieves information about the given artifact.

Args:
  uri: str, The artifact uri.

Raises:
  ar_exceptions.InvalidInputValueError: If the artifact type is unsupported.

Returns:
  An Artifact object with metadata of the given artifact.
z"Failed to resolve the artifact: {}Nr   )r   IsARDockerImagerj   
IsGCRImagerz   r   r1   r2   r   debugr3   rb   r   )rf   rQ   s     r9   ProcessArtifactr   \  s       %%S!!c""S!!// 		ii4;;A>?+ 	s   
A B.-6B)#B.)B.c                 N    U R                  U5      (       a  U [        U5      S  $ U $ N)
startswithlenvalueprefixs     r9   _RemovePrefixr   }  s)    
fV	,r;   c                 :    U R                  U5      (       d  X-   n U $ r   )r   r   s     r9   _EnsurePrefixr     s    			&	!	!NE	,r;   c                    U R                   nU R                  nU R                  nU(       a  U(       d  U(       d  U(       a  U(       a  [        R                  " S5      e[
        R                  " 5       R                  S/5      n[        R                  " U 5      nU(       a  [
        R                  " 5       R                  S/5      R                  SR                  U5      5      n[        [        R                  " XVR                  5       S5      5      nU(       d  / $ [!        S U 5       5      nUR#                  U5        U(       a  [%        US5      n	SR                  U	5      U	/n
 ['        U	5      nXR(                  :w  a*  U
SR                  UR(                  5      UR(                  /-   n
UR*                  (       a+  [        R,                  " UR*                  U R.                  5      nUR#                  U
5        U(       a.  [%        US5      nUR;                  SR                  U5      U/5        U(       a%  [        R<                  " XTR?                  5       5      nO/[        R                  " XTR                  5       U R@                  5      nU(       a  [C        U5      $ U Vs/ s H  n[E        U0 5      PM     sn$ ! [        R                  [0        R2                  4 a#    [4        R6                  R9                  S	5         GNf = fs  snf )
ztLists SBOM references in a given project.

Args:
  args: User input arguments.

Returns:
  List of SBOM references.
zYCannot specify more than one of the flags --dependency, --resource and --resource-prefix.SBOM_REFERENCEPACKAGEz<noteProjectId="goog-analysis" AND dependencyPackageName="{}"Nc              3   N   #    U  H  n[        UR                  S 5      v   M     g7f)https://N)r   resourceUri).0os     r9   	<genexpr>%ListSbomReferences.<locals>.<genexpr>  s     P<aq}}j99<s   #%r   
https://{}z;Failed to resolve the artifact. Filter on the URI directly.)#resourceresource_prefix
dependencyr1   r2   r   ContainerAnalysisFilter	WithKindsr   
GetProjectWithCustomFilterr3   listca_requestsListOccurrences	GetFiltersetWithResourcesr   r   rY   rZ   	GetParentr[   r	   r   r   statusPrintWithResourcePrefixesListOccurrencesWithFiltersGetChunkifiedFilters	page_size_VerifyGCSObjectsSbomReference)argsr   r   r   filtersrZ   dependency_filterspackage_occsimagesrY   resource_urisartifactpath_prefixoccsoccs                  r9   ListSbomReferencesr     s    ]](&*Fjv*

.
.	- 
 //1;;=M<NO'OOD!'++-	I;			JVJ

  ##113T	
L
 i
 P<PPF&! :6L 	L)M .h	..	.% 5 56!!)
 

 
		..!1!14==A -(
3K  K(" 
 11--/D &&""$dnnD T"",0	1DS-R
 D	11= 00+2N2NO 	jj
G < 
2s   $B J4 K>4AK;:K;c                 D    U  Vs/ s H  n[        U5      PM     sn$ s  snf r   )_VerifyGCSObject)r   r   s     r9   r   r     s     +/	04C
3
4	00	0s   c                    [         R                  " 5       n[        R                  R	                  U R
                  R                  R                  R                  5      n0 n UR                  U5        SUS'   [%        X5      $ ! [        R                   a    SUS'    N&[        R                   a5  n[        R                  " UR                  5      nUS   S   US'    SnANiSnAf[          a  n[#        U5      US'    SnANSnAff = f)zVerify the existence and the content of a GCS SBOM file object.

Args:
  occ: SBOM reference occurrence.

Returns:
  An SbomReference object with the input occurrence and SBOM file information.
Tr   Ferrormessageerr_msgN)r   StorageClientr   ObjectReferenceFromUrlsbomReferencepayload	predicater[   	GetObjectapitools_exceptionsHttpNotFoundError	HttpErrorr   rF   rP   	Exceptionr   r   )r   
gcs_clientobj_ref	file_inforQ   msgs         r9   r   r     s     ((**((00	))22' )! Ih 
s	&& 
	.	.  Ih		&	& 3
**QYY
Cw<	2Ii	 " q6Ii"s*    B DD/+CD,C??Dc                 $    SR                  X5      $ )Nzartifactanalysis-{0}-{1})r3   )project_numr[   s     r9   _DefaultGCSBucketNamer     s    	#	*	*8	AAr;   c           	      
   [         R                  R                  SU05      SS  nUR                  R	                  SS5      nSR
                  " S
0 U R	                  SS5      R                  S5      UUUR                  5       S	.D6$ )Nrf      .-z;gs://{storage_path}/{uri_encoded}/sbom/user-{version}.{ext}zgs://rW   ro   )storage_pathuri_encodedr*   ext )r   parse	urlencoder*   ra   r3   rstripGetExtension)r   rY   sbomr   r*   s        r9   _GetSbomGCSPathr     s    &&|'<=abA+LL  c*'
G	O	O 
&..w;BB3G$""$		
 r;   c           	      V   [         R                  " 5       nUR                  US9nU GH5  n[        R                  " SR                  UR                  5      5        UR                  R                  U 5      (       d  MU  UR                  R                  5       S:X  a1  [        R                  " SR                  UR                  5      5        M  UR                  R                  5       UR                  5       :w  aZ  [        R                  " SR                  UR                  UR                  R                  5       UR                  5       5      5        GM*  UR                  s  $    U S-   n[        [        5       H   nU[        R                  " [        5      -   nM"     UR!                  UUUSSS9   UR#                  US	9nUR$                  (       a   [&        R(                  " UR$                  5      O0 nS
US'   [&        R*                  " XR,                  R.                  R0                  5      Ul        UR,                  R3                  UUS9n	UR4                  R6                  R9                  U	5        U$ ! [:         a0  n
[        R<                  " SR                  Xj5      5         Sn
A
U$ Sn
A
ff = f)a  Find an appropriate default bucket to store the SBOM file.

Find a bucket with the same prefix same as the default bucket in the project.
If no bucket could be found, will start to create a new bucket by
concatenating the default bucket name and a random suffix.

Args:
  default_bucket: str, targeting default bucket name for the resource.
  project_id: str, project we will use to store the SBOM.
  location: str, location we will use to store the SBOM.

Returns:
  bucket_name: str, name of the prepared bucket.
rZ   zVerifying bucket {}zdual-regionzSkipping dual region bucket {}z4The bucket {0} has location {1} is not matching {2}.r   T)bucketrZ   r[   check_ownershipenable_uniform_level_accessr  artifact-analysisgoog-managed-byr  bucketResource%Failed to add labels to bucket {}: {}N)r   r   ListBucketsr   r   r3   r}   r   locationTypelowerr[   range_BUCKET_SUFFIX_LENGTHrandomchoice_BUCKET_NAME_CHARSCreateBucketIfNotExists	GetBucketlabelsr   MessageToDictDictToMessagemessagesBucketLabelsValueStorageBucketsPatchRequestclientbucketsPatchr   warning)default_bucket
project_idr[   r   r  r  bucket_name_labels_dictrequestrQ   s              r9   _FindAvailableGCSBucketr%  #  s2    ((**"":"6'fII#**6;;78;;!!.11  "m3	ii077DE(.."22	ii
@
G
Gkk6??002HNN4D
 ;; " $+&'a.@ AAK ($$"& % P!!!5F;A==(((7bK%8K!"**((//;;FM !!<< = G ##G, 
 
 PKK7>>{NOO	Ps   -B?I. .
J(8%J##J(c                    [         R                  " 5       nU(       a  [        X1R                  U5      nGOp[        R
                  " UR                  5      nUR                  nUR                  nUS:X  a  Sn[        Xh5      n	U	n
Sn UR                  U
UUSS9   UR                  U
S9nUR                  (       a   [        R                  " UR                  5      O0 nSUS'   [        R                  " XR                  R                   R"                  5      Ul        UR                  R%                  U
US	9nUR&                  R(                  R+                  U5        U(       a  [=        XU5      n
[.        R6                  " SR3                  U
5      5        [        XR                  U5      n[>        R@                  RC                  U5      nURE                  U U5        U$ ! [,         a/  n[.        R0                  " S
R3                  X5      5         SnANSnAff = f! [         R4                   a    [.        R6                  " S5        Sn N[8        R:                   a    [.        R6                  " S5        Sn GNf = f)a  Upload an SBOM file onto the GCS bucket in the given project and location.

Args:
  source: str, the SBOM file location.
  artifact: Artifact, the artifact metadata SBOM file generated from.
  sbom: SbomFile, metadata of the SBOM file.
  gcs_path: str, the GCS location for the SBOm file. If not provided, will use
    the default bucket path of the artifact.

Returns:
  dest: str, the GCS storage path the file is copied to.
rm   euFT)r  rZ   r[   r  r  r  r  r  r	  Nz)The default bucket is in a wrong project.z&The default bucket cannot be accessed.zUsing bucket: {})#r   r   r   rY   project_utilGetProjectNumberrZ   r[   r   r  r  r  r   r  r  r  r  r  r  r  r  r  r   r   r  r3   BucketInWrongProjectErrorr   r   HttpForbiddenErrorr%  r   r   r   CopyFileToGCS)sourcer   r   gcs_pathr   destr   bucket_projectbucket_locationr  r!  use_backup_bucketr  r#  r$  rQ   
target_refs                    r9   UploadSbomToGCSr4  a  s.    ((**8%:%:DAD//0@0@AK%%N''O("o*;HN K%(( "	 ) 
%%[%95;]]H""6==1 	 *=%& ..,,33??
 %%@@! A 
 	!!''0" +
/k II ''45;(=(=tDD++33D9*6:.	+5  
3::;J	
 	

 00  
ii;<11  
ii89s=   H B?G 
H"%HH HH ,I1+I10I1c                 (   [         R                  " 5       n[         R                  " 5       n[        UR                  UR
                  5      n[        R                  R                  SU US9R                  5       n UR                  US9nUR                  R                  U5      n[        R                   " S
R#                  U5      5        U$ ! [        R                   a    [        R                   " SR#                  U5      5        UR%                  UR                  UR
                  S9nUR'                  UR&                  R(                  R*                  US9n	UR-                  SR#                  U S9UU	S	9n
UR                  R                  U
5      n Nf = f)zCreate the SBOM reference note if not exists.

Args:
  project_id: str, the project we will use to create the note.
  sbom: SbomFile, metadata of the SBOM file.

Returns:
  A Note object for the targeting SBOM reference note.
z containeranalysis.projects.notes)
collection
projectsIdnotesIdr   z"Note not found. Creating note {0}.)r3   r*   )kindr   projects/{project}r   )parentnoteIdnotezget note results: {0})r   	GetClientGetMessages_GetReferenceNoteIDr)   r*   r   REGISTRYCreateRelativeName(ContaineranalysisProjectsNotesGetRequestprojects_notesGetr   r   r   r   r3   SBOMReferenceNoteNoteKindValueValuesEnumr   +ContaineranalysisProjectsNotesCreateRequest)r   r   r  r  note_idr}   get_requestr=  sbom_referencenew_notecreate_requests              r9   _CreateSbomRefNoteIfNotExistsrP    sx      "&$$&( 0 0$,,?'				"	"3 
# 
 LN	 8CCCNK  $$[1D" ))#**401	+# 
	.	. 8II299$?@// 0 N }}]]..==$  H II#**:*> J N
   ''7D8s   9*C
 
CFFc                 t   [         R                  " 5       nUR                  R                  5       nUR                  R                  5        HB  u  pgUR                  R                  UR                  R                  R                  UUS95        MD     UR                  UUUR                  5       [        S9nUR                  [        [        US9n	UR                  R                  5       n
U R                  R                  5        HB  u  pgU
R                  R                  UR                  R                  R                  UUS95        MD     UR                  XR                  S9nU	R                   R                  U5        UR#                  U	[$        S9nUR'                  UUR(                  U R+                  5       S9nU$ )aX  Create the SBOM reference note if not exists.

Args:
  artifact: Artifact, the artifact metadata SBOM file generated from.
  sbom: SbomFile, metadata of the SBOM file.
  note: Note, the Note object we will use to attach occurrence.
  storage: str, the path that SBOM is stored remotely.

Returns:
  An Occurrence object for the SBOM reference.
)keyr   )r`   r[   mimeType
referrerId)predicateType_typer   )r`   r}   )r   payloadType)r   noteNamer   )r   r?  SbomReferenceIntotoPredicateDigestValuerN   itemsadditionalPropertiesappendAdditionalPropertyGetMimeType_SBOM_REFERENCE_REFERRERIDSbomReferenceIntotoPayload_SBOM_REFERENCE_PREDICATE_TYPE_SBOM_REFERENCE_TARGET_TYPESubjectrY   subjectSBOMReferenceOccurrence_SBOM_REFERENCE_PAYLOAD_TYPE
Occurrencer}   GetOccurrenceResourceUri)r   r   r=  storager  sbom_digsetskvr   r   artifact_digestssbom_subjectref_occr   s                 r9   _GenerateSbomRefOccurrencerq    s    $$&(66BBD,ll  "da%%,,--99LL 	M 	
 # 33!+	 4 ) //2' 0 '
 %%113$$&da))00$$77 	8 	
 ' !!$9$9 " , 
//&,,. - '
 	yy335 	 	# 
*r;   c                 H    UR                  SS5      nSR                  X5      $ )Nr   r   zsbom-{0}-{1})ra   r3   )r)   sbom_versionsbom_version_encodeds      r9   r@  r@    s&    %--c37			{	AAr;   c                    [         R                  " 5       nUR                  U R                  5       /5        UR	                  S/5        [        UR                  UR                  5      n[        UR                  S5      5      S:  a  UR                  S5      S   nUR                  SR                  XB5      5        UR                  5       $ )Nr   ro   r'   r   z$noteId="{0}" AND noteProjectId="{1}")r   r   r   ri  r   r@  r)   r*   r   splitr   r3   r   )r   r   r   frK  s        r9   $_GenerateSbomRefOccurrenceListFilterrx    s    ))+!//844678++ ! 0 0$,,?'		#	!#!!#&q)J,33GH 
r;   c                 V    S[        U 5      U R                  S5      [        U5      U4-  $ )zCreates DSSEv1 Pre-Authentication encoding for given type and payload.

Args:
  payload_type: str, the SBOM reference payload type.
  payload: bytes, the serialized SBOM reference payload.

Returns:
  A bytes of DSSEv1 Pre-Authentication encoding.
s   DSSEv1 %d %b %d %bzutf-8)r   encode)payload_typer   s     r9   _PAEr|  ,  s6     
	,'"	'l	" 
 r;   c                    [         R                  " [        R                  " U R                  R
                  5      5      n[        U R                  R                  U5      n[        R                  " 5       n[        R                  " 5       nUR                  UUR                  US9S9nUR                  R                  U5      n[        R                   " 5       nUR#                  XR$                  S9n	UR'                  UU R                  R                  U	/S9U l        U R                  R*                  R-                  U	5        U $ )a  Add signatures in reference occurrence by using the given kms key.

Args:
  occ: Occurrence, the SBOM reference occurrence object we want to sign.
  kms_key_version: str, a kms key used to sign the reference occurrence.

Returns:
  An Occurrence object with signatures added.
)r6   )r}   asymmetricSignRequest)keyidsig)r   rW  
signatures)r,   rL   r   MessageToJsonr   r   r|  rW  cloudkms_baseGetClientInstanceGetMessagesModuleQCloudkmsProjectsLocationsKeyRingsCryptoKeysCryptoKeyVersionsAsymmetricSignRequestAsymmetricSignRequest8projects_locations_keyRings_cryptoKeys_cryptoKeyVersionsAsymmetricSignr   r?  EnvelopeSignature	signatureEnvelopeenveloper  r]  )
r   kms_key_versionpayload_bytesr6   
kms_clientkms_messagesreqrespr  evelope_signatures
             r9   _SignSbomRefOccurrencePayloadr  ?  s)    ##S..667- 
c++]	;$..0*002,ff(>>D>I 	g 	# 
	L	L	[	[	
$ $$&(00 1  ""##//#$ # #,
 %%&78	*r;   c                 H   [        X5      n[        XXR5      nU(       a  [        Xd5      n[        XU5      n[        R
                  " SR                  U5      5        [        R                  " 5       n[        R                  " 5       n	[        R                  " XS5      n
[        R
                  " SR                  U
5      5        SnU
 H  nUn  O   U(       af  [        R
                  " SR                  UR                  5      5        U	R                  UR                  USS9nUR                  R                  U5      nO8U	R                  USR                  US9S	9nUR                  R!                  U5      n[        R
                  " S
R                  U5      5        UR                  $ )a  Write the reference occurrence to link the artifact and the SBOM.

Args:
  artifact: Artifact, the artifact metadata SBOM file generated from.
  project_id: str, the project_id where we will use to store the Occurrence.
  storage: str, the path that SBOM is stored remotely.
  sbom: SbomFile, metadata of the SBOM file.
  kms_key_version: str, the kms key to sign the reference occurrence payload.

Returns:
  A str for occurrence ID.
z#listing occurrence with filter {0}.Nzlist successfully: {}zupdating occurrence {0}.zsbom_reference,envelope)r}   
occurrence
updateMaskr:  r   )r  r;  zUsed occurrence: {0}.)rP  rq  r  rx  r   r   r3   r   r>  r?  r   r}   0ContaineranalysisProjectsOccurrencesPatchRequestprojects_occurrencesr  1ContaineranalysisProjectsOccurrencesCreateRequestrB  )r   r   rj  r   r  r=  r   rw  r  r  r   old_occr   r$  s                 r9   WriteReferenceOccurrencer  g  sk     
'z	8$ 	#84A#
'
=C +8:F!))188;<  "&$$&(		$	$ZD	9$))#**401'aG	 
 II(//=>GG\\, H G
 
%
%
+
+G
4CHH#**:*> I G 
%
%
,
,W
5C))#**3/0	/r;   c                    U R                   (       d  [        R                  " S5      e[        U R                   S5      n[        R
                  " U5      (       a  [        U5      nO[        R                  " U5      (       a  [        U5      n[        R                  " 5       n[        R                  " UR                  5      nUR                  UR                  R                  R                   :w  a  [        R                  " S5      eO%[        R                  " SR#                  U5      5      e[$        R&                  " U 5      nUR                  (       a  UR                  n[$        R(                  " XPR*                  5      n[,        R.                  " USR#                  UR0                  5      5      n[2        R4                  R7                  SR#                  UR0                  UR8                  5      5        g)zMExport SBOM files for a given AR image.

Args:
  args: User input arguments.
z--uri is required.r   zyThis command only supports Artifact Registry. You can enable redirection to use gcr.io repositories in Artifact Registry.z%{} is not an Artifact Registry image.r   zDExporting the SBOM file for resource {}. Discovery occurrence ID: {}N)rf   r1   r2   r   r   r   rj   r   rz   ar_requestsr?  GetProjectSettingsrZ   legacyRedirectionStateProjectSettings%LegacyRedirectionStateValueValuesEnumREDIRECTION_FROM_GCR_IO_ENABLEDr3   r   r   r   r[   r   ExportSbomV1beta1rY   r   r   r   discoveryOccurrenceId)r   rf   r   r  settingsrZ   r;  r  s           r9   
ExportSbomr    s    


.
.  	dhh
+#  %% %Hc""C H&&(H--h.>.>?H''##IIii	j 00J 	j 
.
./66s;  OOD!'G>>'==1&		&	&l!!("7"78
$ **Lv




$
$r;   c                   >    \ rS rSrSrS r\S 5       r\S 5       rSr	g)r   i  z|Holder for SBOM reference.

Properties:
  occ: SBOM reference occurrence.
  file_info: Information of GCS object SBOM file.
c                     Xl         X l        g r   )_occ
_file_info)selfr   r   s      r9   __init__SbomReference.__init__  s    IOr;   c                     U R                   $ r   )r  r  s    r9   r   SbomReference.occ  s    99r;   c                     U R                   $ r   )r  r  s    r9   r   SbomReference.file_info  s    ??r;   )r  r  N)
__name__
__module____qualname____firstlineno____doc__r  propertyr   r   __static_attributes__r   r;   r9   r   r     s4         r;   r   c                   Z    \ rS rSrSrS rS rS r\S 5       r	\S 5       r
\S 5       rS	rg
)r4   i  zHolder for SBOM file's metadata.

Properties:
  sbom_format: Data format of the SBOM file.
  version: Version of the SBOM format.
  digests: A dictionary of digests, where key is the algorithm.
c                 :    Xl         X l        [        5       U l        g r   )_sbom_format_versiondict_digests)r  r)   r*   s      r9   r  SbomFile.__init__  s    #MFDMr;   c                 v    U R                   [        :X  a  [        $ U R                   [        :X  a  [        $ [
        $ r   )r  r5   _SBOM_REFERENCE_SPDX_MIME_TYPEr?   #_SBOM_REFERENCE_CYCLONEDX_MIME_TYPE!_SBOM_REFERENCE_DEFAULT_MIME_TYPEr  s    r9   r_  SbomFile.GetMimeType  2    --++2200,,r;   c                 v    U R                   [        :X  a  [        $ U R                   [        :X  a  [        $ [
        $ r   )r  r5   _SBOM_REFERENCE_SPDX_EXTENSIONr?   #_SBOM_REFERENCE_CYCLONEDX_EXTENSION!_SBOM_REFERENCE_DEFAULT_EXTENSIONr  s    r9   r   SbomFile.GetExtension  r  r;   c                     U R                   $ r   r  r  s    r9   rN   SbomFile.digests      ==r;   c                     U R                   $ r   )r  r  s    r9   r)   SbomFile.sbom_format  s    r;   c                     U R                   $ r   )r  r  s    r9   r*   SbomFile.version  r  r;   )r  r  r  N)r  r  r  r  r  r  r_  r   r  rN   r)   r*   r  r   r;   r9   r4   r4     sR    
--      r;   r4   c                   t    \ rS rSrSrS r\S 5       r\S 5       r\S 5       r	\S 5       r
\S 5       rS	 rS
rg)rb   i
  ak  Holder for Artifact's metadata.

Properties:
  resource_uri: str, Uri will be used when storing as a reference occurrence.
  project: str, Project of the artifact.
  location: str, Location of the artifact.
  digests: A dictionary of digests, where key is the algorithm.
  artifact_type: str, Type of the provided artifact.
  scheme: str, Scheme of the registry.
c                 L    Xl         X l        X0l        X@l        XPl        X`l        g r   )_resource_uri_project	_locationr  _artifact_type_scheme)r  rY   rZ   r[   rN   r\   r]   s          r9   r  Artifact.__init__  s$     &MNM'Lr;   c                     U R                   $ r   )r  r  s    r9   rY   Artifact.resource_uri   s    r;   c                     U R                   $ r   )r  r  s    r9   rZ   Artifact.project$  r  r;   c                     U R                   $ r   )r  r  s    r9   r[   Artifact.location(  s    >>r;   c                     U R                   $ r   r  r  s    r9   rN   Artifact.digests,  r  r;   c                     U R                   $ r   )r  r  s    r9   r\   Artifact.artifact_type0  s    r;   c                 |    U R                   c  U R                  $ SR                  U R                   U R                  S9$ )Nz{scheme}://{uri})r]   rf   )r  rY   r3   r  s    r9   ri  !Artifact.GetOccurrenceResourceUri4  s8    ||$$DLLd>O>O$PPr;   )r  r  r  r  r  r  N)r  r  r  r  r  r  r  rY   rZ   r[   rN   r\   ri  r  r   r;   r9   rb   rb   
  sv    	          Qr;   rb   r   )gr  
__future__r   r   r   rK   r   r  r.   apitools.base.pyr   r   r   containerregistry.clientr   r	   containerregistry.client.v2_2r
   r   r   r   r   r    googlecloudsdk.api_lib.artifactsr1   googlecloudsdk.api_lib.cloudkmsr   r  'googlecloudsdk.api_lib.container.imagesr   rq   (googlecloudsdk.api_lib.containeranalysisr   r   r   googlecloudsdk.api_lib.storager   r   $googlecloudsdk.command_lib.artifactsr   r  #googlecloudsdk.command_lib.projectsr(  googlecloudsdk.corer   r   r   googlecloudsdk.core.utilr   r,   	six.movesr   r5   r?   rJ   rg  rc  rb  r  r  r  r`  r  r  r  r  r  _DEFAULT_DOCKER_REGISTRY_DEFAULT_DOCKER_REPOSITORY_REGISTRY_SCHEME_HTTPre   rd   rv   r   r:   r@   rT   rj   rz   r   r   r   r   r   r   r   r   r   r   r%  r4  rP  rq  r@  rx  r|  r  r  r  objectr   r4   rb   r   r;   r9   <module>r     s   ' &  '    	 % > 1 0 I D N H A D @ L 6 7 < H 5 D # ) * *  
  $ / 
  > A 6  "9 $6 !&F #D  "- $* !&0 #;  4 &    +   B4G<!H4.b>:zB`2F1'DB
;|M`(V:zB

&%P5p*ZF *&v &R-Qv -Qr;   