创建自定义注释和出现次数

您可以选择将自己的元数据提供给 Artifact Analysis,以满足特定的业务需求。例如,为客户的 Docker 容器提供安全管理的组织,可以使用 Artifact Analysis 来存储和检索这些映像的安全相关元数据。

以下步骤展示了如何使用 Artifact Analysis API 为映像提供证明元数据。您可以使用相同的说明来存储和检索 Artifact Analysis 支持的任何种类的元数据

准备工作

  1. 登录您的 Google Cloud 账号。如果您是 Google Cloud新手,请 创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Enable the Container Analysis API.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the API

  4. 安装 Google Cloud CLI。

  5. 如果您使用的是外部身份提供方 (IdP),则必须先使用联合身份登录 gcloud CLI

  6. 如需初始化 gcloud CLI,请运行以下命令:

    gcloud init
  7. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  8. Enable the Container Analysis API.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the API

  9. 安装 Google Cloud CLI。

  10. 如果您使用的是外部身份提供方 (IdP),则必须先使用联合身份登录 gcloud CLI

  11. 如需初始化 gcloud CLI,请运行以下命令:

    gcloud init
  12. 了解如何为项目中的元数据设置访问权限控制。如果您仅使用 Artifact Analysis 容器扫描创建的实例中的元数据,请跳过此步骤。

为项目创建笔记和出现

本部分介绍了如何创建备注和发生实例。在此示例中,您将使用 ATTESTATION 种类。

作为提供方,您需要在自己的项目中为每项证明创建备注,还需要在客户的项目中为该证明的事件创建事件。

创建备注

请按以下步骤创建笔记并为其指定笔记 ID。

API

  1. 创建一个名为 note.json 的文件,其中包含证明说明和详细信息。以下代码显示了一个示例 note.json 文件:

    {
      "shortDescription": "A brief Description of the note",
      "longDescription": "A longer description of the note",
      "kind": "ATTESTATION",
      "attestation": {
        "hint": {
          "humanReadableName": "my-attestation-authority"
        }
      }
    }
    

    如需详细了解笔记 JSON 表示法,请参阅笔记 API 文档

  2. 运行以下 curl 命令以创建备注:

    curl -v -H "Content-Type: application/json" -H \
      "Authorization: Bearer $(gcloud auth print-access-token)" \
      https://containeranalysis.googleapis.com/v1/projects/PROVIDER_PROJECT_ID/notes?note_id=NOTE_ID -d @note.json
    

    其中:

    • PROVIDER_PROJECT_ID 是项目 ID。
    • NOTE_ID 用于指定注释的标识符。使用长度不超过 100 个字符的字符串。

Java

如需了解如何安装和使用 Artifact Analysis 客户端库,请参阅 Artifact Analysis 客户端库。如需了解详情,请参阅 Artifact Analysis Java API 参考文档

如需向 Artifact Analysis 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证

import com.google.cloud.devtools.containeranalysis.v1.ContainerAnalysisClient;
import io.grafeas.v1.GrafeasClient;
import io.grafeas.v1.Note;
import io.grafeas.v1.ProjectName;
import io.grafeas.v1.Version;
import io.grafeas.v1.AttestationNote;
import java.io.IOException;
import java.lang.InterruptedException;

public class CreateNote {

  // Creates and returns a new Note
  public static Note createNote(String noteId, String projectId)
      throws IOException, InterruptedException {
    // String noteId = "my-note";
    // String projectId = "my-project-id";
    final String projectName = ProjectName.format(projectId);

    Note newNote =
        Note.newBuilder()
            // Associate the Note with the metadata type
            // https://docs.cloud.google.com/artifact-registry/docs/analysis
            // Here, we use the type "attestation"
            .setAttestation(
                AttestationNote.newBuilder()
                    .setHint(
                        AttestationNote.Hint.newBuilder()
                            .setHumanReadableName("my-attestation-authority")))
            .build();

    // Initialize client that will be used to send requests. After completing all of your requests,
    // call the "close" method on the client to safely clean up any remaining background resources.
    GrafeasClient client = ContainerAnalysisClient.create().getGrafeasClient();
    Note result = client.createNote(projectName, noteId, newNote);
    return result;
  }
}

Go

如需了解如何安装和使用 Artifact Analysis 客户端库,请参阅 Artifact Analysis 客户端库。如需了解详情,请参阅 Artifact Analysis Go API 参考文档

如需向 Artifact Analysis 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证


import (
  "context"
  "fmt"

  containeranalysis "cloud.google.com/go/containeranalysis/apiv1"
  grafeaspb "google.golang.org/genproto/googleapis/grafeas/v1"
)

// createNote creates and returns a new attestation Note.
func createNote(noteID, projectID string) (*grafeaspb.Note, error) {
  ctx := context.Background()
  client, err := containeranalysis.NewClient(ctx)
  if err != nil {
    return nil, fmt.Errorf("NewClient: %w", err)
  }
  defer client.Close()

  projectName := fmt.Sprintf("projects/%s", projectID)

  req := &grafeaspb.CreateNoteRequest{
    Parent: projectName,
    NoteId: noteID,
    Note: &grafeaspb.Note{
      Type: &grafeaspb.Note_Attestation{
        Attestation: &grafeaspb.AttestationNote{
          Hint: &grafeaspb.AttestationNote_Hint{
            HumanReadableName: "my-attestation-authority",
          },
        },
      },
    },
  }

  return client.GetGrafeasClient().CreateNote(ctx, req)
}

Node.js

如需了解如何安装和使用 Artifact Analysis 客户端库,请参阅 Artifact Analysis 客户端库。如需了解详情,请参阅 Artifact Analysis Node.js API 参考文档

如需向 Artifact Analysis 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证

/**
* TODO(developer): Uncomment these variables before running the sample
*/
// const projectId = 'your-project-id', // Your Google Cloud Project ID
// const noteId = 'my-note-id' // Id of the note

// Import the library and create a client
const {ContainerAnalysisClient} = require('@google-cloud/containeranalysis');
const client = new ContainerAnalysisClient();

// Construct request
// Associate the Note with a metadata type
// https://docs.cloud.google.com/artifact-registry/docs/analysis
// Here, we use the type "attestation"
const formattedParent = client.getGrafeasClient().projectPath(projectId);

// Creates and returns a new Note
const [note] = await client.getGrafeasClient().createNote({
  parent: formattedParent,
  noteId: noteId,
  note: {
    attestation: {
      hint: {
        humanReadableName: 'my-attestation-authority',
      },
    },
  },
});

console.log(`Note ${note.name} created.`);

Ruby

如需了解如何安装和使用 Artifact Analysis 客户端库,请参阅 Artifact Analysis 客户端库。如需了解详情,请参阅 Artifact Analysis Ruby API 参考文档

如需向 Artifact Analysis 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证

# note_id = "A user-specified identifier for the note"
# project_id = "Your Google Cloud project ID"

require "google/cloud/container_analysis"

# Initialize the client
client = Google::Cloud::ContainerAnalysis.container_analysis.grafeas_client

parent = client.project_path project: project_id
note = {
  attestation: {
    hint: {
      human_readable_name: "attestation-authority"
    }
  }
}
response = client.create_note parent: parent, note_id: note_id, note: note
puts response.name

Python

如需了解如何安装和使用 Artifact Analysis 客户端库,请参阅 Artifact Analysis 客户端库。如需了解详情,请参阅 Artifact Analysis Python API 参考文档

如需向 Artifact Analysis 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证

from google.cloud.devtools import containeranalysis_v1
from grafeas.grafeas_v1 import types, Version

def create_note(note_id: str, project_id: str) -> types.grafeas.Note:
    """Creates and returns a new attestation note."""
    # note_id = 'my-note'
    # project_id = 'my-gcp-project'

    client = containeranalysis_v1.ContainerAnalysisClient()
    grafeas_client = client.get_grafeas_client()
    project_name = f"projects/{project_id}"
    note = {
      "attestation": {
        "hint": {
          "human_readable_name": "attestation-authority",
        }
      }
    }
    response = grafeas_client.create_note(
        parent=project_name, note_id=note_id, note=note
    )
    return response

为备注创建事件

要为备注创建事件,请按如下所述操作:

API

  1. 创建一个名为 occurrence.json 的文件,其中包含证明说明和详细信息。以下代码显示了一个示例 occurrence.json 文件:

    {
      "resourceUri": "your-resource-uri-here",
      "noteName": "projects/your-note-project/notes/your-note-id",
      "kind": "ATTESTATION",
      "attestation": {
        "serializedPayload": "eW91ci1wYXlsb2FkLWhlcmU=",
        "signatures": [
          {
            "publicKeyId": "your-key-id-here",
            "signature": "eW91ci1zaWduYXR1cmUtaGVyZQ=="
          }
        ]
      }
    }
    

    如需详细了解笔记 JSON 表示法,请参阅笔记 API 文档

  2. 运行以下 curl 命令以创建一次性活动:

    curl -v -H "Content-Type: application/json" -H \
      "Authorization: Bearer $(gcloud auth print-access-token)" \
      https://containeranalysis.googleapis.com/v1/projects/PROVIDER_PROJECT_ID/occurrences/ -d @occurrence.json
    

    其中:

    • PROVIDER_PROJECT_ID 是项目 ID。
    • NOTE_ID 用于指定注释的标识符。使用长度不超过 100 个字符的字符串。

Java

如需了解如何安装和使用 Artifact Analysis 客户端库,请参阅 Artifact Analysis 客户端库。如需了解详情,请参阅 Artifact Analysis Java API 参考文档

如需向 Artifact Analysis 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证

import com.google.cloud.devtools.containeranalysis.v1.ContainerAnalysisClient;
import com.google.protobuf.ByteString;
import io.grafeas.v1.AttestationOccurrence;
import io.grafeas.v1.GrafeasClient;
import io.grafeas.v1.NoteName;
import io.grafeas.v1.Occurrence;
import io.grafeas.v1.ProjectName;
import io.grafeas.v1.Signature;
import java.io.IOException;

public class CreateOccurrence {
  // Creates and returns a new attestation Occurrence associated with an existing Note
  public static Occurrence createOccurrence(
      String resourceUrl, String noteId, String occProjectId, String noteProjectId)
      throws IOException {
    // String resourceUrl = "https://gcr.io/project/image@sha256:123";
    // String noteId = "my-note";
    // String occProjectId = "my-project-id";
    // String noteProjectId = "my-project-id";
    final NoteName noteName = NoteName.of(noteProjectId, noteId);
    final String occProjectName = ProjectName.format(occProjectId);

    Occurrence newOcc =
        Occurrence.newBuilder()
            .setNoteName(noteName.toString())
            .setResourceUri(resourceUrl)
            .setAttestation(
                AttestationOccurrence.newBuilder()
                    .setSerializedPayload(ByteString.copyFrom("your-payload-here", "UTF-8"))
                    .addSignatures(
                        Signature.newBuilder()
                            .setPublicKeyId("your-key-id-here")
                            .setSignature(ByteString.copyFrom("your-signature-here", "UTF-8"))))
            .build();

    // Initialize client that will be used to send requests. After completing all of your requests,
    // call the "close" method on the client to safely clean up any remaining background
    // resources.
    GrafeasClient client = ContainerAnalysisClient.create().getGrafeasClient();
    Occurrence result = client.createOccurrence(occProjectName, newOcc);
    return result;
  }
}

Go

如需了解如何安装和使用 Artifact Analysis 客户端库,请参阅 Artifact Analysis 客户端库。如需了解详情,请参阅 Artifact Analysis Go API 参考文档

如需向 Artifact Analysis 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证

import (
  "context"
  "fmt"

  containeranalysis "cloud.google.com/go/containeranalysis/apiv1"
  grafeaspb "google.golang.org/genproto/googleapis/grafeas/v1"
)

// createsOccurrence creates and returns a new Occurrence of a previously created attestation note.
  // Use this style of URL when you use Google Artifact Registry.
  // resourceURL := "https://LOCATION-docker.pkg.dev/my-project/my-repo/my-image"
  // noteID := "my-note"
  ctx := context.Background()
  client, err := containeranalysis.NewClient(ctx)
  if err != nil {
    return nil, fmt.Errorf("NewClient: %w", err)
  }
  defer client.Close()

  req := &grafeaspb.CreateOccurrenceRequest{
    Parent: fmt.Sprintf("projects/%s", occProjectID),
    Occurrence: &grafeaspb.Occurrence{
      NoteName: fmt.Sprintf("projects/%s/notes/%s", noteProjectID, noteID),
      // Attach the occurrence to the associated resource uri.
      ResourceUri: resourceURL,
      // Details about the attestation can be added here.
      Details: &grafeaspb.Occurrence_Attestation{
        Attestation: &grafeaspb.AttestationOccurrence{
          SerializedPayload: []byte("..."),
          Signatures: []*grafeaspb.Signature{
            {
              PublicKeyId: "...",
              Signature:   []byte("..."),
            },
          },
        },
      },
    },
  }
  return client.GetGrafeasClient().CreateOccurrence(ctx, req)
}

Node.js

如需了解如何安装和使用 Artifact Analysis 客户端库,请参阅 Artifact Analysis 客户端库。如需了解详情,请参阅 Artifact Analysis Node.js API 参考文档

如需向 Artifact Analysis 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证

/**
 * TODO(developer): Uncomment these variables before running the sample
 */
// const noteProjectId = 'your-project-id', // Your Google Cloud Project ID
// const noteId = 'my-note-id', // Id of the note
// const occurrenceProjectId = 'your-project-id', // The Google Cloud Project ID of the occurrence
// If you are using Google Artifact Registry
// const imageUrl = 'https://LOCATION-docker.pkg.dev/my-project/my-repo/my-image:123' // Image to attach metadata to

// Import the library and create a client
const {ContainerAnalysisClient} = require('@google-cloud/containeranalysis');
const client = new ContainerAnalysisClient();

// Construct request
const formattedParent = client
.getGrafeasClient()
.projectPath(occurrenceProjectId);
const formattedNote = client
.getGrafeasClient()
.notePath(noteProjectId, noteId);

// Creates and returns a new Occurrence associated with an existing Note
const [occurrence] = await client.getGrafeasClient().createOccurrence({
parent: formattedParent,
occurrence: {
  noteName: formattedNote,
  resourceUri: imageUrl,
  attestation: {
    serializedPayload: Buffer.from('your-payload-here').toString('base64'),
    signatures: [
      {
        publicKeyId: 'your-key-id-here',
        signature: Buffer.from('your-signature-here').toString('base64'),
      },
    ],
  },
},
});
console.log(`Occurrence created ${occurrence.name}.`);
return occurrence;

Ruby

如需了解如何安装和使用 Artifact Analysis 客户端库,请参阅 Artifact Analysis 客户端库。如需了解详情,请参阅 Artifact Analysis Ruby API 参考文档

如需向 Artifact Analysis 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证

# note_id    = "A user-specified identifier for the note"
# project_id = "Your Google Cloud project ID"
# note_project = "The project that contains the note"
# occurrence_project = "The project that contains the occurrence"

require "google/cloud/container_analysis"
require "base64"

# Initialize the client
client = Google::Cloud::ContainerAnalysis.container_analysis.grafeas_client
note_path = client.note_path project: note_project, note: note_id
project_path = client.project_path project: occurrence_project

occurrence = {
  note_name:    note_path,
  resource_uri: resource_url,
  attestation:  {
    serialized_payload: Base64.encode64("your-payload-here"),
    signatures:         [
      {
        public_key_id: "your-key-id-here",
        signature:     Base64.encode64("your-signature-here")
      }
    ]
  }
}

response = client.create_occurrence parent: project_path, occurrence: occurrence
puts response.name

Python

如需了解如何安装和使用 Artifact Analysis 客户端库,请参阅 Artifact Analysis 客户端库。如需了解详情,请参阅 Artifact Analysis Python API 参考文档

如需向 Artifact Analysis 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证

import base64
from google.cloud.devtools import containeranalysis_v1
from grafeas.grafeas_v1 import types

def create_occurrence(
    resource_url: str, note_id: str, occurrence_project: str, note_project: str
) -> types.grafeas.Occurrence:
    """Creates and returns a new occurrence of a previously
    created attestation note."""
    # note_id = 'my-note'
    # project_id = 'my-gcp-project'

    client = containeranalysis_v1.ContainerAnalysisClient()
    grafeas_client = client.get_grafeas_client()
    formatted_note = f"projects/{note_project}/notes/{note_id}"
    formatted_project = f"projects/{occurrence_project}"

    occurrence = {
        "note_name": formatted_note,
        "resource_uri": resource_url,
        "attestation": {
            "serialized_payload": base64.b64encode(b"your-payload-here").decode("utf-8"),
            "signatures": [
                {
                    "public_key_id": "your-key-id-here",
                    "signature": base64.b64encode(b"your-signature-here").decode("utf-8"),
                }
            ],
        },
    }

    return grafeas_client.create_occurrence(
        parent=formatted_project, occurrence=occurrence
    )

获取特定备注的所有事件

您可以使用 notes.occurrences.list() 查看客户项目中特定证明的所有发生实例。

API

如需列出某一备注的所有发生实例,请按如下方式发送 GET 请求:

GET https://containeranalysis.googleapis.com/v1/projects/PROJECT_ID/notes/NOTE_ID/occurrences

如需了解完整的详细信息,请参阅 projects.notes.occurrences.list API 端点。

Java

如需了解如何安装和使用 Artifact Analysis 客户端库,请参阅 Artifact Analysis 客户端库。 如需了解详情,请参阅 Artifact Analysis Java API 参考文档

如需向 Artifact Analysis 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证

import static java.lang.Thread.sleep;

import com.google.cloud.devtools.containeranalysis.v1.ContainerAnalysisClient;
import io.grafeas.v1.GrafeasClient;
import io.grafeas.v1.ListNoteOccurrencesRequest;
import io.grafeas.v1.NoteName;
import io.grafeas.v1.Occurrence;
import java.io.IOException;
import java.lang.InterruptedException;

public class OccurrencesForNote {  
  // Retrieves all the Occurrences associated with a specified Note
  // Here, all Occurrences are printed and counted
  public static int getOccurrencesForNote(String noteId, String projectId) 
      throws IOException, InterruptedException {
    // String noteId = "my-note";
    // String projectId = "my-project-id";
    final NoteName noteName = NoteName.of(projectId, noteId);

    ListNoteOccurrencesRequest request = ListNoteOccurrencesRequest.newBuilder()
                                                                   .setName(noteName.toString())
                                                                   .build();

    // Initialize client that will be used to send requests. After completing all of your requests, 
    // call the "close" method on the client to safely clean up any remaining background resources.
    GrafeasClient client = ContainerAnalysisClient.create().getGrafeasClient();
    int i = 0;
    for (Occurrence o : client.listNoteOccurrences(request).iterateAll()) {
      // Write custom code to process each Occurrence here
      System.out.println(o.getName());
      i = i + 1;
    }
    return i;
  }
}

Go

如需了解如何安装和使用 Artifact Analysis 客户端库,请参阅 Artifact Analysis 客户端库。 如需了解详情,请参阅 Artifact Analysis Go API 参考文档

如需向 Artifact Analysis 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证


import (
	"context"
	"fmt"
	"io"

	containeranalysis "cloud.google.com/go/containeranalysis/apiv1"
	"google.golang.org/api/iterator"
	grafeaspb "google.golang.org/genproto/googleapis/grafeas/v1"
)

// getOccurrencesForNote retrieves all the Occurrences associated with a specified Note.
// Here, all Occurrences are printed and counted.
func getOccurrencesForNote(w io.Writer, noteID, projectID string) (int, error) {
	// noteID := fmt.Sprintf("my-note")
	ctx := context.Background()
	client, err := containeranalysis.NewClient(ctx)
	if err != nil {
		return -1, fmt.Errorf("NewClient: %w", err)
	}
	defer client.Close()

	req := &grafeaspb.ListNoteOccurrencesRequest{
		Name: fmt.Sprintf("projects/%s/notes/%s", projectID, noteID),
	}
	it := client.GetGrafeasClient().ListNoteOccurrences(ctx, req)
	count := 0
	for {
		occ, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return -1, fmt.Errorf("occurrence iteration error: %w", err)
		}
		// Write custom code to process each Occurrence here.
		fmt.Fprintln(w, occ)
		count = count + 1
	}
	return count, nil
}

Node.js

如需了解如何安装和使用 Artifact Analysis 客户端库,请参阅 Artifact Analysis 客户端库。 如需了解详情,请参阅 Artifact Analysis Node.js API 参考文档

如需向 Artifact Analysis 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证

/**
 * TODO(developer): Uncomment these variables before running the sample
 */
// const projectId = 'your-project-id', // Your GCP Project ID
// const noteId = 'my-note-id' // Id of the note

// Import the library and create a client
const {ContainerAnalysisClient} = require('@google-cloud/containeranalysis');
const client = new ContainerAnalysisClient();

// Get path to Note
const formattedNote = client.notePath(projectId, noteId);

// Retrieves all the Occurrences associated with a specified Note
const [occurrences] = await client.getGrafeasClient().listNoteOccurrences({
  name: formattedNote,
});

if (occurrences.length) {
  console.log('Occurrences:');
  occurrences.forEach(occurrence => {
    console.log(`${occurrence.name}:`);
  });
} else {
  console.log('No occurrences found.');
}

Ruby

如需了解如何安装和使用 Artifact Analysis 客户端库,请参阅 Artifact Analysis 客户端库。 如需了解详情,请参阅 Artifact Analysis Ruby API 参考文档

如需向 Artifact Analysis 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证

  # note_id    = "The identifier for the note to query"
  # project_id = "The Google Cloud project ID of the occurrences to retrieve"

  require "google/cloud/container_analysis"

  # Initialize the client
  client = Google::Cloud::ContainerAnalysis.container_analysis.grafeas_client

  name = client.note_path project: project_id, note: note_id
  count = 0
  client.list_note_occurrences(name: name).each do |occurrence|
    # Process occurrence here
    puts occurrence
    count += 1
  end
  puts "Found #{count} occurrences"
  count
end

def get_discovery_info resource_url:, project_id:
  # resource_url = "The URL of the resource associated with the occurrence."
  #                # e.g. https://gcr.io/project/image@sha256:123
  # project_id   = "The Google Cloud project ID of the occurrences to retrieve"

  require "google/cloud/container_analysis"

  # Initialize the client
  client = Google::Cloud::ContainerAnalysis.container_analysis.grafeas_client

  parent = client.project_path project: project_id
  filter = "kind = \"DISCOVERY\" AND resourceUrl = \"#{resource_url}\""
  client.list_occurrences(parent: parent, filter: filter).each do |occurrence|
    # Process discovery occurrence here
    puts occurrence
  end
end

def occurrence_pubsub subscription_id:, timeout_seconds:, project_id:
  # subscription_id = "A user-specified identifier for the new subscription"
  # timeout_seconds = "The number of seconds to listen for new Pub/Sub messages"
  # project_id      = "Your Google Cloud project ID"

  require "google/cloud/pubsub"

  pubsub = Google::Cloud::PubSub.new project_id: project_id
  subscription_admin = pubsub.subscription_admin
  subscription = subscription_admin.create_subscription \
    name: pubsub.subscription_path(subscription_id),
    topic: pubsub.topic_path("container-analysis-occurrences-v1")

  subscriber = pubsub.subscriber subscription.name
  count = 0
  listener = subscriber.listen do |received_message|
    count += 1
    # Process incoming occurrence here
    puts "Message #{count}: #{received_message.data}"
    received_message.acknowledge!
  end

  listener.start
  # Wait for incoming occurrences
  sleep timeout_seconds
  listener.stop.wait!

  subscription_admin.delete_subscription subscription: subscription.name

  # Print and return the total number of Pub/Sub messages received
  puts "Total Messages Received: #{count}"
  count
end

# rubocop:disable Metrics/MethodLength

def poll_discovery_finished resource_url:, timeout_seconds:, project_id:
  # resource_url    = "The URL of the resource associated with the occurrence."
  #                   # e.g. https://gcr.io/project/image@sha256:123
  # timeout_seconds = "The number of seconds to wait for the discovery occurrence"
  # project_id      = "Your Google Cloud project ID"

  require "google/cloud/container_analysis"

  deadline = Time.now + timeout_seconds

  # Initialize the client
  client = Google::Cloud::ContainerAnalysis.container_analysis.grafeas_client
  parent = client.project_path project: project_id

  # Find the discovery occurrence using a filter string
  discovery_occurrence = nil
  while discovery_occurrence.nil?
    begin
      filter = "resourceUrl=\"#{resource_url}\" " \
               'AND noteProjectId="goog-analysis" ' \
               'AND noteId="PACKAGE_VULNERABILITY"'
      # The above filter isn't testable, since it looks for occurrences in a
      # locked down project. Fall back to a more permissive filter for testing
      filter = "kind = \"DISCOVERY\" AND resourceUrl = \"#{resource_url}\""
      # Only the discovery occurrence should be returned for the given filter
      discovery_occurrence = client.list_occurrences(parent: parent, filter: filter).first
    rescue StandardError # If there is an error, keep trying until the deadline
      puts "discovery occurrence not yet found"
    ensure
      # check for timeout
      sleep 1
      raise "Timeout while retrieving discovery occurrence." if Time.now > deadline
    end
  end

  # Wait for the discovery occurrence to enter a terminal state
  status = Grafeas::V1::DiscoveryOccurrence::AnalysisStatus::PENDING
  until [:FINISHED_SUCCESS, :FINISHED_FAILED, :FINISHED_UNSUPPORTED].include? status
    # Update occurrence
    begin
      updated = client.get_occurrence name: discovery_occurrence.name
      status = updated.discovery.analysis_status
    rescue StandardError # If there is an error, keep trying until the deadline
      puts "discovery occurrence not yet in terminal state"
    ensure
      # check for timeout
      sleep 1
      raise "Timeout while retrieving discovery occurrence." if Time.now > deadline
    end
  end
  puts "Found discovery occurrence #{updated.name}."
  puts "Status: #{updated.discovery.analysis_status}"
  updated
end

# rubocop:enable Metrics/MethodLength

def find_vulnerabilities_for_image resource_url:, project_id:
  # resource_url = "The URL of the resource associated with the occurrence
  #                e.g. https://gcr.io/project/image@sha256:123"
  # project_id   = "The Google Cloud project ID of the vulnerabilities to find"

  require "google/cloud/container_analysis"

  # Initialize the client
  client = Google::Cloud::ContainerAnalysis.container_analysis.grafeas_client

  parent = client.project_path project: project_id
  filter = "resourceUrl = \"#{resource_url}\" AND kind = \"VULNERABILITY\""
  client.list_occurrences parent: parent, filter: filter
end

def find_high_severity_vulnerabilities_for_image resource_url:, project_id:
  # resource_url       = "The URL of the resource associated with the occurrence."
  #                      # If you are using Google Container Registry
  #                      # e.g. https://gcr.io/project/repo/image@sha256:123
  #                      # If you are using Google Artifact Registry
  #                      # e.g. https://LOCATION-docker.pkg.dev/project/repo/image@sha256:123
  # project_id   = "The Google Cloud project ID of the vulnerabilities to find"

  require "google/cloud/container_analysis"

  # Initialize the client
  client = Google::Cloud::ContainerAnalysis.container_analysis.grafeas_client

  parent = client.project_path project: project_id
  filter = "resourceUrl = \"#{resource_url}\" AND kind = \"VULNERABILITY\""
  vulnerability_list = client.list_occurrences parent: parent, filter: filter
  # Filter the list to include only "high" and "critical" vulnerabilities
  vulnerability_list.select do |item|
    [:HIGH, :CRITICAL].include? item.vulnerability.effective_severity
  end
end

Python

如需了解如何安装和使用 Artifact Analysis 客户端库,请参阅 Artifact Analysis 客户端库。 如需了解详情,请参阅 Artifact Analysis Python API 参考文档

如需向 Artifact Analysis 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证

from google.cloud.devtools import containeranalysis_v1


def get_occurrences_for_note(note_id: str, project_id: str) -> int:
    """Retrieves all the occurrences associated with a specified Note.
    Here, all occurrences are printed and counted."""
    # note_id = 'my-note'
    # project_id = 'my-gcp-project'

    client = containeranalysis_v1.ContainerAnalysisClient()
    grafeas_client = client.get_grafeas_client()
    note_name = f"projects/{project_id}/notes/{note_id}"

    response = grafeas_client.list_note_occurrences(name=note_name)
    count = 0
    for o in response:
        # do something with the retrieved occurrence
        # in this sample, we will simply count each one
        count += 1
    return count

后续步骤