Como gerenciar canais de notificação pela 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. Atualmente, os tipos de canal disponíveis, descritos mais genericamente em Opções de notificação, são estes:

  • campfire
  • 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

Você pode 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.

Por exemplo, aqui está uma representação JSON de um novo canal de notificação do tipo email:

{
  "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 do campo type precisa corresponder ao campo type em um dos descritores de canal de notificação disponíveis, conforme descrito em Descritores de canal.

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 glcoud 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);
    }
}

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;
}

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

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();
    }
}

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;
}

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.

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#

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);
    }
}

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;
}

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.