为映像提供元数据

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

请按照以下步骤使用 Container Analysis API 为您的映像提供自定义漏洞元数据。您可以使用相同的说明存储和检索 Container Analysis 支持的任何类型的元数据

准备工作

  1. 启用 Container Scanning API。此操作可以启用漏洞扫描以及 Container Analysis API。您可以为现有项目启用 API,也可以创建新项目,然后再启用 API。您可以稍后手动停用漏洞扫描

    启用 Container Scanning API

  2. 阅读 Container Analysis 概览

为项目创建漏洞备注和发生实例

本部分介绍第三方漏洞提供方如何为其用户的项目创建备注和事件。

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

创建备注

IAM 权限:

要执行此项任务,您必须对提供方的项目(即用于创建备注的项目)具有以下 IAM 权限

  • containeranalysis.notes.create

也可以授予以下预定义的 IAM 角色,该角色将自动提供所有必要的权限:

  • 您的项目的 Container Analysis 备注编辑者角色。

要创建备注,请执行以下操作:

API

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

    {
        "shortDescription": "A brief Description of the note",
        "longDescription": "A longer description of the note",
        "kind": "PACKAGE_VULNERABILITY",
        "vulnerabilityType": {
            "details": [
            {
                "package": "libexempi3",
                "cpeUri": "cpe:/o:debian:debian_linux:7",
                "minAffectedVersion": { "name": "2.5.7", "revision": "1"},
                "maxAffectedVersion": { "name": "2.5.9", "revision": "1"},
            },
            {
                "cpeUri": "something else"
            }
            ]
        }
    }
    
  2. 运行以下 curl 命令以创建备注,其中 [PROVIDER_PROJECT_ID] 是您的项目 ID:

    curl -X POST -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
    

Java

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

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.VulnerabilityNote;
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://cloud.google.com/container-registry/docs/container-analysis#supported_metadata_types
        // Here, we use the type "vulnerability"
        .setVulnerability(VulnerabilityNote.newBuilder()
            .addDetails(VulnerabilityNote.Detail.newBuilder()
                .setAffectedCpeUri("your-uri-here")
                .setAffectedPackage("your-package-here")
                .setAffectedVersionStart(Version.newBuilder()
                    .setKind(Version.VersionKind.MINIMUM))
                .setAffectedVersionEnd(Version.newBuilder()
                    .setKind(Version.VersionKind.MAXIMUM))))
        .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

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


import (
	"context"
	"fmt"

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

// createNote creates and returns a new vulnerability 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: %v", err)
	}
	defer client.Close()

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

	req := &grafeaspb.CreateNoteRequest{
		Parent: projectName,
		NoteId: noteID,
		Note: &grafeaspb.Note{
			Type: &grafeaspb.Note_Vulnerability{
				// The 'Vulnerability' field can be modified to contain information about your vulnerability.
				Vulnerability: &grafeaspb.VulnerabilityNote{
					Details: []*grafeaspb.VulnerabilityNote_Detail{
						{
							AffectedCpeUri:  "your-uri-here",
							AffectedPackage: "your-package-here",
							AffectedVersionStart: &grafeaspb.Version{
								Kind: grafeaspb.Version_MINIMUM,
							},
							AffectedVersionEnd: &grafeaspb.Version{
								Kind: grafeaspb.Version_MAXIMUM,
							},
						},
					},
				},
			},
		},
	}

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

Node.js

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

/**
 * 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();

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

// Creates and returns a new Note
const [note] = await client.getGrafeasClient().createNote({
  parent: formattedParent,
  noteId: noteId,
  note: {
    vulnerability: {
      details: [
        {
          affectedCpeUri: 'foo.uri',
          affectedPackage: 'foo',
          affectedVersionStart: {
            kind: 'MINIMUM',
          },
          affectedVersionEnd: {
            kind: 'MAXIMUM',
          },
        },
      ],
    },
  },
});

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

Ruby

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

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

require "grafeas"

# Initialize the client
client = Grafeas.new

formatted_parent = Grafeas::V1::GrafeasClient.project_path project_id
note = {
  vulnerability: {
    details: [
      affected_cpe_uri:     "your-uri-here",
      affected_package:     "your-package-here",
      min_affected_version: { kind: :MINIMUM },
      fixed_version:        { kind: :MAXIMUM }
    ]
  }
}
response = client.create_note formatted_parent, note_id, note
puts response.name

Python

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

def create_note(note_id, project_id):
    """Creates and returns a new vulnerability note."""
    # note_id = 'my-note'
    # project_id = 'my-gcp-project'

    from grafeas.grafeas_v1.gapic.enums import Version
    from google.cloud.devtools import containeranalysis_v1

    client = containeranalysis_v1.ContainerAnalysisClient()
    grafeas_client = client.get_grafeas_client()
    project_name = grafeas_client.project_path(project_id)
    note = {
        'vulnerability': {
            'details': [
                {
                    'affected_cpe_uri': 'your-uri-here',
                    'affected_package': 'your-package-here',
                    'min_affected_version': {
                        'kind': Version.VersionKind.MINIMUM
                    },
                    'fixed_version': {
                        'kind': Version.VersionKind.MAXIMUM
                    }
                }
            ]
        }
    }
    response = grafeas_client.create_note(project_name, note_id, note)
    return response

为备注创建发生实例

IAM 权限:

要执行此项任务,您必须拥有以下 IAM 权限

  • 客户项目的 containeranalysis.occurrences.create 权限
  • 您的项目的 containeranalysis.notes.attachOccurrence 权限。

也可以授予以下预定义的 IAM 角色,该角色将自动提供所有必要的权限:

  • 客户项目的 Container Analysis 事件编辑者角色
  • 您的项目的 Container Analysis 备注附加者角色。

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

API

  1. 创建名为 occurrence.json 的文件,其中包含以下内容:

    {
        "resourceUrl": "<resource_url>",
        "noteName": "projects/<provider-project-id>/notes/<note_id>",
        "kind": "PACKAGE_VULNERABILITY",
        "vulnerabilityDetails": {
            "packageIssue": [{
                "affectedLocation": {
                    "cpeUri": "7",
                    "package": "a",
                    "version":  {
                        "epoch": "1"
                        "name": "namestring"
                        "revision": "r"
                    },
                },
                "fixedLocation": {
                    "cpeUri": "cpe:/o:debian:debian_linux:7",
                    "package": "a",
                    "version":  {
                        "epoch": "2"
                        "name": "namestring"
                        "revision": "1"
                    }
                }
            }]
        }
    }
    
  2. 运行以下 curl 命令,其中 [CUSTOMER_PROJECT_ID] 是您的客户的项目 ID:

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

Java

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

import com.google.cloud.devtools.containeranalysis.v1.ContainerAnalysisClient;
import io.grafeas.v1.GrafeasClient;
import io.grafeas.v1.NoteName;
import io.grafeas.v1.Occurrence;
import io.grafeas.v1.ProjectName;
import io.grafeas.v1.Version;
import io.grafeas.v1.VulnerabilityOccurrence;
import io.grafeas.v1.VulnerabilityOccurrence.PackageIssue;
import java.io.IOException;
import java.lang.InterruptedException;

public class CreateOccurrence {
  // Creates and returns a new vulnerability Occurrence associated with an existing Note
  public static Occurrence createOccurrence(String resourceUrl, String noteId,
      String occProjectId, String noteProjectId) throws IOException, InterruptedException {
    // 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)
        .setVulnerability(VulnerabilityOccurrence.newBuilder()
            .addPackageIssue(PackageIssue.newBuilder()
                .setAffectedCpeUri("your-uri-here")
                .setAffectedPackage("your-package-here")
                .setAffectedVersion(Version.newBuilder()
                    .setKind(Version.VersionKind.MINIMUM))
                .setFixedVersion(Version.newBuilder()
                    .setKind(Version.VersionKind.MAXIMUM))))
        .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

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


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 vulnerability Note.
func createOccurrence(resourceURL, noteID, occProjectID, noteProjectID string) (*grafeaspb.Occurrence, error) {
	// resourceURL := fmt.Sprintf("https://gcr.io/my-project/my-image")
	// noteID := fmt.Sprintf("my-note")
	ctx := context.Background()
	client, err := containeranalysis.NewClient(ctx)
	if err != nil {
		return nil, fmt.Errorf("NewClient: %v", 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 vulnerability instance can be added here.
			Details: &grafeaspb.Occurrence_Vulnerability{
				Vulnerability: &grafeaspb.VulnerabilityOccurrence{
					PackageIssue: []*grafeaspb.VulnerabilityOccurrence_PackageIssue{
						{
							AffectedCpeUri:  "your-uri-here",
							AffectedPackage: "your-package-here",
							AffectedVersion: &grafeaspb.Version{
								Kind: grafeaspb.Version_MINIMUM,
							},
							FixedVersion: &grafeaspb.Version{
								Kind: grafeaspb.Version_MAXIMUM,
							},
						},
					},
				},
			},
		},
	}
	return client.GetGrafeasClient().CreateOccurrence(ctx, req)
}

Node.js

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

/**
 * TODO(developer): Uncomment these variables before running the sample
 */
// const noteProjectId = 'your-project-id', // Your GCP Project Id
// const noteId = 'my-note-id', // Id of the note
// const occurrenceProjectId = 'your-project-id', // GCP Project Id of Occurrence
// const imageUrl = 'https://gcr.io/my-project/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,
    vulnerability: {
      packageIssue: [
        {
          affectedCpeUri: 'foo.uri',
          affectedPackage: 'foo',
          affectedVersion: {
            kind: 'MINIMUM',
          },
          fixedVersion: {
            kind: 'MAXIMUM',
          },
        },
      ],
    },
  },
});
console.log(`Occurrence created ${occurrence.name}.`);
return occurrence;

Ruby

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

# resource_url       = "The URL of the resource associated with the
#                       occurrence.
#                       e.g. https://gcr.io/project/image@sha256:123
# note_id            = "The identifier of the note associated with the
#                       occurrence"
# occurrence_project = "The Google Cloud project ID for the new occurrence"
# note_project       = "The Google Cloud project ID of the associated note"

require "grafeas"

# Initialize the client
client = Grafeas.new
formatted_note = Grafeas::V1::GrafeasClient.note_path note_project, note_id
formatted_project = Grafeas::V1::GrafeasClient.project_path occurrence_project

occurrence = {
  note_name:     formatted_note,
  resource_uri:  resource_url,
  vulnerability: {
    package_issue: [
      affected_cpe_uri:     "your-uri-here:",
      affected_package:     "your-package-here",
      min_affected_version: { kind: :MINIMUM },
      fixed_version:        { kind: :MAXIMUM }
    ]
  }
}

response = client.create_occurrence formatted_project, occurrence
puts response.name

Python

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

def create_occurrence(resource_url, note_id, occurrence_project, note_project):
    """ Creates and returns a new occurrence of a previously
    created vulnerability note."""
    # resource_url = 'https://gcr.io/my-project/my-image@sha256:123'
    # note_id = 'my-note'
    # occurrence_project = 'my-gcp-project'
    # note_project = 'my-gcp-project'

    from grafeas.grafeas_v1.gapic.enums import Version
    from google.cloud.devtools import containeranalysis_v1

    client = containeranalysis_v1.ContainerAnalysisClient()
    grafeas_client = client.get_grafeas_client()
    formatted_note = grafeas_client.note_path(note_project, note_id)
    formatted_project = grafeas_client.project_path(occurrence_project)

    occurrence = {
        'note_name': formatted_note,
        'resource_uri': resource_url,
        'vulnerability': {
            'package_issue': [
                {
                    'affected_cpe_uri': 'your-uri-here',
                    'affected_package': 'your-package-here',
                    'min_affected_version': {
                        'kind': Version.VersionKind.MINIMUM
                    },
                    'fixed_version': {
                        'kind': Version.VersionKind.MAXIMUM
                    }
                }
            ]
        }
    }

    return grafeas_client.create_occurrence(formatted_project, occurrence)

获取特定备注的所有发生实例

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

IAM 权限:

要执行此项任务,您必须拥有以下 IAM 权限

  • 您的项目的 containeranalysis.notes.listOccurrences 权限

也可以授予以下预定义的 IAM 角色,该角色将自动提供所有必要的权限:

  • 您的项目的 Container Analysis 事件查看者角色

要获取某一备注对应的所有事件,请按如下所述操作:

API

要列出某一备注对应的所有事件,请按如下方式发送 GET 请求:

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

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

Java

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

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

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


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: %v", 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: %v", err)
		}
		// Write custom code to process each Occurrence here.
		fmt.Fprintln(w, occ)
		count = count + 1
	}
	return count, nil
}

Node.js

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

/**
 * 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

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

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

  require "grafeas"

  # Initialize the client
  client = Grafeas.new

  formatted_note = Grafeas::V1::GrafeasClient.note_path project_id, note_id
  count = 0
  client.list_note_occurrences(formatted_note).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 "grafeas"

  # Initialize the client
  client = Grafeas.new

  formatted_parent = Grafeas::V1::GrafeasClient.project_path project_id
  filter = "kind = \"DISCOVERY\" AND resourceUrl = \"#{resource_url}\""
  client.list_occurrences(formatted_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: project_id
  topic = pubsub.topic "container-analysis-occurrences-v1"
  subscription = topic.subscribe subscription_id

  count = 0
  subscriber = subscription.listen do |received_message|
    count += 1
    # Process incoming occurrence here
    puts "Message #{count}: #{received_message.data}"
    received_message.acknowledge!
  end
  subscriber.start
  # Wait for incomming occurrences
  sleep timeout_seconds
  subscriber.stop.wait!
  subscription.delete
  # Print and return the total number of Pub/Sub messages received
  puts "Total Messages Received: #{count}"
  count
end

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 "grafeas"

  deadline = Time.now + timeout_seconds

  # Initialize the client
  client = Grafeas.new
  formatted_parent = Grafeas::V1::GrafeasClient.project_path 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(formatted_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
      if Time.now > deadline
        raise "Timeout while retrieving discovery occurrence."
      end
    end
  end

  # Wait for the discovery occurrence to enter a terminal state
  status = Grafeas::V1::DiscoveryOccurrence::AnalysisStatus::PENDING
  while status != :FINISHED_SUCCESS &&
        status != :FINISHED_FAILED &&
        status != :FINISHED_UNSUPPORTED
    # Update occurrence
    begin
      updated = client.get_occurrence 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
      if Time.now > deadline
        raise "Timeout while retrieving discovery occurrence."
      end
    end
  end
  puts "Found discovery occurrence #{updated.name}."
  puts "Status: #{updated.discovery.analysis_status}"
  updated
end

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 "grafeas"

  # Initialize the client
  client = Grafeas.new

  formatted_parent = Grafeas::V1::GrafeasClient.project_path project_id
  filter = "resourceUrl = \"#{resource_url}\" AND kind = \"VULNERABILITY\""
  client.list_occurrences formatted_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,
  #                 e.g. https://gcr.io/project/image@sha256:123"
  # project_id   = "The Google Cloud project ID of the vulnerabilities to find"

  require "grafeas"

  # Initialize the client
  client = Grafeas.new

  formatted_parent = Grafeas::V1::GrafeasClient.project_path project_id
  filter = "resourceUrl = \"#{resource_url}\" AND kind = \"VULNERABILITY\""
  vulnerability_list = client
                       .list_occurrences(formatted_parent, filter: filter)
  # Filter the list to include only "high" and "critical" vulnerabilities
  vulnerability_list.select do |item|
    item.vulnerability.severity == :HIGH || item.vulnerability.severity == :CRITICAL
  end
end

Python

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

def get_occurrences_for_note(note_id, project_id):
    """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'

    from google.cloud.devtools import containeranalysis_v1

    client = containeranalysis_v1.ContainerAnalysisClient()
    grafeas_client = client.get_grafeas_client()
    note_name = grafeas_client.note_path(project_id, note_id)

    response = grafeas_client.list_note_occurrences(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

后续步骤

  • 如需了解如何查看、过滤和获取关于 Container Registry 映像漏洞的通知,请参阅获取映像漏洞
此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
Container Registry 文档