Creazione di un notifier personalizzato

Cloud Build può inviarti notifiche sugli aggiornamenti dello stato della build ai canali selezionati. Oltre ai notificatori gestiti da Cloud Build, come Slack o SMTP, puoi anche utilizzare la libreria fornita nel repository cloud-build-notifiers per creare il tuo notificatore.

Questa pagina spiega come creare il tuo notificatore.

Prima di iniziare

  • Abilita le API Cloud Build, Cloud Run, Pub/Sub e Secret Manager.

    Ruoli richiesti per abilitare le API

    Per abilitare le API, devi disporre del ruolo IAM Amministratore utilizzo servizi (roles/serviceusage.serviceUsageAdmin), che contiene l'autorizzazione serviceusage.services.enable. Scopri come concedere i ruoli.

    Abilita le API

  • Installa il linguaggio di programmazione Go.

  • Installa la Google Cloud CLI.

Configurazione

  1. Apri una finestra del terminale sulla tua macchina.

  2. Clona il repository cloud-build-notifiers e vai al suo interno:

      git clone https://github.com/GoogleCloudPlatform/cloud-build-notifiers.git && cd cloud-build-notifiers
    
  3. Aggiungi una directory per il tuo notificatore e vai al suo interno, dove DIRECTORY_NAME è il nome della directory:

      mkdir DIRECTORY_NAME && cd DIRECTORY_NAME
    
  4. Inizializza i moduli Go nella nuova directory, dove DIRECTORY_NAME è il nome della nuova directory:

      go mod init github.com/GoogleCloudPlatform/cloud-build-notifiers/DIRECTORY_NAME
    

    Ora dovresti vedere un file go.mod nella directory.

  5. Aggiungi la seguente riga al file go.mod per assicurarti di utilizzare l'ultima versione dei notificatori:

     replace github.com/GoogleCloudPlatform/cloud-build-notifiers/lib/notifiers => ../
    

Le dipendenze sono ora configurate e puoi creare il tuo notificatore.

Creazione di un notificatore personalizzato

cloud-build-notifiers contiene una directory lib/notifiers. Nella directory lib/notifiers vedrai un file denominato notifier.go. Questo file contiene il framework che puoi utilizzare per creare il tuo notificatore.

Dovrai definire due metodi per creare un notificatore nel file principale.

  1. Nella nuova directory, crea un file denominato main.go.

  2. In main.go, importa il framework della libreria dei notificatori e qualsiasi altra dipendenza:

    package main
    
    import (
    	"context"
    	"fmt"
    
    	cbpb "cloud.google.com/go/cloudbuild/apiv1/v2/cloudbuildpb"
    	"github.com/GoogleCloudPlatform/cloud-build-notifiers/lib/notifiers"
    	log "github.com/golang/glog"
    	"google.golang.org/protobuf/encoding/prototext"
    )
    
  3. Definisci un metodo principale per il notificatore. In questo esempio, logger è il nome del notificatore:

    func main() {
    	if err := notifiers.Main(new(logger)); err != nil {
    		log.Fatalf("fatal error: %v", err)
    	}
    }
    

    Il metodo main utilizza il metodo Main definito nel file notifier.go, che viene utilizzato per configurare i file binari del notificatore.

  4. Definisci una struct per il notificatore, in cui definirai le variabili per l'interfaccia. In questo esempio, logger è il nome del notificatore:

    type logger struct {
    	filter notifiers.EventFilter
    }
    
  5. Aggiungi la funzionalità del notificatore. L'interfaccia del notificatore è definita da due metodi:

    • SetUp: il metodo SetUp accetta una configurazione, recupera i secret ed estrae i filtri specificati dalla configurazione e li archivia come predicato Common Expression Language che può essere utilizzato per inviare notifiche. Per saperne di più su CEL, consulta il cel-spec repository.
    • SendNotification: il metodo SendNotification viene utilizzato per inviare notifiche al canale o al servizio selezionato.

      La definizione del notificatore è disponibile in notifier.go e nella documentazione di Go.

      Nell'esempio seguente, l'interfaccia del notificatore viene definita utilizzando i metodi SetUp e SendNotification per stampare i log di build, con logger come nome del notificatore:

      func (h *logger) SetUp(_ context.Context, cfg *notifiers.Config, _ notifiers.SecretGetter, _ notifiers.BindingResolver) error {
      	prd, err := notifiers.MakeCELPredicate(cfg.Spec.Notification.Filter)
      	if err != nil {
      		return fmt.Errorf("failed to create CELPredicate: %w", err)
      	}
      	h.filter = prd
      	return nil
      }
      
      func (h *logger) SendNotification(ctx context.Context, build *cbpb.Build) error {
      	// Include custom functionality here.
      	// This example logs the build.
      	if h.filter.Apply(ctx, build) {
      		log.V(1).Infof("printing build\n%s", prototext.Format(build))
      	} else {
      		log.V(1).Infof("build (%q, %q) did NOT match CEL filter", build.ProjectId, build.Id)
      	}
      
      	return nil
      }
      

      Il file main.go finale dovrebbe essere simile al seguente. In questo esempio, logger viene utilizzato come nome del notificatore.

      package main
      
      import (
      	"context"
      	"fmt"
      
      	cbpb "cloud.google.com/go/cloudbuild/apiv1/v2/cloudbuildpb"
      	"github.com/GoogleCloudPlatform/cloud-build-notifiers/lib/notifiers"
      	log "github.com/golang/glog"
      	"google.golang.org/protobuf/encoding/prototext"
      )
      
      
      func main() {
      	if err := notifiers.Main(new(logger)); err != nil {
      		log.Fatalf("fatal error: %v", err)
      	}
      }
      
      
      type logger struct {
      	filter notifiers.EventFilter
      }
      
      
      func (h *logger) SetUp(_ context.Context, cfg *notifiers.Config, _ notifiers.SecretGetter, _ notifiers.BindingResolver) error {
      	prd, err := notifiers.MakeCELPredicate(cfg.Spec.Notification.Filter)
      	if err != nil {
      		return fmt.Errorf("failed to create CELPredicate: %w", err)
      	}
      	h.filter = prd
      	return nil
      }
      
      func (h *logger) SendNotification(ctx context.Context, build *cbpb.Build) error {
      	// Include custom functionality here.
      	// This example logs the build.
      	if h.filter.Apply(ctx, build) {
      		log.V(1).Infof("printing build\n%s", prototext.Format(build))
      	} else {
      		log.V(1).Infof("build (%q, %q) did NOT match CEL filter", build.ProjectId, build.Id)
      	}
      
      	return nil
      }
      

    Quindi, configura il notificatore.

Configurare le notifiche

  1. Scrivi un file di configurazione del notificatore per configurare il notificatore e filtrare gli eventi di build:

    Nel seguente file di configurazione del notificatore di esempio, il campo filter utilizza CEL con la variabile disponibile, build, per filtrare gli eventi di build con lo stato SUCCESS:

    apiVersion: cloud-build-notifiers/v1
    kind: YourNotifier
    metadata:
      name: logging-sample
    spec:
      notification:
        filter: build.status == Build.Status.SUCCESS

    Dove:

    • logging-sample è il nome del notificatore.

    Per altri campi in base ai quali puoi filtrare, consulta la risorsa Build. Per altri esempi di filtro, consulta Utilizzo di CEL per filtrare gli eventi di build.

  2. Carica il file di configurazione del notificatore in un bucket Cloud Storage:

    1. Se non hai un bucket Cloud Storage, esegui il seguente comando per creare un bucket, dove BUCKET_NAME è il nome che vuoi assegnare al bucket, soggetto a requisiti di denominazione.

      gcloud storage buckets create gs://BUCKET_NAME/
      
    2. Carica il file di configurazione del notificatore nel bucket:

      gcloud storage cp CONFIG_FILE_NAME gs://BUCKET_NAME/CONFIG_FILE_NAME
      

      Dove:

      • BUCKET_NAME è il nome del bucket.
      • CONFIG_FILE_NAME è il nome del file di configurazione.
  3. Crea ed esegui il deployment del notificatore:

    1. Crea un Dockerfile per logging-sample:

      
      FROM golang AS build-env
      COPY . /go-src/
      WORKDIR /go-src/
      RUN go build -o /go-app .
      
      # From the Cloud Run docs:
      # https://cloud.google.com/run/docs/tutorials/pubsub#looking_at_the_code
      # Use the official Debian slim image for a lean production container.
      # https://hub.docker.com/_/debian
      # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds
      FROM debian:buster-slim
      # Modify sources.list to point to the Debian archive
      RUN sed -i 's|deb.debian.org|archive.debian.org|g' /etc/apt/sources.list && \
          sed -i 's|security.debian.org|archive.debian.org/debian-security|g' /etc/apt/sources.list && \
          sed -i '/buster-updates/d' /etc/apt/sources.list && \
          echo "deb http://archive.debian.org/debian buster-updates main contrib non-free" >> /etc/apt/sources.list && \
          set -x && \
          apt-get update --allow-releaseinfo-change && \
          DEBIAN_FRONTEND=noninteractive apt-get install -y ca-certificates && \
          rm -rf /var/lib/apt/lists/*
      
      
      FROM gcr.io/distroless/base
      COPY --from=build-env /go-app /
      ENTRYPOINT ["/go-app", "--v=1", "--alsologtostderr"]
      
    2. Crea ed esegui il deployment del notificatore utilizzando il seguente file cloudbuild.yaml.

      steps:
      - # Build the binary and put it into the builder image.
        name: gcr.io/cloud-builders/docker
        args: ['build', '--tag=gcr.io/$PROJECT_ID/logging-sample', '.']
      
      - # Push the container image to Container Registry
        name: gcr.io/cloud-builders/docker
        args: ['push', 'gcr.io/$PROJECT_ID/logging-sample']
      
      - # Deploy to Cloud Run
        name: google/cloud-sdk
        args: 
          - gcloud
          - run
          - deploy
          - logging-sample-notifier
          - --platform=managed
          - --region=us-central1
          - --image=gcr.io/$PROJECT_ID/logging-sample
          - --no-allow-unauthenticated
          - --update-env-vars=CONFIG_PATH=${_CONFIG_PATH}
      
      # Push the image with tags.
      images:
      - gcr.io/$PROJECT_ID/logging-sample

      Dove:

      • _CONFIG_PATH è il percorso della configurazione del notificatore, ad esempio gs://BUCKET_NAME/CONFIG_FILE_NAME.yaml.

    Per eseguire cloudbuild.yaml, trasmetti il percorso del notificatore come variabile di sostituzione.

     gcloud builds submit .  --substitutions=_CONFIG_PATH=gs://BUCKET_NAME/CONFIG_FILE_NAME
    
  4. Concedi le autorizzazioni Pub/Sub per creare token di autenticazione nel progetto:

     gcloud projects add-iam-policy-binding PROJECT_ID \
       --member=serviceAccount:service-PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com \
       --role=roles/iam.serviceAccountTokenCreator
    

    Dove:

    • PROJECT_ID è l'ID del tuo Google Cloud progetto.
    • PROJECT_NUMBER è il numero del tuo progetto Google Cloud .
  5. Crea un account di servizio per rappresentare l'identità della sottoscrizione Pub/Sub:

    gcloud iam service-accounts create cloud-run-pubsub-invoker \
      --display-name "Cloud Run Pub/Sub Invoker"
    

    Puoi utilizzare cloud-run-pubsub-invoker o un nome univoco all'interno del tuo progetto Google Cloud .

  6. Concedi al account di servizio cloud-run-pubsub-invoker l'autorizzazione Invoker di Cloud Run:

    gcloud run services add-iam-policy-binding SERVICE_NAME \
       --member=serviceAccount:cloud-run-pubsub-invoker@PROJECT_ID.iam.gserviceaccount.com \
       --role=roles/run.invoker
    

    Dove:

    • SERVICE_NAME è il nome del servizio Cloud Run su cui stai eseguendo il deployment dell'immagine.
    • PROJECT_ID è l'ID del tuo Google Cloud progetto.
  7. Crea l'argomento cloud-builds per ricevere i messaggi di aggiornamento della build per il notificatore:

    gcloud pubsub topics create cloud-builds
    

    Puoi anche definire un nome di argomento personalizzato nel file di configurazione della build in modo che i messaggi vengano inviati all'argomento personalizzato. In questo caso, devi creare un argomento con lo stesso nome di argomento personalizzato:

    gcloud pubsub topics create topic-name
    

    Per saperne di più, consulta Argomenti Pub/Sub per le notifiche di build.

  8. Crea un sottoscrittore push Pub/Sub per il notificatore:

     gcloud pubsub subscriptions create subscriber-id \
       --topic=cloud-builds \
       --push-endpoint=service-url \
       --push-auth-service-account=cloud-run-pubsub-invoker@project-id.iam.gserviceaccount.com
    

    Dove:

    • subscriber-id è il nome che vuoi assegnare alla sottoscrizione.
    • service-url è l'URL generato da Cloud Run per il nuovo servizio.
    • project-id è l'ID del tuo Google Cloud progetto.

Le notifiche per il tuo progetto Cloud Build sono ora configurate. La prossima volta che richiami una build, riceverai una notifica nel tuo canale se la build corrisponde al filtro che hai configurato.

Notifiche di test

Per testare le notifiche per l'esempio utilizzato in questa guida, puoi richiamare una build eseguendo il comando gcloud builds submit.

Nell'esempio seguente, specifichiamo success.yaml come percorso di configurazione. L'esecuzione di questo comando dovrebbe generare una build minima riuscita. Dovresti anche essere in grado di visualizzare un output dei log di build.

 gcloud builds submit --no-source --config=success.yaml

Dove success.yaml è:

 steps:
 - name: busybox
   args: ["true"]

Nell'esempio seguente, specifichiamo failure.yaml come percorso di configurazione. L'esecuzione di questo comando dovrebbe generare una build non riuscita. Anziché visualizzare un output dei log di build, vedrai un output che ti informa che non è stata trovata alcuna corrispondenza per i filtri CEL specificati nell'origine.

gcloud builds submit --no-source --config=failure.yaml

Dove failure.yaml è:

 steps:
 - name: busybox
   args: ["false"]

Se hai creato un notificatore configurato per eseguire un'altra attività diversa dalla registrazione dell'output nei log del servizio Cloud Run, puoi anche eseguire il comando gcloud builds submit per testare le notifiche. Per esaminare gli errori associati alla build, controlla i log di Cloud Run per il tuo servizio. Per saperne di più, consulta Visualizzazione dei log in Cloud Run.

Passaggi successivi