Criar o seu próprio notificador

O Cloud Build pode enviar-lhe notificações para canais selecionados sobre atualizações ao estado da compilação. Além dos notificadores mantidos pelo Cloud Build, como o Slack ou o SMTP, também pode usar a biblioteca fornecida no repositório cloud-build-notifiers para criar o seu próprio notificador.

Esta página explica como pode criar o seu próprio notificador.

Antes de começar

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

    Enable the APIs

  • Instale a linguagem de programação Go.

  • Instale a CLI do Google Cloud.

A configurar o

  1. Abra uma janela de terminal na máquina.

  2. Clone e navegue para o repositório cloud-build-notifiers:

      git clone https://github.com/GoogleCloudPlatform/cloud-build-notifiers.git && cd cloud-build-notifiers
    
  3. Adicione um diretório para o seu próprio notificador e navegue até ele, onde DIRECTORY_NAME é o nome do seu diretório:

      mkdir DIRECTORY_NAME && cd DIRECTORY_NAME
    
  4. Inicialize os módulos Go no novo diretório, em que DIRECTORY_NAME é o nome do novo diretório:

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

    Agora, deve ver um ficheiro go.mod no seu diretório.

  5. Adicione a seguinte linha ao ficheiro go.mod para garantir que está a usar a versão mais recente dos notificadores:

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

As suas dependências estão agora configuradas e tem tudo pronto para criar o seu próprio notificador.

Criar o seu próprio notificador

O cloud-build-notifiers contém um diretório lib/notifiers. No diretório lib/notifiers, é apresentado um ficheiro denominado notifier.go. Este ficheiro contém a estrutura que pode usar para criar o seu próprio notificador.

Tem de definir dois métodos para criar um notificador no ficheiro principal.

  1. No novo diretório, crie um ficheiro denominado main.go.

  2. Em main.go, importe a framework da biblioteca de notificadores e quaisquer outras dependências:

    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. Defina um método principal para o seu notificador. Neste exemplo, logger é o nome do notificador:

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

    O método main usa o método Main definido no ficheiro notifier.go, que é usado para configurar ficheiros binários de notificação.

  4. Defina uma struct para o seu notificador, onde vai definir as variáveis para a sua interface. Neste exemplo, logger é o nome do notificador:

    type logger struct {
    	filter notifiers.EventFilter
    }
    
  5. Adicione a funcionalidade de notificação. A interface do notificador é definida por dois métodos:

    • SetUp: o método SetUp aceita uma configuração, obtém segredos e extrai filtros especificados da configuração e armazena-os como um predicado da linguagem de expressão comum que pode ser usado para enviar notificações. Para saber mais sobre a CEL, consulte o cel-specrepositório.
    • SendNotification: O método SendNotification é o que é usado para enviar notificações para o canal ou o serviço selecionado.

      A definição do notificador está disponível em notifier.go e na documentação do Go.

      No exemplo seguinte, a interface do notificador é definida através do método SetUp e SendNotification para imprimir registos de compilação, com logger como o nome do 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
      }
      

      O ficheiro main.go final deve ser semelhante ao seguinte ficheiro. Neste exemplo, logger é usado como o nome do 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
      }
      

    Em seguida, configure o notificador.

Configure as notificações

  1. Escreva um ficheiro de configuração do notificador para configurar o notificador e filtrar eventos de compilação:

    No ficheiro de configuração do notificador do exemplo seguinte, o campo filter usa CEL com a variável disponível, build, para filtrar eventos de compilação com um estado SUCCESS:

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

    Onde:

    • logging-sample é o nome do remetente da notificação.

    Para ver campos adicionais pelos quais pode filtrar, consulte o recurso Build. Para ver exemplos de filtragem adicionais, consulte o artigo Usar o IEC para filtrar eventos de compilação.

  2. Carregue o ficheiro de configuração do notificador para um contentor do Cloud Storage:

    1. Se não tiver um contentor do Cloud Storage, execute o seguinte comando para criar um contentor, em que BUCKET_NAME é o nome que quer dar ao contentor, sujeito aos requisitos de nomenclatura.

      gcloud storage buckets create gs://BUCKET_NAME/
      
    2. Carregue o ficheiro de configuração do notificador para o seu contentor:

      gcloud storage cp CONFIG_FILE_NAME gs://BUCKET_NAME/CONFIG_FILE_NAME
      

      Onde:

      • BUCKET_NAME é o nome do seu contentor.
      • CONFIG_FILE_NAME é o nome do ficheiro de configuração.
  3. Crie e implemente o seu notificador:

    1. Crie um ficheiro Docker para o 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. Crie e implemente o notificador com o seguinte ficheiro 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

      Onde:

      • _CONFIG_PATH é o caminho para a configuração do seu notificador, como gs://BUCKET_NAME/CONFIG_FILE_NAME.yaml.

    Para executar o comando cloudbuild.yaml, transmita o caminho do notificador como uma variável de substituição.

     gcloud builds submit .  --substitutions=_CONFIG_PATH=gs://BUCKET_NAME/CONFIG_FILE_NAME
    
  4. Conceda autorizações do Pub/Sub para criar tokens de autenticação no seu projeto:

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

    Onde:

    • PROJECT_ID é o ID do seu Google Cloud projeto.
    • PROJECT_NUMBER é o número do seu Google Cloud projeto.
  5. Crie uma conta de serviço para representar a identidade da sua subscrição do Pub/Sub:

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

    Pode usar cloud-run-pubsub-invoker ou usar um nome único no seu projeto Google Cloud .

  6. Conceda à conta de serviço cloud-run-pubsub-invoker a autorização Invoker do 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
    

    Onde:

    • SERVICE_NAME é o nome do serviço do Cloud Run para o qual está a implementar a imagem.
    • PROJECT_ID é o ID do seu Google Cloud projeto.
  7. Crie o tópico cloud-builds para receber mensagens de atualização de compilação para o seu notificador:

    gcloud pubsub topics create cloud-builds
    

    Também pode definir um nome de tópico personalizado no ficheiro de configuração de compilação para que as mensagens sejam enviadas para o tópico personalizado. Neste caso, criaria um tópico com o mesmo nome de tópico personalizado:

    gcloud pubsub topics create topic-name
    

    Para mais informações, consulte o artigo Tópicos do Pub/Sub para notificações de compilação.

  8. Crie um subscritor de envio do Pub/Sub para o seu 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
    

    Onde:

    • subscriber-id é o nome que quer atribuir à sua subscrição.
    • service-url é o URL gerado pelo Cloud Run para o seu novo serviço.
    • project-id é o ID do seu Google Cloud projeto.

As notificações para o seu projeto do Cloud Build estão agora configuradas. Da próxima vez que invocar uma compilação, recebe uma notificação no seu canal se a compilação corresponder ao filtro que configurou.

Notificações de teste

Para testar as notificações do exemplo usado neste guia, pode invocar uma compilação executando o comando gcloud builds submit.

No exemplo seguinte, especificamos success.yaml como o caminho de configuração. A execução deste comando deve resultar numa compilação bem-sucedida mínima. Também deve conseguir ver um resultado dos registos de compilação.

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

Onde success.yaml é:

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

No exemplo seguinte, especificamos failure.yaml como o caminho de configuração. A execução deste comando deve resultar numa compilação com falhas. Em vez de ver um resultado dos registos de compilação, vê um resultado a informar que não houve correspondência para os filtros CEL especificados na sua origem.

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

Onde failure.yaml é:

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

Se criou um notificador configurado para realizar outra tarefa que não seja registar a saída nos registos de serviço do Cloud Run, também pode executar o comando gcloud builds submit para testar as suas notificações. Para examinar os erros associados à sua compilação, verifique os registos do Cloud Run para o seu serviço. Para saber mais, consulte o artigo Ver registos no Cloud Run.

O que se segue?