Pub/Sub-Benachrichtigungen

In diesem Dokument wird beschrieben, wie Benachrichtigungen für Aktualisierungen von Hinweisen und Vorkommen eingerichtet werden.

Container Registry stellt Benachrichtigungen über Cloud Pub/Sub bereit, wenn nach Sicherheitslücken und anderen Metadaten gesucht wird. Wenn ein Hinweis oder ein Vorkommen erstellt oder aktualisiert wird, wird für jede API-Version eine Nachricht an das entsprechende Thema veröffentlicht. Verwenden Sie das Thema, das Ihrer aktuellen API-Version entspricht.

Vorbereitung

  1. Container Analysis API aktivieren.

  2. Übersicht über Container Analysis

Pub/Sub-Themen erstellen

Nachdem Sie die Container Analysis API aktiviert haben, werden folgende Pub/Sub-Themen für Sie in Ihrem Projekt erstellt:

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

Wenn die Themen versehentlich gelöscht wurden oder fehlen, können Sie sie selbst hinzufügen.

Console

  1. Rufen Sie in der Cloud Console die Seite "Pub/Sub-Themen" auf.

    Seite "Pub/Sub-Themen" öffnen

  2. Klicken Sie auf Thema erstellen.

  3. Geben Sie ein Thema für Hinweise mit dem URI ein:

    projects/[PROJECT-ID]/topics/container-analysis-notes-v1
    

    Dabei ist [PROJECT-ID] Ihre Google Cloud-Projekt-ID.

  4. Klicken Sie auf Erstellen.

  5. Erstellen Sie ein anderes Thema für Vorkommen mit dem URI:

     projects/[PROJECT-ID]/topics/container-analysis-occurrences-v1
    

gcloud

Führen Sie die folgenden Befehle in der Shell oder im Terminalfenster aus:

gcloud pubsub topics create projects/[PROJECT-ID]/topics/container-analysis-notes-v1
gcloud pubsub topics create projects/[PROJECT-ID]/topics/container-analysis-occurrences-v1

Weitere Informationen zum Befehl gcloud pubsub topics finden Sie in der topics-Dokumentation.

Bei jedem Erstellen oder Aktualisieren einer Notiz oder eines Vorkommens wird im entsprechenden Thema eine Nachricht veröffentlicht.

Pub/Sub-Nutzlasten haben das JSON-Format und folgendes Schema:

Notizen:

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

Vorkommen:

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

Dabei gilt:

  • [NOTE_KIND] ist einer der Werte in NoteKind.
  • [NOTIFICATION_TIME] ist ein Zeitstempel im Format RFC 3339 UTC "Zulu'" in Nanosekunden.

Pub/Sub-Abos erstellen

Damit Sie Ereignisse erhalten, erstellen Sie ein mit dem Thema verknüpftes Pub/Sub-Abo:

Console

  1. Rufen Sie in der Cloud Console die Seite "Pub/Sub-Abos" auf.

    Seite "Pub/Sub-Abos" öffnen

  2. Klicken Sie auf Abo erstellen.

  3. Geben Sie einen Namen für das Abo ein. Beispiel: Hinweise.

  4. Geben Sie den URI des Themas für Hinweise ein:

    projects/[PROJECT-ID]/topics/container-analysis-notes-v1
    

    Dabei ist [PROJECT-ID] Ihre Google Cloud-Projekt-ID.

  5. Klicken Sie auf Erstellen.

  6. Erstellen Sie ein weiteres Abo für Vorkommen mit dem URI:

     projects/[PROJECT-ID]/topics/container-analysis-occurrences-v1
    

gcloud

Damit Sie Pub/Sub-Ereignisse erhalten, müssen Sie zuerst ein Abo erstellen, das mit dem Thema container-analysis-occurrences-v1 verknüpft ist:

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

Jetzt können Sie über Ihr neues Abo Nachrichten bezüglich Ihrer Vorkommen abrufen:

gcloud pubsub subscriptions pull \
    --auto-ack occurrences

Java

Wie Sie die Clientbibliothek für Container Registry installieren und verwenden, erfahren Sie unter Container Registry-Clientbibliotheken. Weitere Informationen finden Sie in der Referenzdokumentation zur Container Registry Java API.

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.ProjectTopicName;
import com.google.pubsub.v1.PubsubMessage;
import com.google.pubsub.v1.PushConfig;
import com.google.pubsub.v1.Subscription;
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";
    ProjectTopicName topicName = ProjectTopicName.of(projectId, topicId);
    ProjectSubscriptionName subName = ProjectSubscriptionName.of(projectId, subId);

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

Go

Wie Sie die Clientbibliothek für Container Registry installieren und verwenden, erfahren Sie unter Container Registry-Clientbibliotheken. Weitere Informationen finden Sie in der Referenzdokumentation zur Container Registry Go API.


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: %v", 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: %v", 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: %v", 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: %v", err)
}

Node.js

Wie Sie die Clientbibliothek für Container Registry installieren und verwenden, erfahren Sie unter Container Registry-Clientbibliotheken. Weitere Informationen finden Sie in der Referenzdokumentation zur Container Registry Node.js API.

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

Wie Sie die Clientbibliothek für Container Registry installieren und verwenden, erfahren Sie unter Container Registry-Clientbibliotheken. Weitere Informationen finden Sie in der Referenzdokumentation zur Container Registry Ruby API.

# 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

Wie Sie die Clientbibliothek für Container Registry installieren und verwenden, erfahren Sie unter Container Registry-Clientbibliotheken. Weitere Informationen finden Sie in der Referenzdokumentation zur Container Registry Python API.

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

    import time
    from google.cloud.pubsub import SubscriberClient

    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):
        # initialize counter to 0 on initialization
        self.msg_count = 0

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

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

    from google.api_core.exceptions import AlreadyExists
    from google.cloud.pubsub import SubscriberClient

    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

Abonnentenanwendungen erhalten nur die Nachrichten, die nach dem Erstellen des Abos für das Thema veröffentlicht wurden.

Weitere Informationen

  • Informationen zur Verwendung von Container Analysis zum Speichern und Verwalten der Metadaten Ihrer Kunden finden Sie unter Metadaten für Images bereitstellen.

  • Sie können die Binärautorisierung in das Scannen auf Sicherheitslücken einbinden, um zu verhindern, dass Images mit bekannten Sicherheitslücken in Ihrer Bereitstellungsumgebung ausgeführt werden. Unter Scannen auf Sicherheitslücken einbinden erfahren Sie mehr dazu.