Configurazione delle notifiche Pub/Sub

Questo documento descrive come configurare le notifiche per gli aggiornamenti di note e occorrenze.

Artifact Analysis fornisce notifiche tramite Pub/Sub per le vulnerabilità trovate dalla scansione automatica e per altri metadati. Quando viene creata o aggiornata una nota o un evento, viene pubblicato un messaggio nell'argomento corrispondente per ogni versione dell'API. Utilizza l'argomento per la versione dell'API che stai utilizzando.

Prima di iniziare

  1. Accedi al tuo account Google Cloud . Se non conosci Google Cloud, crea un account per valutare le prestazioni dei nostri prodotti in scenari reali. I nuovi clienti ricevono anche 300 $di crediti senza costi per l'esecuzione, il test e il deployment dei workload.
  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. Installa Google Cloud CLI.

  5. Se utilizzi un provider di identità (IdP) esterno, devi prima accedere a gcloud CLI con la tua identità federata.

  6. Per inizializzare gcloud CLI, esegui questo comando:

    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. Installa Google Cloud CLI.

  10. Se utilizzi un provider di identità (IdP) esterno, devi prima accedere a gcloud CLI con la tua identità federata.

  11. Per inizializzare gcloud CLI, esegui questo comando:

    gcloud init
  12. Scopri come configurare il controllo dell'accesso per i metadati nel tuo progetto. Ignora questo passaggio se utilizzi solo i metadati delle occorrenze create dalla scansione dei container di Artifact Analysis.

Crea argomenti Pub/Sub

Dopo aver attivato l'API Artifact Analysis, Artifact Analysis crea automaticamente argomenti Pub/Sub con i seguenti ID argomento:

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

Se gli argomenti sono stati eliminati per errore o non sono presenti, puoi aggiungerli manualmente. Ad esempio, gli argomenti potrebbero non essere presenti se la tua Google Cloud organizzazione ha un vincolo di policy dell'organizzazione che richiede la crittografia con chiavi di crittografia gestite dal cliente (CMEK). Quando l'API Pub/Sub si trova nell'elenco negato di questo vincolo, i servizi non possono creare automaticamente argomenti conGoogle-owned and Google-managed encryption keys.

Per creare gli argomenti con Google-owned and Google-managed encryption keys:

Console

  1. Vai alla pagina degli argomenti Pub/Sub nella console Google Cloud .

    Apri la pagina degli argomenti Pub/Sub

  2. Fai clic su Crea argomento.

  3. Inserisci un ID argomento:

    container-analysis-notes-v1
    

    in modo che il nome corrisponda all'URI:

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

    dove PROJECT_ID è l' Google Cloud ID progetto.

  4. Fai clic su Crea.

  5. Inserisci un ID argomento:

    container-analysis-occurrences-v1
    

    in modo che il nome corrisponda all'URI:

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

gcloud

Esegui questi comandi nella finestra della shell o del terminale:

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

Per saperne di più sul comando gcloud pubsub topics, consulta la documentazione di topics.

Per creare gli argomenti con la crittografia CMEK, consulta le istruzioni per la crittografia degli argomenti di Pub/Sub.

Ogni volta che viene creata o aggiornata una nota o un'occorrenza, viene pubblicato un messaggio nell'argomento corrispondente, anche se devi creare un abbonamento Pub/Sub per rimanere in ascolto degli eventi e ricevere messaggi dal servizio Pub/Sub.

Crea sottoscrizioni Pub/Sub

Per ascoltare gli eventi, crea una sottoscrizione Pub/Sub associata all'argomento:

Console

  1. Vai alla pagina Sottoscrizioni Pub/Sub nella consoleGoogle Cloud .

    Apri la pagina delle sottoscrizioni Pub/Sub

  2. Fai clic su Crea sottoscrizione.

  3. Digita un nome per l'abbonamento. Ad esempio, note.

  4. Inserisci l'URI dell'argomento per le note:

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

    dove PROJECT_ID è l' Google Cloud ID progetto.

  5. Fai clic su Crea.

  6. Crea un'altra sottoscrizione per le occorrenze con l'URI:

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

gcloud

Per ricevere eventi Pub/Sub, devi prima creare una sottoscrizione associata all'argomento container-analysis-occurrences-v1:

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

In futuro, potrai estrarre i messaggi relativi ai tuoi eventi utilizzando il tuo nuovo abbonamento:

gcloud pubsub subscriptions pull \
    --auto-ack occurrences

Java

Per scoprire come installare e utilizzare la libreria client per Artifact Analysis, consulta Librerie client di Artifact Analysis. Per saperne di più, consulta la documentazione di riferimento dell'API Artifact Analysis Java.

Per eseguire l'autenticazione in Artifact Analysis, configura le Credenziali predefinite dell'applicazione. Per saperne di più, consulta Configura l'autenticazione per un ambiente di sviluppo locale.

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

Per scoprire come installare e utilizzare la libreria client per Artifact Analysis, consulta Librerie client di Artifact Analysis. Per saperne di più, consulta la documentazione di riferimento dell'API Artifact Analysis Go.

Per eseguire l'autenticazione in Artifact Analysis, configura le Credenziali predefinite dell'applicazione. Per saperne di più, consulta Configura l'autenticazione per un ambiente di sviluppo locale.


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

Per scoprire come installare e utilizzare la libreria client per Artifact Analysis, consulta Librerie client di Artifact Analysis. Per saperne di più, consulta la documentazione di riferimento dell'API Artifact Analysis Node.js.

Per eseguire l'autenticazione in Artifact Analysis, configura le Credenziali predefinite dell'applicazione. Per saperne di più, consulta Configura l'autenticazione per un ambiente di sviluppo locale.

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

Per scoprire come installare e utilizzare la libreria client per Artifact Analysis, consulta Librerie client di Artifact Analysis. Per saperne di più, consulta la documentazione di riferimento dell'API Artifact Analysis Ruby.

Per eseguire l'autenticazione in Artifact Analysis, configura le Credenziali predefinite dell'applicazione. Per saperne di più, consulta Configura l'autenticazione per un ambiente di sviluppo locale.

# 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

Python

Per scoprire come installare e utilizzare la libreria client per Artifact Analysis, consulta Librerie client di Artifact Analysis. Per saperne di più, consulta la documentazione di riferimento dell'API Artifact Analysis Python.

Per eseguire l'autenticazione in Artifact Analysis, configura le Credenziali predefinite dell'applicazione. Per saperne di più, consulta Configura l'autenticazione per un ambiente di sviluppo locale.

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

Le applicazioni del sottoscrittore ricevono solo i messaggi pubblicati nell'argomento dopo la creazione della sottoscrizione.

I payload Pub/Sub sono in formato JSON e il loro schema è il seguente:

Note:

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

Occorrenze:

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

dove:

  • NOTE_KIND è uno dei valori in NoteKind
  • NOTIFICATION_TIME è un timestamp in formato "Zulu" UTC RFC 3339, preciso al nanosecondo.

Visualizza dettagli

Per saperne di più su una nota o un evento, puoi accedere ai metadati archiviati in Artifact Analysis. Ad esempio, puoi richiedere tutti i dettagli di un evento specifico. Consulta le istruzioni in Analizzare le vulnerabilità.

Passaggi successivi