Crear tu propio notificador

Cloud Build puede enviarte notificaciones a los canales que elijas para informarte de las actualizaciones del estado de tus compilaciones. Además de los notificadores que mantiene Cloud Build, como Slack o SMTP, también puedes usar la biblioteca proporcionada en el repositorio cloud-build-notifiers para crear tu propio notificador.

En esta página se explica cómo puedes crear tu propio notificador.

Antes de empezar

  • Enable the Cloud Build, Cloud Run, Pub/Sub, and Secret Manager APIs.

    Enable the APIs

  • Instala el lenguaje de programación Go.

  • Instala Google Cloud CLI.

Configurando

  1. Abre una ventana de terminal en tu máquina.

  2. Clona el repositorio cloud-build-notifiers y ve a él:

      git clone https://github.com/GoogleCloudPlatform/cloud-build-notifiers.git && cd cloud-build-notifiers
    
  3. Añade un directorio para tu propio notificador y desplázate hasta él. DIRECTORY_NAME es el nombre de tu directorio:

      mkdir DIRECTORY_NAME && cd DIRECTORY_NAME
    
  4. Inicializa los módulos de Go en el nuevo directorio, donde DIRECTORY_NAME es el nombre del nuevo directorio:

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

    Ahora deberías ver un archivo go.mod en tu directorio.

  5. Añade la siguiente línea a tu archivo go.mod para asegurarte de que usas la versión más reciente de los notifiers:

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

Ahora tus dependencias están configuradas y puedes crear tu propio notificador.

Crear tu propio notificador

cloud-build-notifiers contiene un directorio lib/notifiers. En el directorio lib/notifiers, verás un archivo llamado notifier.go. Este archivo contiene el framework que puedes usar para crear tu propio notificador.

Deberás definir dos métodos para crear un notificador en tu archivo principal.

  1. En el nuevo directorio, crea un archivo llamado main.go.

  2. En main.go, importa el framework de la biblioteca de notificaciones y cualquier otra dependencia:

    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. Define un método principal para tu notificador. En este ejemplo, logger es el nombre del notificador:

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

    El método main usa el método Main definido en el archivo notifier.go, que se usa para configurar los archivos binarios del notificador.

  4. Define una estructura para tu notificador, donde definirás las variables de tu interfaz. En este ejemplo, logger es el nombre del notificador:

    type logger struct {
    	filter notifiers.EventFilter
    }
    
  5. Añade la función de notificador. La interfaz de notificador se define mediante dos métodos:

    • SetUp: el método SetUp acepta una configuración, obtiene secretos y extrae filtros específicos de la configuración, que almacena como un predicado de Common Expression Language que se puede usar para enviar notificaciones. Para obtener más información sobre CEL, consulta el repositorio cel-spec.
    • SendNotification: el método SendNotification es el que se usa para enviar notificaciones al canal o servicio que hayas seleccionado.

      Puedes consultar la definición del notificador en notifier.go y en la documentación de Go.

      En el siguiente ejemplo, la interfaz del notificador se define mediante SetUp y el método SendNotification para imprimir los registros de compilación, con logger como nombre del notificador:

      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
      }
      

      El archivo main.go final debería tener un aspecto similar al siguiente. En este ejemplo, se usa logger como nombre del notificador.

      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
      }
      

    A continuación, configura tu notificador.

Configurar notificaciones

  1. Escribe un archivo de configuración de notificador para configurar tu notificador y filtrar los eventos de compilación:

    En el siguiente archivo de configuración de notificador de ejemplo, el campo filter usa CEL con la variable disponible build para filtrar eventos de compilación con el estado SUCCESS:

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

    Donde:

    • logging-sample es el nombre del notificador.

    Para ver los campos adicionales por los que puedes filtrar, consulta el recurso Build. Para ver más ejemplos de filtrado, consulta Usar CEL para filtrar eventos de compilaciones.

  2. Sube el archivo de configuración del notificador a un depósito de Cloud Storage:

    1. Si no tienes ningún segmento de Cloud Storage, ejecuta el siguiente comando para crear uno. Sustituye BUCKET_NAME por el nombre que quieras darle al segmento, que debe cumplir los requisitos de nomenclatura.

      gcloud storage buckets create gs://BUCKET_NAME/
      
    2. Sube el archivo de configuración del notificador a tu segmento:

      gcloud storage cp CONFIG_FILE_NAME gs://BUCKET_NAME/CONFIG_FILE_NAME
      

      Donde:

      • BUCKET_NAME es el nombre de tu segmento.
      • CONFIG_FILE_NAME es el nombre del archivo de configuración.
  3. Crea y despliega tu notificador:

    1. Crea un Dockerfile para 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 y despliega el notificador con el siguiente archivo 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

      Donde:

      • _CONFIG_PATH es la ruta a la configuración de tu notificador, como gs://BUCKET_NAME/CONFIG_FILE_NAME.yaml.

    Para ejecutar cloudbuild.yaml, introduce la ruta del notificador como variable de sustitución.

     gcloud builds submit .  --substitutions=_CONFIG_PATH=gs://BUCKET_NAME/CONFIG_FILE_NAME
    
    .
  4. Concede permisos de Pub/Sub para crear tokens de autenticación en tu proyecto:

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

    Donde:

    • PROJECT_ID es el ID de tu Google Cloud proyecto.
    • PROJECT_NUMBER es el número de tu proyecto Google Cloud .
  5. Crea una cuenta de servicio que represente la identidad de tu suscripción de Pub/Sub:

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

    Puedes usar cloud-run-pubsub-invoker o un nombre único en tu proyecto. Google Cloud

  6. Concede a la cuenta de servicio cloud-run-pubsub-invoker el permiso Cloud Run Invoker:

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

    Donde:

    • SERVICE_NAME es el nombre del servicio de Cloud Run en el que vas a desplegar la imagen.
    • PROJECT_ID es el ID de tu Google Cloud proyecto.
  7. Crea el tema cloud-builds para recibir mensajes de actualización de compilación de tu notificador:

    gcloud pubsub topics create cloud-builds
    

    También puedes definir un nombre de tema personalizado en el archivo de configuración de compilación para que los mensajes se envíen al tema personalizado. En este caso, crearías un tema con el mismo nombre de tema personalizado:

    gcloud pubsub topics create topic-name
    

    Para obtener más información, consulta Temas de Pub/Sub para notificaciones de compilación.

  8. Crea un suscriptor de inserción de Pub/Sub para tu notificador:

     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
    

    Donde:

    • subscriber-id es el nombre que quieres dar a tu suscripción.
    • service-url es la URL generada por Cloud Run para tu nuevo servicio.
    • project-id es el ID de tu Google Cloud proyecto.

Las notificaciones de tu proyecto de Cloud Build ya están configuradas. La próxima vez que invoques una compilación, recibirás una notificación en tu canal si la compilación coincide con el filtro que has configurado.

Notificaciones de prueba

Para probar las notificaciones del ejemplo que se usa en esta guía, puedes invocar una compilación ejecutando el comando gcloud builds submit.

En el siguiente ejemplo, especificamos success.yaml como ruta de configuración. Al ejecutar este comando, se debería generar una compilación mínima correcta. También deberías poder ver el resultado de los registros de compilación.

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

Donde success.yaml es:

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

En el siguiente ejemplo, especificamos failure.yaml como ruta de configuración. Al ejecutar este comando, la compilación debería fallar. En lugar de ver el resultado de los registros de compilación, verás un mensaje que te informa de que no se ha encontrado ninguna coincidencia para los filtros de CEL que has especificado en tu fuente.

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

Donde failure.yaml es:

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

Si has creado un notificador configurado para realizar otra tarea que no sea registrar la salida en los registros de servicio de Cloud Run, también puedes ejecutar el comando gcloud builds submit para probar tus notificaciones. Para examinar los errores asociados a tu compilación, consulta los registros de Cloud Run de tu servicio. Para obtener más información, consulta Ver registros en Cloud Run.

Siguientes pasos