Como gerenciar canais de notificação por API

As políticas de alertas normalmente têm uma maneira de informar quando foram acionadas. Essas "maneiras de informar" se chamam canais de notificação. Existem diversos tipos de canal disponíveis. Cada tipo é definido em um descritor do canal de notificação. Um canal de um determinado tipo é uma instância do descritor desse tipo. Entre as políticas de alertas estão referências para os canais de notificação a serem usadas como caminhos de notificação.

Um canal de notificação precisa existir para ser usado em uma política de alertas. Os descritores do canal de notificação são fornecidos, mas você precisa criar os canais para que possam ser usados.

As amostras de código usadas aqui são extraídas do exemplo da API da política de alertas, descrito em Exemplo: backup e restauração.

Descritores de canal

O Stackdriver fornece vários tipos de canal de notificação internos. Cada um desses tipos é descrito em um NotificationChannelDescriptor. Esses descritores têm um campo type, e o valor desse campo funciona como um identificador para ele durante a criação de instâncias desse tipo de canal. Recupere os tipos de canal disponíveis, descritos de maneira mais generalizada em Opções de notificação, com o seguinte comando:

$ gcloud alpha monitoring channel-descriptors list --format='value(type)'
email
hipchat
pagerduty
slack
sms
webhook_basicauth
webhook_tokenauth

Para recuperar todos os descritores de canal em um projeto, use o método notificationChannelDescriptors.list. Os descritores recuperados são somente leitura.

Se estiver procurando um descritor específico e souber o nome dele, use o método notificationChannelDescriptors.get para recuperar apenas esse descritor de canal. O nome de um descritor de canal tem o formato projects/[PROJECT_ID]/notificationChannelDescriptors/[CHANNEL_TYPE]. [CHANNEL_TYPE] precisa ser um dos tipos listados acima. Por exemplo:

projects/a-gcp-project/notificationChannelDescriptors/email

COMANDO GCLOUD

Para listar todos os descritores do canal de notificação em um projeto, use o comando gcloud alpha monitoring channel-descriptors list:

gcloud alpha monitoring channel-descriptors list

Se bem-sucedido, o comando list fornecerá uma listagem de todos os descritores de canal no projeto especificado. Por exemplo, o descritor de canal email é exibido na lista assim:

---
description: A channel that sends notifications via email.
displayName: Email
labels:
- description: An address to send email.
  key: email_address
name: projects/a-gcp-project/notificationChannelDescriptors/email
type: email
---

Para listar um único descritor de canal, use gcloud alpha monitoring channel-descriptors describe, em vez disso, e especifique o nome do descritor de canal. Por exemplo, este comando retorna apenas a listagem acima:

gcloud alpha monitoring channel-descriptors describe projects/a-gcp-project/notificationChannelDescriptors/email

Consulte as referências de gcloud alpha monitoring channel-descriptors list e describe para ver mais informações. O comando describe corresponde ao método notificationChannelDescriptors.get na API.

Canais de notificação

Canal de notificação é uma instância de um dos descritores do canal de notificação abordados em Descritores de canal.

O recurso NotificationChannel aceita cinco operações:

  • criação de novos canais
  • exclusão de canais existentes
  • recuperação de canais específicos
  • recuperação de todos os canais
  • modificação de canais existentes

Existem três outras operações relacionadas ao gerenciamento do campo verificationStatus de um canal:

  • Envio de um código de verificação
  • Geração de um código para copiar o status da verificação de um canal verificado para outros canais idênticos no mesmo projeto ou em um novo
  • Verificação do canal usando o código criado pelas duas operações anteriores

Consulte a referência notificationChannels para ver mais informações sobre eles.

Como criar canais

É possível criar canais de notificação com base em arquivos JSON ou YAML usando o utilitário de linha de comando gcloud e criá-los de maneira programática.

Para criar um canal de notificação, você precisa fornecer valores para os campos no descritor. A maioria desses, como type, é comum em todos os descritores de canais de notificação. Consulte notificationChannelDescriptors.

Cada descritor também tem um conjunto de rótulos, e esse conjunto varia entre os descritores. Para ver o conjunto de rótulos de um descritor específico, recupere o descritor usando o comando gcloud alpha monitoring channel-descriptors describe descrito em Descritores de canal. Por exemplo, a recuperação do descritor de canal email mostra um único rótulo:

labels:
- description: An address to send email.
  key: email_address

A recuperação do descritor de canal webhook_basicauth mostra diversos rótulos:

labels:
- description: The password. The field is obfuscated when the channel is fetched.
  key: password
- description: The URL to which to publish the webhook.
  key: url
- description: The username.
  key: username

Se você criar um novo canal programaticamente ou a partir da linha de comando, o valor do type na especificação precisará corresponder ao campo type no descritor do canal de notificação correspondente. Todas as chaves de rótulo obrigatórias também precisam corresponder àquelas no descritor de canais.

Alguns rótulos correspondem às credenciais usadas na autenticação com o provedor. Durante a criação de um canal, os valores desses rótulos precisam ser recebidos do provedor. O recebimento de uma credencial pode envolver o uso de uma página de geração da chave de API no site do provedor ou a conclusão de um fluxo de login do OAuth com o provedor. As especificidades de como receber essa credencial dependem do provedor específico.

Por exemplo, isto mostra a especificação de um novo canal de notificação email em JSON:

{
  "type": "email",
  "displayName": "test e-mail channel",
  "description": "E-mail channel created by gcloud as a test",
  "labels": {
    "email_address": "user@example.com"
  },
  "enabled": false
}

O valor type (email) e a chave de rótulo única (email_address) correspondem aos campos type e labels.key no descritor de canais correspondente.

Nos exemplos a seguir, veja a criação de canais de notificação.

COMANDO GCLOUD

Para criar um canal de notificação em um projeto, use o comando gcloud alpha monitoring channels create. Para carregar o canal de um arquivo, use a sinalização --channel-content-from-file para especificar o arquivo.

O seguinte exemplo cria um novo canal de e-mail em a-gcp-project com base no arquivo new-email-channel.json:

gcloud alpha monitoring channels create --channel-content-from-file="new-email-channel.json"

Se bem-sucedido, este comando retornará o nome do novo canal. Por exemplo:

Created notification channel [projects/a-gcp-project/notificationChannels/1355376463305411567].

Consulte a referência de gcloud alpha monitoring channels create para ver mais informações.

C#

static void RestorePolicies(string projectId, string filePath)
{
    var policyClient = AlertPolicyServiceClient.Create();
    var channelClient = NotificationChannelServiceClient.Create();
    List<Exception> exceptions = new List<Exception>();
    var backup = JsonConvert.DeserializeObject<BackupRecord>(
        File.ReadAllText(filePath), new ProtoMessageConverter());
    var projectName = new ProjectName(projectId);
    bool isSameProject = projectId == backup.ProjectId;
    // When a channel is recreated, rather than updated, it will get
    // a new name.  We have to update the AlertPolicy with the new
    // name.  Track the names in this map.
    var channelNameMap = new Dictionary<string, string>();
    foreach (NotificationChannel channel in backup.Channels)
    {
        try
        {
            bool updated = false;
            Console.WriteLine("Updating channel.\n{0}",
                channel.DisplayName);
            // This field is immutable and it is illegal to specify a
            // non-default value (UNVERIFIED or VERIFIED) in the
            // Create() or Update() operations.
            channel.VerificationStatus = NotificationChannel.Types
                .VerificationStatus.Unspecified;
            if (isSameProject)
                try
                {
                    channelClient.UpdateNotificationChannel(
                        null, channel);
                    updated = true;
                }
                catch (Grpc.Core.RpcException e)
                when (e.Status.StatusCode == StatusCode.NotFound)
                { }
            if (!updated)
            {
                // The channel no longer exists.  Recreate it.
                string oldName = channel.Name;
                channel.Name = null;
                var response = channelClient.CreateNotificationChannel(
                    projectName, channel);
                channelNameMap.Add(oldName, response.Name);
            }
        }
        catch (Exception e)
        {
            // If one failed, continue trying to update the others.
            exceptions.Add(e);
        }
    }
    foreach (AlertPolicy policy in backup.Policies)
    {
    }
    if (exceptions.Count > 0)
    {
        throw new AggregateException(exceptions);
    }
}

Node.js

// Imports the Google Cloud client library
const monitoring = require('@google-cloud/monitoring');

// Creates clients
const alertClient = new monitoring.AlertPolicyServiceClient();
const notificationClient = new monitoring.NotificationChannelServiceClient();

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const alertPolicyId = '123456789012314';
// const channelIds = [
//   'channel-1',
//   'channel-2',
//   'channel-3',
// ];

const notificationChannels = channelIds.map(id =>
  notificationClient.notificationChannelPath(projectId, id)
);

for (const channel of notificationChannels) {
  const updateChannelRequest = {
    updateMask: {paths: ['enabled']},
    notificationChannel: {
      name: channel,
      enabled: {value: true},
    },
  };
  try {
    await notificationClient.updateNotificationChannel(updateChannelRequest);
  } catch (err) {
    const createChannelRequest = {
      notificationChannel: {
        name: channel,
        notificationChannel: {type: 'email'},
      },
    };
    const newChannel = await notificationClient.createNotificationChannel(
      createChannelRequest
    );
    notificationChannels.push(newChannel);
  }
}

const updateAlertPolicyRequest = {
  updateMask: {paths: ['notification_channels']},
  alertPolicy: {
    name: alertClient.alertPolicyPath(projectId, alertPolicyId),
    notificationChannels: notificationChannels,
  },
};
const [alertPolicy] = await alertClient.updateAlertPolicy(
  updateAlertPolicyRequest
);
console.log(`Updated ${alertPolicy.name}.`);

Go

// restorePolicies updates the project with the alert policies and
// notification channels in r.
func restorePolicies(w io.Writer, projectID string, r io.Reader) error {
	b := backup{}
	if err := json.NewDecoder(r).Decode(&b); err != nil {
		return err
	}
	sameProject := projectID == b.ProjectID

	ctx := context.Background()

	alertClient, err := monitoring.NewAlertPolicyClient(ctx)
	if err != nil {
		return err
	}
	channelClient, err := monitoring.NewNotificationChannelClient(ctx)
	if err != nil {
		return err
	}

	// When a channel is recreated, rather than updated, it will get
	// a new name.  We have to update the AlertPolicy with the new
	// name.  channelNames keeps track of the new names.
	channelNames := make(map[string]string)
	for _, c := range b.Channels {
		fmt.Fprintf(w, "Updating channel %q\n", c.GetDisplayName())
		c.VerificationStatus = monitoringpb.NotificationChannel_VERIFICATION_STATUS_UNSPECIFIED
		updated := false
		if sameProject {
			req := &monitoringpb.UpdateNotificationChannelRequest{
				NotificationChannel: c.NotificationChannel,
			}
			_, err := channelClient.UpdateNotificationChannel(ctx, req)
			if err == nil {
				updated = true
			}
		}
		if !updated {
			req := &monitoringpb.CreateNotificationChannelRequest{
				Name:                "projects/" + projectID,
				NotificationChannel: c.NotificationChannel,
			}
			oldName := c.GetName()
			c.Name = ""
			newC, err := channelClient.CreateNotificationChannel(ctx, req)
			if err != nil {
				return err
			}
			channelNames[oldName] = newC.GetName()
		}
	}

	for _, policy := range b.AlertPolicies {
		fmt.Fprintf(w, "Updating alert %q\n", policy.GetDisplayName())
		policy.CreationRecord = nil
		policy.MutationRecord = nil
		for i, aChannel := range policy.GetNotificationChannels() {
			if c, ok := channelNames[aChannel]; ok {
				policy.NotificationChannels[i] = c
			}
		}
		updated := false
		if sameProject {
			req := &monitoringpb.UpdateAlertPolicyRequest{
				AlertPolicy: policy.AlertPolicy,
			}
			_, err := alertClient.UpdateAlertPolicy(ctx, req)
			if err == nil {
				updated = true
			}
		}
		if !updated {
			req := &monitoringpb.CreateAlertPolicyRequest{
				Name:        "projects/" + projectID,
				AlertPolicy: policy.AlertPolicy,
			}
			if _, err = alertClient.CreateAlertPolicy(ctx, req); err != nil {
				log.Fatal(err)
			}
		}
	}
	fmt.Fprintf(w, "Successfully restored alerts.")
	return nil
}

Java

private static Map<String, String> restoreNotificationChannels(
    String projectId,
    List<NotificationChannel> channels,
    boolean isSameProject) throws IOException {
  Map<String, String> newChannelNames = Maps.newHashMap();
  try (NotificationChannelServiceClient client = NotificationChannelServiceClient.create()) {
    for (NotificationChannel channel : channels) {
      // Update channel name if project ID is different.
      boolean channelUpdated = false;
      if (isSameProject) {
        try {
          NotificationChannel updatedChannel =
              client.updateNotificationChannel(NOTIFICATION_CHANNEL_UPDATE_MASK, channel);
          newChannelNames.put(channel.getName(), updatedChannel.getName());
          channelUpdated = true;
        } catch (Exception e) {
          channelUpdated = false;
        }
      }
      if (!channelUpdated) {
        NotificationChannel newChannel = client.createNotificationChannel(
            ProjectName.of(projectId),
            channel
                .toBuilder()
                .clearName()
                .clearVerificationStatus()
                .build());
        newChannelNames.put(channel.getName(), newChannel.getName());
      }
    }
  }
  return newChannelNames;
}

PHP

use Google\Cloud\Monitoring\V3\NotificationChannelServiceClient;
use Google\Cloud\Monitoring\V3\NotificationChannel;

/**
 * @param string $projectId Your project ID
 */
function alert_create_channel($projectId)
{
    $channelClient = new NotificationChannelServiceClient([
        'projectId' => $projectId,
    ]);
    $projectName = $channelClient->projectName($projectId);

    $channel = new NotificationChannel();
    $channel->setDisplayName('Test Notification Channel');
    $channel->setType('email');
    $channel->setLabels(['email_address' => 'fake@example.com']);

    $channel = $channelClient->createNotificationChannel($projectName, $channel);
    printf('Created notification channel %s' . PHP_EOL, $channel->getName());
}

Python

def restore(project_name):
    print('Loading alert policies and notification channels from backup.json.')
    record = json.load(open('backup.json', 'rt'))
    is_same_project = project_name == record['project_name']
    # Convert dicts to AlertPolicies.
    policies_json = [json.dumps(policy) for policy in record['policies']]
    policies = [google.protobuf.json_format.Parse(
        policy_json, monitoring_v3.types.alert_pb2.AlertPolicy())
        for policy_json in policies_json]
    # Convert dicts to NotificationChannels
    channels_json = [json.dumps(channel) for channel in record['channels']]
    channels = [google.protobuf.json_format.Parse(
        channel_json, monitoring_v3.types.notification_pb2.
        NotificationChannel()) for channel_json in channels_json]

    # Restore the channels.
    channel_client = monitoring_v3.NotificationChannelServiceClient()
    channel_name_map = {}

    for channel in channels:
        updated = False
        print('Updating channel', channel.display_name)
        # This field is immutable and it is illegal to specify a
        # non-default value (UNVERIFIED or VERIFIED) in the
        # Create() or Update() operations.
        channel.verification_status = monitoring_v3.enums.NotificationChannel.\
            VerificationStatus.VERIFICATION_STATUS_UNSPECIFIED

        if is_same_project:
            try:
                channel_client.update_notification_channel(channel)
                updated = True
            except google.api_core.exceptions.NotFound:
                pass  # The channel was deleted.  Create it below.

        if not updated:
            # The channel no longer exists.  Recreate it.
            old_name = channel.name
            channel.ClearField("name")
            new_channel = channel_client.create_notification_channel(
                project_name, channel)
            channel_name_map[old_name] = new_channel.name

    # Restore the alerts
    alert_client = monitoring_v3.AlertPolicyServiceClient()

    for policy in policies:
        print('Updating policy', policy.display_name)
        # These two fields cannot be set directly, so clear them.
        policy.ClearField('creation_record')
        policy.ClearField('mutation_record')

        # Update old channel names with new channel names.
        for i, channel in enumerate(policy.notification_channels):
            new_channel = channel_name_map.get(channel)
            if new_channel:
                policy.notification_channels[i] = new_channel

        updated = False

        if is_same_project:
            try:
                alert_client.update_alert_policy(policy)
                updated = True
            except google.api_core.exceptions.NotFound:
                pass  # The policy was deleted.  Create it below.
            except google.api_core.exceptions.InvalidArgument:
                # Annoying that API throws InvalidArgument when the policy
                # does not exist.  Seems like it should throw NotFound.
                pass  # The policy was deleted.  Create it below.

        if not updated:
            # The policy no longer exists.  Recreate it.
            old_name = policy.name
            policy.ClearField("name")
            for condition in policy.conditions:
                condition.ClearField("name")
            policy = alert_client.create_alert_policy(project_name, policy)
        print('Updated', policy.name)

Como recuperar canais

Para recuperar todos os canais de notificação em um projeto, use o método notificationChannels.list. Esse método também aceita opções filter e orderBy para restringir e classificar os resultados. Consulte Como classificar e filtrar.

Se estiver procurando um canal específico e souber o nome dele, use o método notificationChannels.get para recuperar apenas esse canal. O nome de um canal tem o formato projects/[PROJECT_ID]/notificationChannels/[CHANNEL_ID]. Por exemplo:

projects/a-gcp-project/notificationChannels/1355376463305411567

Quando você recupera um canal, valores confidenciais, como tokens de autenticação e chaves de API, podem ficar ocultos por motivos de segurança. Se você estiver criando um novo canal copiando um atual, todos os valores ocultos precisarão ser corrigidos.

COMANDO GCLOUD

Para listar todos os canais de notificação em um projeto, use o comando gcloud alpha monitoring channels list:

gcloud alpha monitoring channels list

Se bem-sucedido, o comando list fornece uma listagem de todos os canais no projeto especificado. Por exemplo, o comando acima gera uma lista que inclui o seguinte:

---
description: E-mail channel created by gcloud as a test
displayName: test e-mail channel
enabled: false
labels:
  email_address: user@example.com
name: projects/a-gcp-project/notificationChannels/1355376463305411567
type: email
---

Para listar um único canal, use gcloud alpha monitoring channels describe e especifique o nome do canal. Por exemplo, este comando retorna apenas a listagem acima:

gcloud alpha monitoring channels describe projects/a-gcp-project/notificationChannels/1355376463305411567

Consulte as referências de gcloud alpha monitoring channels list e describe para ver mais informações. O comando describe corresponde ao método notificationChannels.get na API.

C#

static void ListNotificationChannels(string projectId)
{
    var client = NotificationChannelServiceClient.Create();
    var response = client.ListNotificationChannels(new ProjectName(projectId));
    foreach (NotificationChannel channel in response)
    {
        Console.WriteLine(channel.Name);
        if (channel.DisplayName != null)
        {
            Console.WriteLine(channel.DisplayName);
        }
        Console.WriteLine();
    }
}

Node.js

// Imports the Google Cloud client library
const monitoring = require('@google-cloud/monitoring');

// Creates a client
const client = new monitoring.NotificationChannelServiceClient();

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const filter = 'A filter for selecting policies, e.g. description:"cloud"';

const request = {name: client.projectPath(projectId), filter};
const channels = await client.listNotificationChannels(request);
console.log(channels);
for (const channel of channels[0]) {
  console.log(`Deleting channel ${channel.displayName}`);
  try {
    await client.deleteNotificationChannel({
      name: channel.name,
    });
  } catch (err) {
    // ignore error
  }
}

Go

channelClient, err := monitoring.NewNotificationChannelClient(ctx)
if err != nil {
	return err
}
channelReq := &monitoringpb.ListNotificationChannelsRequest{
	Name: "projects/" + projectID,
	// Filter:  "", // See https://cloud.google.com/monitoring/api/v3/sorting-and-filtering.
	// OrderBy: "", // See https://cloud.google.com/monitoring/api/v3/sorting-and-filtering.
}
channelIt := channelClient.ListNotificationChannels(ctx, channelReq)
for {
	resp, err := channelIt.Next()
	if err == iterator.Done {
		break
	}
	if err != nil {
		return err
	}
	b.Channels = append(b.Channels, &channel{resp})
}

Java

private static List<NotificationChannel> getNotificationChannels(String projectId)
    throws IOException {
  List<NotificationChannel> notificationChannels = Lists.newArrayList();
  try (NotificationChannelServiceClient client = NotificationChannelServiceClient.create()) {
    ListNotificationChannelsPagedResponse listNotificationChannelsResponse =
        client.listNotificationChannels(ProjectName.of(projectId));
    for (NotificationChannel channel : listNotificationChannelsResponse.iterateAll()) {
      notificationChannels.add(channel);
    }
  }
  return notificationChannels;
}

PHP

use Google\Cloud\Monitoring\V3\NotificationChannelServiceClient;

/**
 * @param string $projectId Your project ID
 */
function alert_list_channels($projectId)
{
    $channelClient = new NotificationChannelServiceClient([
        'projectId' => $projectId,
    ]);

    $channels = $channelClient->listNotificationChannels(
        $channelClient->projectName($projectId)
    );
    foreach ($channels->iterateAllElements() as $channel) {
        printf('Name: %s (%s)' . PHP_EOL, $channel->getDisplayName(), $channel->getName());
    }
}

Python

def list_notification_channels(project_name):
    client = monitoring_v3.NotificationChannelServiceClient()
    channels = client.list_notification_channels(project_name)
    print(tabulate.tabulate(
        [(channel.name, channel.display_name) for channel in channels],
        ('name', 'display_name')))

Como excluir canais

Para excluir um canal de notificação de um projeto, use o método notificationChannels.delete e forneça o nome do canal de notificação a ser excluído. O nome de um canal é o valor do campo name, e não o displayName, na instância de NotificationChannel. O nome de um canal tem o formato projects/[PROJECT_ID]/notificationChannels/[CHANNEL_ID]. Por exemplo:

projects/a-gcp-project/notificationChannels/1355376463305411567

Por padrão, se você tentar excluir um canal referenciado por uma política de alertas, o canal não será excluído. Para forçar a remoção de referências das políticas de alertas e excluir o canal, defina a opção force como true.

COMANDO GCLOUD

Para excluir um canal de notificação, use gcloud alpha monitoring channels delete e especifique o nome do canal a ser excluído. Por exemplo, o seguinte comando exclui o canal email criado em outro exemplo:

gcloud alpha monitoring channels delete projects/a-gcp-project/notificationChannels/1355376463305411567

Consulte a referência de gcloud alpha monitoring channels delete para ver mais informações.

C#

using Google.Cloud.Monitoring.V3;
using System;

partial class AlertSnippets
{
    public void DeleteNotificationChannel(
        string channelName = "projects/your-project-id/notificationChannels/123")
    {
        var client = NotificationChannelServiceClient.Create();
        client.DeleteNotificationChannel(
            name: NotificationChannelName.Parse(channelName),
            force: true);
        Console.WriteLine("Deleted {0}.", channelName);
    }
}

Go

import (
	"context"
	"fmt"
	"io"

	monitoring "cloud.google.com/go/monitoring/apiv3"
	monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3"
)

// deleteChannel deletes the given channel. channelName should be of the form
// "projects/[PROJECT_ID]/notificationChannels/[CHANNEL_ID]".
func deleteChannel(w io.Writer, channelName string) error {
	ctx := context.Background()

	client, err := monitoring.NewNotificationChannelClient(ctx)
	if err != nil {
		return err
	}

	req := &monitoringpb.DeleteNotificationChannelRequest{
		Name: channelName,
	}

	if err := client.DeleteNotificationChannel(ctx, req); err != nil {
		return fmt.Errorf("DeleteNotificationChannel: %v", err)
	}

	fmt.Fprintf(w, "Deleted channel %q", channelName)
	return nil
}

Java

static void deleteNotificationChannel(String channelName) throws IOException {
  String projectId = System.getProperty("projectId");
  try (NotificationChannelServiceClient client = NotificationChannelServiceClient.create()) {
    NotificationChannelName name = NotificationChannelName.of(projectId, channelName);
    client.deleteNotificationChannel(channelName, false);
    System.out.println("Deleted notification channel " + channelName);
  }
}

PHP

use Google\Cloud\Monitoring\V3\NotificationChannelServiceClient;

/**
 * @param string $projectId Your project ID
 */
function alert_delete_channel($projectId, $channelId)
{
    $channelClient = new NotificationChannelServiceClient([
        'projectId' => $projectId,
    ]);
    $channelName = $channelClient->notificationChannelName($projectId, $channelId);

    $channelClient->deleteNotificationChannel($channelName);
    printf('Deleted notification channel %s' . PHP_EOL, $channelName);
}

Node.js

// Imports the Google Cloud client library
const monitoring = require('@google-cloud/monitoring');

// Creates a client
const client = new monitoring.NotificationChannelServiceClient();

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const filter = 'A filter for selecting policies, e.g. description:"cloud"';

const request = {name: client.projectPath(projectId), filter};
const channels = await client.listNotificationChannels(request);
console.log(channels);
for (const channel of channels[0]) {
  console.log(`Deleting channel ${channel.displayName}`);
  try {
    await client.deleteNotificationChannel({
      name: channel.name,
    });
  } catch (err) {
    // ignore error
  }
}

Python

def delete_notification_channels(project_name, channel_ids, force=None):
    channel_client = monitoring_v3.NotificationChannelServiceClient()
    for channel_id in channel_ids:
        channel_name = '{}/notificationChannels/{}'.format(
            project_name, channel_id)
        try:
            channel_client.delete_notification_channel(
                channel_name, force=force)
            print('Channel {} deleted'.format(channel_name))
        except ValueError:
            print('The parameters are invalid')
        except Exception as e:
            print('API call failed: {}'.format(e))

Como modificar canais

Para modificar um canal de notificação, use o método notificationChannels.patch (na API REST). Outras implementações de API e a interface do gcloud chamam update em vez de patch.

Uma operação de atualização pode substituir todo o canal existente ou modificar um subconjunto de campos. Por exemplo, ative e desative o canal. Desativar um canal evita a entrega de notificações para o canal. Desativar um canal costuma ser mais prático do que removê-lo das políticas de alertas que se referem a ele, caso a alteração seja temporária.

COMANDO GCLOUD

Para ativar um canal de notificação desativado, use o comando gcloud alpha monitoring channels update e forneça a sinalização --enabled. O seguinte comando ativa o canal de notificação email criado, no estado desativado, em um exemplo anterior:

gcloud alpha monitoring channels update projects/a-gcp-project/notificationChannels/1355376463305411567 --enabled

Para desativar uma política, use o mesmo comando e forneça a sinalização --no-enabled. Consulte a referência de gcloud alpha monitoring channels update para ver mais informações. O comando update corresponde ao método notificationChannels.patch na API REST.

C#

using Google.Cloud.Monitoring.V3;
using Google.Protobuf.WellKnownTypes;
using System;

partial class AlertSnippets
{
    public NotificationChannel EnableNotificationChannel(
        string channelName = "projects/your-project-id/notificationChannels/123")
    {
        var client = NotificationChannelServiceClient.Create();
        NotificationChannel channel = new NotificationChannel();
        channel.Enabled = true;
        channel.Name = channelName;
        var fieldMask = new FieldMask { Paths = { "enabled" } };
        channel = client.UpdateNotificationChannel(
            updateMask: fieldMask,
            notificationChannel: channel);
        Console.WriteLine("Enabled {0}.", channel.Name);
        return channel;
    }
}

Go

import (
	"context"
	"fmt"
	"io"

	monitoring "cloud.google.com/go/monitoring/apiv3"
	"github.com/golang/protobuf/ptypes/wrappers"
	monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3"
	"google.golang.org/genproto/protobuf/field_mask"
)

// enableChannel enables the given channel. channelName should be of the form
// "projects/[PROJECT_ID]/notificationChannels/[CHANNEL_ID]".
func enableChannel(w io.Writer, channelName string) error {
	ctx := context.Background()

	client, err := monitoring.NewNotificationChannelClient(ctx)
	if err != nil {
		return err
	}

	req := &monitoringpb.UpdateNotificationChannelRequest{
		UpdateMask: &field_mask.FieldMask{Paths: []string{"enabled"}},
		NotificationChannel: &monitoringpb.NotificationChannel{
			Name:    channelName,
			Enabled: &wrappers.BoolValue{Value: true},
		},
	}

	if _, err := client.UpdateNotificationChannel(ctx, req); err != nil {
		return fmt.Errorf("EnableNotificationChannel: %v", err)
	}

	fmt.Fprintf(w, "Enabled channel %q", channelName)
	return nil
}

Node.js

// Imports the Google Cloud client library
const monitoring = require('@google-cloud/monitoring');

// Creates clients
const alertClient = new monitoring.AlertPolicyServiceClient();
const notificationClient = new monitoring.NotificationChannelServiceClient();

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const alertPolicyId = '123456789012314';
// const channelIds = [
//   'channel-1',
//   'channel-2',
//   'channel-3',
// ];

const notificationChannels = channelIds.map(id =>
  notificationClient.notificationChannelPath(projectId, id)
);

for (const channel of notificationChannels) {
  const updateChannelRequest = {
    updateMask: {paths: ['enabled']},
    notificationChannel: {
      name: channel,
      enabled: {value: true},
    },
  };
  try {
    await notificationClient.updateNotificationChannel(updateChannelRequest);
  } catch (err) {
    const createChannelRequest = {
      notificationChannel: {
        name: channel,
        notificationChannel: {type: 'email'},
      },
    };
    const newChannel = await notificationClient.createNotificationChannel(
      createChannelRequest
    );
    notificationChannels.push(newChannel);
  }
}

const updateAlertPolicyRequest = {
  updateMask: {paths: ['notification_channels']},
  alertPolicy: {
    name: alertClient.alertPolicyPath(projectId, alertPolicyId),
    notificationChannels: notificationChannels,
  },
};
const [alertPolicy] = await alertClient.updateAlertPolicy(
  updateAlertPolicyRequest
);
console.log(`Updated ${alertPolicy.name}.`);

Java

private static Map<String, String> restoreNotificationChannels(
    String projectId,
    List<NotificationChannel> channels,
    boolean isSameProject) throws IOException {
  Map<String, String> newChannelNames = Maps.newHashMap();
  try (NotificationChannelServiceClient client = NotificationChannelServiceClient.create()) {
    for (NotificationChannel channel : channels) {
      // Update channel name if project ID is different.
      boolean channelUpdated = false;
      if (isSameProject) {
        try {
          NotificationChannel updatedChannel =
              client.updateNotificationChannel(NOTIFICATION_CHANNEL_UPDATE_MASK, channel);
          newChannelNames.put(channel.getName(), updatedChannel.getName());
          channelUpdated = true;
        } catch (Exception e) {
          channelUpdated = false;
        }
      }
      if (!channelUpdated) {
        NotificationChannel newChannel = client.createNotificationChannel(
            ProjectName.of(projectId),
            channel
                .toBuilder()
                .clearName()
                .clearVerificationStatus()
                .build());
        newChannelNames.put(channel.getName(), newChannel.getName());
      }
    }
  }
  return newChannelNames;
}

PHP

use Google\Cloud\Monitoring\V3\AlertPolicyServiceClient;
use Google\Cloud\Monitoring\V3\NotificationChannelServiceClient;
use Google\Cloud\Monitoring\V3\AlertPolicy;
use Google\Cloud\Monitoring\V3\NotificationChannel;
use Google\Cloud\Monitoring\V3\NotificationChannel\VerificationStatus;
use Google\ApiCore\ApiException;

/**
 * @param string $projectId Your project ID
 */
function alert_restore_policies($projectId)
{
    $alertClient = new AlertPolicyServiceClient([
        'projectId' => $projectId,
    ]);

    $channelClient = new NotificationChannelServiceClient([
        'projectId' => $projectId,
    ]);

    print('Loading alert policies and notification channels from backup.json.' . PHP_EOL);
    $projectName = $alertClient->projectName($projectId);
    $record = json_decode(file_get_contents('backup.json'), true);
    $isSameProject = $projectName == $record['project_name'];

    # Convert dicts to AlertPolicies.
    $policies = [];
    foreach ($record['policies'] as $policyArray) {
        $policy = new AlertPolicy();
        $policy->mergeFromJsonString(json_encode($policyArray));
        $policies[] = $policy;
    }

    # Convert dicts to NotificationChannels
    $channels = [];
    foreach (array_filter($record['channels']) as $channelArray) {
        $channel = new NotificationChannel();
        $channel->mergeFromJsonString(json_encode($channelArray));
        $channels[] = $channel;
    }

    # Restore the channels.
    $channelNameMap = [];
    foreach ($channels as $channel) {
        $updated = false;
        printf('Updating channel %s' . PHP_EOL, $channel->getDisplayName());

        # This field is immutable and it is illegal to specify a
        # non-default value (UNVERIFIED or VERIFIED) in the
        # Create() or Update() operations.
        $channel->setVerificationStatus(
            VerificationStatus::VERIFICATION_STATUS_UNSPECIFIED
        );

        if ($isSameProject) {
            try {
                $channelClient->updateNotificationChannel($channel);
                $updated = true;
            } catch (ApiException $e) {
                # The channel was deleted.  Create it below.
                if ($e->getStatus() !== 'NOT_FOUND') {
                    throw $e;
                }
            }
        }

        if (!$updated) {
            # The channel no longer exists.  Recreate it.
            $oldName = $channel->getName();
            $channel->setName('');
            $newChannel = $channelClient->createNotificationChannel(
                $projectName,
                $channel
            );
            $channelNameMap[$oldName] = $newChannel->getName();
        }
    }

    # Restore the alerts
    foreach ($policies as $policy) {
        printf('Updating policy %s' . PHP_EOL, $policy->getDisplayName());
        # These two fields cannot be set directly, so clear them.
        $policy->setCreationRecord(null);
        $policy->setMutationRecord(null);

        $notificationChannels = $policy->getNotificationChannels();

        # Update old channel names with new channel names.
        foreach ($notificationChannels as $i => $channel) {
            if (isset($channelNameMap[$channel])) {
                $notificationChannels[$i] = $channelNameMap[$channel];
            }
        }

        $updated = false;
        if ($isSameProject) {
            try {
                $alertClient->updateAlertPolicy($policy);
                $updated = true;
            } catch (ApiException $e) {
                # The policy was deleted.  Create it below.
                if ($e->getStatus() !== 'NOT_FOUND') {
                    throw $e;
                }
            }
        }

        if (!$updated) {
            # The policy no longer exists.  Recreate it.
            $oldName = $policy->getName();
            $policy->setName('');
            foreach ($policy->getConditions() as $condition) {
                $condition->setName('');
            }
            $policy = $alertClient->createAlertPolicy($projectName, $policy);
        }
        printf('Updated %s' . PHP_EOL, $policy->getName());
    }
    print('Restored alert policies and notification channels from backup.json.');
}

Python

def restore(project_name):
    print('Loading alert policies and notification channels from backup.json.')
    record = json.load(open('backup.json', 'rt'))
    is_same_project = project_name == record['project_name']
    # Convert dicts to AlertPolicies.
    policies_json = [json.dumps(policy) for policy in record['policies']]
    policies = [google.protobuf.json_format.Parse(
        policy_json, monitoring_v3.types.alert_pb2.AlertPolicy())
        for policy_json in policies_json]
    # Convert dicts to NotificationChannels
    channels_json = [json.dumps(channel) for channel in record['channels']]
    channels = [google.protobuf.json_format.Parse(
        channel_json, monitoring_v3.types.notification_pb2.
        NotificationChannel()) for channel_json in channels_json]

    # Restore the channels.
    channel_client = monitoring_v3.NotificationChannelServiceClient()
    channel_name_map = {}

    for channel in channels:
        updated = False
        print('Updating channel', channel.display_name)
        # This field is immutable and it is illegal to specify a
        # non-default value (UNVERIFIED or VERIFIED) in the
        # Create() or Update() operations.
        channel.verification_status = monitoring_v3.enums.NotificationChannel.\
            VerificationStatus.VERIFICATION_STATUS_UNSPECIFIED

        if is_same_project:
            try:
                channel_client.update_notification_channel(channel)
                updated = True
            except google.api_core.exceptions.NotFound:
                pass  # The channel was deleted.  Create it below.

        if not updated:
            # The channel no longer exists.  Recreate it.
            old_name = channel.name
            channel.ClearField("name")
            new_channel = channel_client.create_notification_channel(
                project_name, channel)
            channel_name_map[old_name] = new_channel.name

    # Restore the alerts
    alert_client = monitoring_v3.AlertPolicyServiceClient()

    for policy in policies:
        print('Updating policy', policy.display_name)
        # These two fields cannot be set directly, so clear them.
        policy.ClearField('creation_record')
        policy.ClearField('mutation_record')

        # Update old channel names with new channel names.
        for i, channel in enumerate(policy.notification_channels):
            new_channel = channel_name_map.get(channel)
            if new_channel:
                policy.notification_channels[i] = new_channel

        updated = False

        if is_same_project:
            try:
                alert_client.update_alert_policy(policy)
                updated = True
            except google.api_core.exceptions.NotFound:
                pass  # The policy was deleted.  Create it below.
            except google.api_core.exceptions.InvalidArgument:
                # Annoying that API throws InvalidArgument when the policy
                # does not exist.  Seems like it should throw NotFound.
                pass  # The policy was deleted.  Create it below.

        if not updated:
            # The policy no longer exists.  Recreate it.
            old_name = policy.name
            policy.ClearField("name")
            for condition in policy.conditions:
                condition.ClearField("name")
            policy = alert_client.create_alert_policy(project_name, policy)
        print('Updated', policy.name)

Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…

Stackdriver Monitoring
Precisa de ajuda? Acesse nossa página de suporte.