Crea tu propio notificador

Cloud Build puede enviarte notificaciones a los canales deseados para notificarte sobre las actualizaciones del estado de la compilación. 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 crear tu propio notificador.

Antes de comenzar

  • Habilita las API de Cloud Build, Cloud Run, Pub/Sub, and Secret Manager.

    Habilita las API

  • Instala el lenguaje de programación Go.

  • Instala Google Cloud CLI.

Establece la configuración

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

  2. Clona y navega al repositorio cloud-build-notifiers:

      git clone https://github.com/GoogleCloudPlatform/cloud-build-notifiers.git && cd cloud-build-notifiers
    
  3. Agrega un directorio para tu propio notificador y navega hasta él, en el que DIRECTORY_NAME es el nombre de tu directorio:

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

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

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

  5. Agrega la siguiente línea a tu archivo go.mod para asegurarte de usar la versión más reciente de los notificadores:

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

Tus dependencias ya están configuradas y estás listo para crear tu propio notificador.

Crea 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 directorio nuevo, crea un archivo llamado main.go.

  2. En main.go, importa el framework de la biblioteca de notificadores 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 el 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 objetos binarios del notificador.

  4. Define una estructura para tu notificador, en la que definirás las variables de la interfaz. En este ejemplo, logger es el nombre del notificador. P. ej.

    type logger struct {
    	filter notifiers.EventFilter
    }
    

A continuación, agregarás la funcionalidad del notificador. La interfaz del notificador se define con dos métodos:

  • SetUp: El método SetUp acepta una configuración, recupera secretos y extrae filtros específicos de la configuración y los 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 deseados.

    La definición del notificador está disponible en notifier.go y en la documentación de Go.

    En el siguiente ejemplo, la interfaz del notificador se define con SetUp y el método SendNotification para imprimir los registros de compilación, con logger como el nombre de tu 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
    }
    

    Tu archivo final main.go debería ser similar al siguiente archivo. 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
    }
    

    Ahora que tienes definido tu notificador, puedes seguir los pasos siguientes para configurar tu notificador.

Configura notificaciones

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

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

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

    Aquí:

    • logging-sample es el nombre del notificador.

    Para ver campos adicionales por los que puedes filtrar, consulta el recurso Compilar. Si deseas ver ejemplos adicionales de filtros, consulta Usa CEL para filtrar eventos de compilación.

  2. Sube tu archivo de configuración de notificador a un bucket de Cloud Storage:

    1. Si no tienes un bucket de Cloud Storage, ejecuta el siguiente comando para crear un bucket, en el que BUCKET_NAME es el nombre que deseas asignar a tu bucket, sujeto a los requisitos de nombres.

      gsutil mb gs://BUCKET_NAME/
      
    2. Sube el archivo de configuración del notificador a tu bucket:

      gsutil cp CONFIG_FILE_NAME gs://BUCKET_NAME/CONFIG_FILE_NAME
      

      Aquí:

      • BUCKET_NAME es el nombre de tu bucket.
      • CONFIG_FILE_NAME es el nombre de tu archivo de configuración.
  3. Compila e implementa 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
      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. Compila e implementa 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

      Aquí:

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

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

     gcloud builds submit .  --substitutions=_CONFIG_PATH=gs://BUCKET_NAME/CONFIG_FILE_NAME
    
  4. Otorga 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
    

    Aquí:

    • PROJECT_ID es el ID de tu proyecto de Google Cloud.
    • PROJECT_NUMBER es el número de proyecto de Google Cloud.
  5. Crea una cuenta de servicio para representar tu identidad de 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 dentro de tu proyecto de Google Cloud.

  6. Otorga el permiso Invoker de Cloud Run a la cuenta de servicio de cloud-run-pubsub-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
    

    Aquí:

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

    gcloud pubsub topics create cloud-builds
    
  8. Crea un suscriptor de envío 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
    

    Aquí:

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

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 configuraste.

Prueba las notificaciones

Para probar la funcionalidad de las notificaciones del ejemplo que se usa en esta guía, puedes invocar una compilación mediante la ejecución del comando gcloud builds submit.

En el siguiente ejemplo, especificamos success.yaml como la ruta de configuración. Ejecutar este comando debería dar como resultado una compilación mínima exitosa. También deberías ver un resultado de los registros de tu compilación.

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

En el ejemplo anterior, success.yaml es:

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

En el siguiente ejemplo, especificamos failure.yaml como la ruta de configuración. Si ejecutas este comando, la compilación fallará. En lugar de ver un resultado de tus registros de compilación, verás un resultado que te informa que no hubo ninguna coincidencia para los filtros de CEL que especificaste en la fuente.

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

En el ejemplo anterior, failure.yaml es:

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

Si creaste un notificador que está configurado para realizar otra tarea que no sea el resultado del registro en los registros del servicio de Cloud Run, también puedes ejecutar el comando gcloud builds submit para probar la funcionalidad de notificación. Para examinar los errores asociados con tu compilación, verifica los registros de Cloud Run de tu servicio. Para obtener más información, consulta Visualiza los registros en Cloud Run.

¿Qué sigue?