Creazione di un notifier personalizzato

Mantieni tutto organizzato con le raccolte Salva e classifica i contenuti in base alle tue preferenze.

Cloud Build può inviarti notifiche sugli aggiornamenti dello stato della build inviandoti notifiche ai canali desiderati. Oltre ai rilevatori gestiti da Cloud Build, come Slack o SMTP, puoi anche utilizzare la libreria fornita nel repository cloud-build-notifiers per creare la tua notifica.

In questa pagina viene spiegato come creare una notifica personalizzata.

Prima di iniziare

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

    Abilita le API

  • Installa il linguaggio di programmazione Go.

  • Installa Google Cloud CLI.

Configurazione in corso…

  1. Apri una finestra del terminale sulla macchina.

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

      git clone https://github.com/GoogleCloudPlatform/cloud-build-notifiers.git && cd cloud-build-notifiers
    
  3. Aggiungi una directory per il tuo notificatore ed esplorala, 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
    

    A questo punto, dovresti vedere un file go.mod nella directory.

  5. Aggiungi la seguente riga al file go.mod per assicurarti di utilizzare la versione più recente dei notificatori:

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

Le dipendenze sono ora configurate e puoi creare il tuo notificante personalizzato.

Creazione di un notifier 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.

Devi definire due metodi per creare una notifica 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 "google.golang.org/genproto/googleapis/devtools/cloudbuild/v1"
            log "github.com/golang/glog"
            "github.com/GoogleCloudPlatform/cloud-build-notifiers/lib/notifiers"
            "github.com/golang/protobuf/proto"
    )
  3. Definisci un metodo principale per il notificante. 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 programmi binari del notificatore.

  4. Definisci una struttura per il notificante, in cui definirai le variabili per la tua interfaccia. In questo esempio, logger è il nome della notifica. Ad es.

    type logger struct {
        filter notifiers.EventFilter
    }

Successivamente, aggiungerai la funzionalità di notifica. L'interfaccia dei rilevatori è definita da due metodi:

  • SetUp: il metodo SetUp accetta una configurazione, recupera i secret e estrae i filtri specificati dalla configurazione e li archivia come predicato di un linguaggio di espressione comune che può essere utilizzato per inviare notifiche. Per scoprire di più su CEL, consulta il repository cel-spec.
  • SendNotification: il metodo SendNotification viene utilizzato per inviare notifiche al canale o servizio desiderato.

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

    Nell'esempio che segue, l'interfaccia del notificatore viene definita utilizzando il metodo SetUp e il metodo 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", proto.MarshalTextString(build))
        } else {
            log.V(1).Infof("build (%q, %q) did NOT match CEL filter", build.ProjectId, build.Id)
        }
    
        return nil
    }

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

    package main
    
    import (
            "context"
            "fmt"
    
            cbpb "google.golang.org/genproto/googleapis/devtools/cloudbuild/v1"
            log "github.com/golang/glog"
            "github.com/GoogleCloudPlatform/cloud-build-notifiers/lib/notifiers"
            "github.com/golang/protobuf/proto"
    )
    
    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", proto.MarshalTextString(build))
        } else {
            log.V(1).Infof("build (%q, %q) did NOT match CEL filter", build.ProjectId, build.Id)
        }
    
        return nil
    }

    Ora che hai definito il notificante, puoi seguire i passaggi riportati di seguito per configurarlo.

Configurazione delle notifiche

  1. Scrivi un file di configurazione del notificatore per configurare il filtro e il filtro degli 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 uno 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 della notifica.

    Per ulteriori campi in base ai quali puoi applicare un filtro, consulta la risorsa Build. Per altri esempi di filtro, consulta la pagina relativa all'utilizzo di CEL per filtrare gli eventi della build.

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

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

      gsutil mb gs://BUCKET_NAME/
      
    2. Carica il file di configurazione del notificatore nel bucket:

      gsutil cp CONFIG_FILE_NAME gs://BUCKET_NAME/CONFIG_FILE_NAME
      

      Dove:

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

    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
      RUN set -x && apt-get update && 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, passa 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 i token di autenticazione nel tuo 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 progetto Cloud.
    • PROJECT_NUMBER è il tuo numero di progetto Cloud.
  5. Crea un account di servizio che rappresenti l'identità dell'abbonamento 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 utilizzare un nome univoco all'interno del progetto Google Cloud.

  6. Concedi all'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 in cui esegui il deployment dell'immagine.
    • PROJECT_ID è l'ID del tuo progetto Cloud.
  7. Dopo aver abilitato l'API Pub/Sub, dovresti vedere creato automaticamente l'argomento cloud-builds nella pagina Topics Pub/Sub. Se non vedi l'argomento cloud-builds, esegui il comando seguente per creare manualmente l'argomento per ricevere i messaggi di aggiornamento della build per il notificante:

    gcloud pubsub topics create cloud-builds
    
  8. Crea un sottoscrittore push Pub/Sub per il notificante:

     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 dare all'abbonamento.
    • SERVICE_URL è l'URL generato da Cloud Run per il tuo nuovo servizio.
    • PROJECT_ID è l'ID del tuo progetto Cloud.

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 quest'ultima corrisponde al filtro configurato.

Notifiche di test

Per testare la funzionalità di notifica 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 comportare una build minima con esito positivo. Dovresti anche essere in grado di visualizzare un output dei log di build.

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

Dove si trova 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. Invece di visualizzare un output dei log di build, vedrai un output che ti informa che non esiste una corrispondenza per i filtri CEL specificati nell'origine.

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

Dove si trova failure.yaml:

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

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

Passaggi successivi