Mengonfigurasi notifikasi Pub/Sub

Dokumen ini menjelaskan cara menyiapkan notifikasi untuk pembaruan pada catatan dan kejadian.

Artifact Analysis memberikan notifikasi melalui Pub/Sub untuk kerentanan yang ditemukan oleh pemindaian otomatis dan untuk metadata lainnya. Saat catatan atau kemunculan dibuat atau diperbarui, pesan akan dipublikasikan ke topik yang sesuai untuk setiap versi API. Gunakan topik untuk versi API yang Anda gunakan.

Sebelum memulai

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Enable the Container Analysis API.

    Enable the API

  4. Install the Google Cloud CLI.
  5. To initialize the gcloud CLI, run the following command:

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

    Go to project selector

  7. Enable the Container Analysis API.

    Enable the API

  8. Install the Google Cloud CLI.
  9. To initialize the gcloud CLI, run the following command:

    gcloud init
  10. Pelajari cara menyiapkan kontrol akses untuk metadata di project Anda. Lewati langkah ini jika Anda hanya menggunakan metadata dari kemunculan kerentanan yang dibuat oleh pemindaian container Artifact Analysis.

Membuat topik Pub/Sub

Setelah Anda mengaktifkan Artifact Analysis API, Artifact Analysis akan otomatis membuat topik Pub/Sub dengan ID topik berikut:

  • container-analysis-notes-v1
  • container-analysis-occurrences-v1

Jika topik tidak sengaja dihapus atau tidak ada, Anda dapat menambahkannya sendiri. Misalnya, topik mungkin tidak ada jika organisasi Google Cloud Anda memiliki batasan kebijakan organisasi yang mewajibkan enkripsi dengan kunci enkripsi yang dikelola pelanggan (CMEK). Jika Pub/Sub API ada dalam daftar tolak batasan ini, layanan tidak dapat otomatis membuat topik dengan kunci milik dan dikelola Google.

Untuk membuat topik dengan kunci milik dan dikelola Google:

Konsol

  1. Buka halaman topik Pub/Sub di konsol Google Cloud.

    Buka halaman topik Pub/Sub

  2. Klik Buat Topik.

  3. Masukkan ID Topik:

    container-analysis-notes-v1
    

    sehingga namanya cocok dengan URI:

    projects/PROJECT_ID/topics/container-analysis-notes-v1
    

    dengan PROJECT_ID sebagai project ID Google Cloud Anda.

  4. Klik Create.

  5. Masukkan ID Topik:

    container-analysis-occurrences-v1
    

    sehingga namanya cocok dengan URI:

    projects/PROJECT_ID/topics/container-analysis-occurrences-v1
    

gcloud

Jalankan perintah berikut di shell atau jendela terminal:

gcloud pubsub topics create projects/PROJECT_ID/topics/container-analysis-notes-v1
gcloud pubsub topics create projects/PROJECT_ID/topics/container-analysis-occurrences-v1

Untuk mempelajari perintah gcloud pubsub topics lebih lanjut, lihat dokumentasi topics.

Untuk membuat topik dengan enkripsi CMEK, lihat petunjuk untuk mengenkripsi topik Pub/Sub.

Setiap kali catatan atau kejadian dibuat atau diperbarui, pesan akan dipublikasikan ke topik masing-masing, meskipun Anda juga harus membuat langganan Pub/Sub untuk memproses peristiwa dan menerima pesan dari layanan Pub/Sub.

Membuat langganan Pub/Sub

Untuk memproses peristiwa, buat langganan Pub/Sub yang terkait dengan topik:

Konsol

  1. Buka halaman langganan Pub/Sub di konsol Google Cloud.

    Buka halaman langganan Pub/Sub

  2. Klik Buat Langganan.

  3. Ketik nama untuk langganan. Misalnya, catatan.

  4. Masukkan URI topik untuk catatan:

    projects/PROJECT_ID/topics/container-analysis-notes-v1
    

    dengan PROJECT_ID sebagai project ID Google Cloud Anda.

  5. Klik Create.

  6. Buat langganan lain untuk kemunculan dengan URI:

    projects/PROJECT_ID/topics/container-analysis-occurrences-v1
    

gcloud

Untuk menerima peristiwa Pub/Sub, Anda harus membuat langganan terlebih dahulu yang terkait dengan topik container-analysis-occurrences-v1:

gcloud pubsub subscriptions create \
    --topic container-analysis-occurrences-v1 occurrences

Ke depannya, Anda dapat mengambil pesan yang berkaitan dengan kemunculan menggunakan langganan baru:

gcloud pubsub subscriptions pull \
    --auto-ack occurrences

Java

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Analisis Artefak, lihat library klien Analisis Artefak. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi Artifact Analysis Java API.

Untuk melakukan autentikasi ke Analisis Artefak, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

import com.google.cloud.pubsub.v1.AckReplyConsumer;
import com.google.cloud.pubsub.v1.MessageReceiver;
import com.google.cloud.pubsub.v1.Subscriber;
import com.google.cloud.pubsub.v1.SubscriptionAdminClient;
import com.google.pubsub.v1.ProjectSubscriptionName;
import com.google.pubsub.v1.PubsubMessage;
import com.google.pubsub.v1.PushConfig;
import com.google.pubsub.v1.Subscription;
import com.google.pubsub.v1.SubscriptionName;
import com.google.pubsub.v1.TopicName;
import io.grpc.StatusRuntimeException;
import java.io.IOException;
import java.lang.InterruptedException;
import java.util.concurrent.TimeUnit;

public class Subscriptions {
  // Handle incoming Occurrences using a Cloud Pub/Sub subscription
  public static int pubSub(String subId, long timeoutSeconds, String projectId)
      throws InterruptedException {
    // String subId = "my-occurrence-subscription";
    // long timeoutSeconds = 20;
    // String projectId = "my-project-id";
    Subscriber subscriber = null;
    MessageReceiverExample receiver = new MessageReceiverExample();

    try {
      // Subscribe to the requested Pub/Sub channel
      ProjectSubscriptionName subName = ProjectSubscriptionName.of(projectId, subId);
      subscriber = Subscriber.newBuilder(subName, receiver).build();
      subscriber.startAsync().awaitRunning();
      // Sleep to listen for messages
      TimeUnit.SECONDS.sleep(timeoutSeconds);
    } finally {
      // Stop listening to the channel
      if (subscriber != null) {
        subscriber.stopAsync();
      }
    }
    // Print and return the number of Pub/Sub messages received
    System.out.println(receiver.messageCount);
    return receiver.messageCount;
  }

  // Custom class to handle incoming Pub/Sub messages
  // In this case, the class will simply log and count each message as it comes in
  static class MessageReceiverExample implements MessageReceiver {
    public int messageCount = 0;

    @Override
    public synchronized void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) {
      // Every time a Pub/Sub message comes in, print it and count it
      System.out.println("Message " + messageCount + ": " + message.getData().toStringUtf8());
      messageCount += 1;
      // Acknowledge the message
      consumer.ack();
    }
  }

  // Creates and returns a Pub/Sub subscription object listening to the Occurrence topic
  public static Subscription createOccurrenceSubscription(String subId, String projectId) 
      throws IOException, StatusRuntimeException, InterruptedException {
    // This topic id will automatically receive messages when Occurrences are added or modified
    String topicId = "container-analysis-occurrences-v1";
    TopicName topicName = TopicName.of(projectId, topicId);
    SubscriptionName subName = SubscriptionName.of(projectId, subId);

    SubscriptionAdminClient client = SubscriptionAdminClient.create();
    PushConfig config = PushConfig.getDefaultInstance();
    Subscription sub = client.createSubscription(subName, topicName, config, 0);
    return sub;
  }
}

Go

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Analisis Artefak, lihat library klien Analisis Artefak. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi Artifact Analysis Go API.

Untuk melakukan autentikasi ke Analisis Artefak, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.


import (
	"context"
	"fmt"
	"io"
	"sync"
	"time"

	pubsub "cloud.google.com/go/pubsub"
)

// occurrencePubsub handles incoming Occurrences using a Cloud Pub/Sub subscription.
func occurrencePubsub(w io.Writer, subscriptionID string, timeout time.Duration, projectID string) (int, error) {
	// subscriptionID := fmt.Sprintf("my-occurrences-subscription")
	// timeout := time.Duration(20) * time.Second
	ctx := context.Background()

	var mu sync.Mutex
	client, err := pubsub.NewClient(ctx, projectID)
	if err != nil {
		return -1, fmt.Errorf("pubsub.NewClient: %w", err)
	}
	// Subscribe to the requested Pub/Sub channel.
	sub := client.Subscription(subscriptionID)
	count := 0

	// Listen to messages for 'timeout' seconds.
	ctx, cancel := context.WithTimeout(ctx, timeout)
	defer cancel()
	err = sub.Receive(ctx, func(ctx context.Context, msg *pubsub.Message) {
		mu.Lock()
		count = count + 1
		fmt.Fprintf(w, "Message %d: %q\n", count, string(msg.Data))
		msg.Ack()
		mu.Unlock()
	})
	if err != nil {
		return -1, fmt.Errorf("sub.Receive: %w", err)
	}
	// Print and return the number of Pub/Sub messages received.
	fmt.Fprintln(w, count)
	return count, nil
}

// createOccurrenceSubscription creates a new Pub/Sub subscription object listening to the Occurrence topic.
func createOccurrenceSubscription(subscriptionID, projectID string) error {
	// subscriptionID := fmt.Sprintf("my-occurrences-subscription")
	ctx := context.Background()
	client, err := pubsub.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("pubsub.NewClient: %w", err)
	}
	defer client.Close()

	// This topic id will automatically receive messages when Occurrences are added or modified
	topicID := "container-analysis-occurrences-v1"
	topic := client.Topic(topicID)
	config := pubsub.SubscriptionConfig{Topic: topic}
	_, err = client.CreateSubscription(ctx, subscriptionID, config)
	return fmt.Errorf("client.CreateSubscription: %w", err)
}

Node.js

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Analisis Artefak, lihat library klien Analisis Artefak. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi Artifact Analysis Node.js API.

Untuk melakukan autentikasi ke Analisis Artefak, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

/**
 * TODO(developer): Uncomment these variables before running the sample
 */
// const projectId = 'your-project-id', // Your GCP Project ID
// const subscriptionId = 'my-sub-id', // A user-specified subscription to the 'container-analysis-occurrences-v1' topic
// const timeoutSeconds = 30 // The number of seconds to listen for the new Pub/Sub Messages

// Import the pubsub library and create a client, topic and subscription
const {PubSub} = require('@google-cloud/pubsub');
const pubsub = new PubSub({projectId});
const subscription = pubsub.subscription(subscriptionId);

// Handle incoming Occurrences using a Cloud Pub/Sub subscription
let count = 0;
const messageHandler = message => {
  count++;
  message.ack();
};

// Listen for new messages until timeout is hit
subscription.on('message', messageHandler);

setTimeout(() => {
  subscription.removeListener('message', messageHandler);
  console.log(`Polled ${count} occurrences`);
}, timeoutSeconds * 1000);

Ruby

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Analisis Artefak, lihat library klien Analisis Artefak. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi Artifact Analysis Ruby API.

Untuk melakukan autentikasi ke Analisis Artefak, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

# 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

Python

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Analisis Artefak, lihat library klien Analisis Artefak. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi Artifact Analysis Python API.

Untuk melakukan autentikasi ke Analisis Artefak, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

import time

from google.api_core.exceptions import AlreadyExists
from google.cloud.pubsub import SubscriberClient
from google.cloud.pubsub_v1.subscriber.message import Message


def pubsub(subscription_id: str, timeout_seconds: int, project_id: str) -> int:
    """Respond to incoming occurrences using a Cloud Pub/Sub subscription."""
    # subscription_id := 'my-occurrences-subscription'
    # timeout_seconds = 20
    # project_id = 'my-gcp-project'

    client = SubscriberClient()
    subscription_name = client.subscription_path(project_id, subscription_id)
    receiver = MessageReceiver()
    client.subscribe(subscription_name, receiver.pubsub_callback)

    # listen for 'timeout' seconds
    for _ in range(timeout_seconds):
        time.sleep(1)
    # print and return the number of pubsub messages received
    print(receiver.msg_count)
    return receiver.msg_count


class MessageReceiver:
    """Custom class to handle incoming Pub/Sub messages."""

    def __init__(self) -> None:
        # initialize counter to 0 on initialization
        self.msg_count = 0

    def pubsub_callback(self, message: Message) -> None:
        # every time a pubsub message comes in, print it and count it
        self.msg_count += 1
        print(f"Message {self.msg_count}: {message.data}")
        message.ack()


def create_occurrence_subscription(subscription_id: str, project_id: str) -> bool:
    """Creates a new Pub/Sub subscription object listening to the
    Container Analysis Occurrences topic."""
    # subscription_id := 'my-occurrences-subscription'
    # project_id = 'my-gcp-project'

    topic_id = "container-analysis-occurrences-v1"
    client = SubscriberClient()
    topic_name = f"projects/{project_id}/topics/{topic_id}"
    subscription_name = client.subscription_path(project_id, subscription_id)
    success = True
    try:
        client.create_subscription({"name": subscription_name, "topic": topic_name})
    except AlreadyExists:
        # if subscription already exists, do nothing
        pass
    else:
        success = False
    return success

Aplikasi pelanggan hanya menerima pesan yang dipublikasikan ke topik setelah langganan dibuat.

Payload Pub/Sub dalam JSON dan skemanya adalah sebagai berikut:

Catatan:

{
    "name": "projects/PROJECT_ID/notes/NOTE_ID",
    "kind": "NOTE_KIND",
    "notificationTime": "NOTIFICATION_TIME",
}

Kejadian:

{
    "name": "projects/PROJECT_ID/occurrences/OCCURRENCE_ID",
    "kind": "NOTE_KIND",
    "notificationTime": "NOTIFICATION_TIME",
}

dengan:

  • NOTE_KIND adalah salah satu nilai dalam NoteKind
  • NOTIFICATION_TIME adalah stempel waktu dalam format RFC 3339 UTC "Zulu", yang akurat hingga nanodetik.

Lihat detail

Untuk mempelajari catatan atau kemunculan lebih lanjut, Anda dapat mengakses metadata yang disimpan di Analisis Artefak. Misalnya, Anda dapat meminta semua detail untuk peristiwa tertentu. Lihat petunjuk di Menginvestigasi Kerentanan.

Langkah selanjutnya

  • Untuk petunjuk tentang cara menggunakan Analisis Artefak untuk menyimpan dan mengelola metadata kustom, lihat Membuat catatan dan kemunculan kustom.

  • Anda dapat menggunakan pengesahan dengan pemindaian kerentanan untuk mencegah image dengan masalah keamanan umum agar tidak berjalan di lingkungan deployment Anda. Untuk mengetahui petunjuk cara melakukannya, lihat Membuat pengesahan dengan Kritis Signer.