Gerenciar Alarmes com ServiceNow

Este tópico explica como registrar tickets ServiceNow automáticos sempre que os alarmes forem disparados.

Neste cenário, sempre que o uso da CPU exceder o limite especificado por seu alarme, um ticket ServiceNow é criado para seu engenheiro de chamada.

Não digite informações confidenciais ao designar descrições, tags ou nomes simples aos seus recursos na nuvem por meio da Console, API ou CLI do Oracle Cloud Infrastructure.

Esse cenário envolve gravar uma função para registrar tickets ServiceNow (e criar um segredo para armazenar suas credenciais ServiceNow), adicionar essa função e um e-mail opcional como assinaturas a um tópico e criar um alarme que envia mensagens a esse tópico quando o limite de alarme é excedido. Os fãs da mensagem para fora das assinaturas do tópico, que inclui um endereço de e-mail de grupo além da função. A função é chamada no recebimento da mensagem.

Tudo, exceto a função, pode ser configurado na Console. Como alternativa, você pode usar a CLI ou a API do Oracle Cloud Infrastructure, que permite que você mesmo execute as operações individuais.

O seguinte diagrama ilustra o fluxo geral do processo:



servicenow-notifications - oracle.zip

Armazene suas Credenciais ServiceNow em um Segredo

Crie um segredo que você fará referência posteriormente ao criar a função.

Crie um segredo usando a console (você também pode criar um segredo usando a CLI (interface de linha de comando) ou a API (interface de programação de aplicativos).

  1. Abra o menu de navegação, clique em Identidade e Segurança e, em seguida, clique em Vault.
  2. Em Escopo da Lista, na lista Compartimento, clique no nome do compartimento no qual você deseja criar um segredo.
  3. Na lista de vaults no compartimento, execute um dos seguintes procedimentos:
    • Clique no nome do vault no qual você deseja criar um segredo.
    • Crie um novo vault para o segredo e clique no nome do vault.
  4. Crie o segredo username:
    1. Clique em Segredos e em Criar Segredo.
    2. Na caixa de diálogo Criar Segredo, escolha um compartimento na lista Criar no Compartimento. É possível haver segredos fora do compartimento no qual o vault reside.)
    3. Clique em Nome e informe um nome para identificar o segredo. Evite digitar qualquer informação confidencial neste campo.
      Nome de exemplo: servicenow_username_plain_text
    4. Clique em Descrição e informe uma breve descrição do segredo para ajudar a identificá-lo. Evite digitar qualquer informação confidencial neste campo.
      Exemplo de descrição: servicenow_username_plain_text
    5. Escolha a chave de criptografia principal que você deseja usar para criptografar o conteúdo do segredo enquanto ele é importado para o vault (a chave deve pertencer ao mesmo vault).
    6. Para Modelo de Tipo de Segredo, escolha Texto Sem Formatação.
    7. Clique em Conteúdo do Segredo e informe seu nome de usuário ServiceNow:
      <your-servicenow-username>
    8. Clique em Criar Segredo.
    9. Observe o OCID do segredo.

Criar a Função

Comece com o código de amostra abaixo para criar uma função para arquivar tíquetes ServiceNow e, em seguida, autorizar a função a acessar suas credenciais ServiceNow no segredo criado usando o serviço Oracle Cloud Infrastructure Vault.

A amostra de código inclui as variáveis SNOW_URL, SNOW_USER_ID_SEC e SNOW_USER_PWD_SEC que são usadas na função hipotética. Você pode optar por ler esses valores diretamente da função ou informar os valores como parâmetros de configuração personalizados.

#####################################################
# THIS SAMPLE CODE IS FOR DEMO PURPOSES ONLY
#*************************************************
# ******** DO NOT USE IN PRODUCTION *************
# ************************************************
#####################################################
import io
import sys
import oci
import json
import base64
import requests
from fdk import response
SNOW_URL = '<Provide Service Now URL here>'
SNOW_USER_ID_SEC = '<Provide the OCID of OCI Secret for Service Now User ID>'
SNOW_USER_PWD_SEC = '<Provide the OCID of OCI Secret for Service Now User Password>'
OCI_TO_SNOW_SEV_MAP =
{    'CRITICAL'  : '1',    'WARNING'   : '2',    'ERROR'     : '3',    'INFO'      : '4' }
def handler(ctx, data: io.BytesIO = None):
    try:
        funDataStr = data.read().decode('utf-8')
        funDataJSON =  json.loads(funDataStr)
        alarmData = {}
        alarmData['type'] = funDataJSON['type']
        alarmData['metaDataList'] = funDataJSON['alarmMetaData']
        alarmData['title'] = funDataJSON['title']
        alarmData['body'] = funDataJSON['body']
        alarmData['sev'] = OCI_TO_SNOW_SEV_MAP[funDataJSON['severity'].upper()]
        if alarmData['type'].upper() == 'OK_TO_FIRING':
            snowURL = SNOW_URL
            snowUsrIDSec = SNOW_USER_ID_SEC
            snowUsrPwdSec = SNOW_USER_PWD_SEC
            ociResPrncplSigner = oci.auth.signers.get_resource_principals_signer()
            ociSecSvc = oci.secrets.SecretsClient(config={}, signer=ociResPrncplSigner)
            snowUserID = readSecValueFromSecSvc(ociSecSvc, snowUsrIDSec)
            snowPswd = readSecValueFromSecSvc(ociSecSvc, snowUsrPwdSec)
            snowData = getSNOWData(alarmData)
            sendDataToSnow(snowURL, snowUserID, snowPswd, snowData)
    except Exception as e:
        sys.stderr.write("Exception : " + str(e))
        sys.stderr.write("Exception Class : " + str(e._class_))
    return response.Response(ctx, response_data="", headers={"Content-Type": "application/json"})
def sendDataToSnow(snowURL, uid, pwd, snowData):
    try:
{ 
snowHdrs =
      "Content-Type" : "application/json",
counter = 0
for sd in snowData:
"Accept" : "application/json"         }
        snowResp = requests.post(snowURL, auth=(uid, pwd), headers=snowHdrs, data=json.dumps(sd))
except Exception as e:
    sys.stderr.write("Exception : " + str(e))
    sys.stderr.write("Exception Class : " + str(e._class_))
   def getSNOWData(alarmData):
       snowData = []
       if alarmData['type'].upper() == 'OK_TO_FIRING':
           alrmMD = alarmData['metaDataList'][0]
           for d in alrmMD['dimensions']:
               snowDataElem = {}
               snowDataElem['node'] = d['resourceDisplayName']
               snowDataElem['source'] = 'OCI'
               snowDataElem['severity'] = alarmData['sev']
               snowDataElem['description'] = alarmData['body']
               snowDataElem['type'] = alarmData['title']
               snowData.append(snowDataElem)
       return snowData
   def readSecValueFromSecSvc(ociSecSvc, secID):
       secResp = ociSecSvc.get_secret_bundle(secID)
       secContent = secResp.data.secret_bundle_content.content
       secret_content = base64.b64decode(secContent).decode('utf-8')
       return secret_content

Use um grupo dinâmico para conceder à sua função a capacidade de ler segredos. Sua função deve ter essa autorização para acessar suas credenciais ServiceNow, que são armazenadas nos segredos que você criou anteriormente.

  1. Localize e anote o OCID da sua função que está no seguinte formato:
    ocid1.fnfunc.oc1.iad.<exampleuniqueID>

    Inclua sua função no grupo dinâmico relevante especificando a seguinte regra:

    resource.id = '<function-ocid>'

    Como alternativa, você pode criar um grupo dinâmico que inclua todas as funções:

    ALL{resource.type=’fnfunc’, resource.compartment.id=’<compartment_OCID>’}
  2. Conceda ao grupo dinâmico acesso a segredos adicionando a política a seguir.
    allow dynamic-group <dynamic-group-name> to read secret-family in tenancy

    Para autorizar sua função de acesso a outros recursos do Oracle Cloud Infrastructure, como instâncias de computação, inclua a função em um grupo dinâmico e crie uma política para conceder ao grupo dinâmico acesso a esses recursos.

Criar o Tópico

Crie o tópico que você usará para as inscrições e o alarme.

Um tópico é um canal de comunicação para enviar mensagens a inscrições. Cada nome de tópico é exclusivo na tenancy. Você pode criar o tópico usando a console, a CLI (interface de linha de comando) ou a API (interface de programação de aplicativos).

Implante a função para usá-la com um tópico.

  1. Para criar o tópico usando a console:
    1. Abra o menu de navegação e clique em Serviços ao Desenvolvedor. Em Integração de Aplicativos, clique em Notificações.
    2. Clique em Criar Tópico na parte superior da lista de tópicos.
    3. Na caixa de diálogo Criar Tópico, configure o tópico:
      • Nome: Especifique um nome amigável para o tópico. Ele deve ser exclusivo na tenancy; a validação diferencia maiúsculas de minúsculas. Evite digitar informações confidenciais.
      • Descrição: Opcionalmente, insira uma descrição para o tópico. Evite digitar informações confidenciais.
    4. Clique em Criar.
  2. Para criar o tópico usando a CLI, abra um prompt de comando e digite um comando semelhante ao seguinte:
    oci ons topic create
    --name "My Topic"
    --compartment-id "<compartment-ocid>"
  3. Para criar o tópico usando a API, use operações semelhantes às seguintes:
    POST /20181201/topics
    Host: notification.us-phoenix-1.oraclecloud.com
    <authorization and other headers>
    {
      "name": "My Topic",
      "compartmentId": "<compartment_OCID>"
    }
    

Criar as Assinaturas

Crie a assinatura para o tópico.

Uma assinatura é um ponto final para um tópico. As mensagens publicadas são enviadas a cada inscrição de um tópico.

Você deve implantar a função antes de usá-la com uma assinatura e deve ter a permissão FN_INVOCATION para que a função possa adicionar a função como uma inscrição em um tópico.

  1. Para criar a assinatura de função usando a console:
    1. Abra o menu de navegação e clique em Serviços ao Desenvolvedor. Em Integração de Aplicativos, clique em Notificações. Clique no nome do tópico ao qual deseja adicionar a inscrição.
    2. Na página de detalhes do tópico, clique em Criar Inscrição.
    3. Na caixa de diálogo Criar Inscrição, configure a sua inscrição de função. A confirmação não é necessária para inscrições de função.
      • Para o protocolo de Inscrição, clique em Função.
      • Para Compartimento da Função, clique no compartimento que contém sua função.
      • para Aplicativo da Função, clique no aplicativo que contém sua função.
      • Para Função, clique em sua função.
    4. Clique em Criar.
  2. Para criar uma assinatura de e-mail opcional usando a console:
    1. Abra o menu de navegação e clique em Serviços ao Desenvolvedor. Em Integração de Aplicativos, clique em Notificações. Clique no nome do tópico ao qual deseja adicionar a inscrição.
    2. Na página de detalhes do tópico, clique em Criar Inscrição.
    3. Na caixa de diálogo Criar Inscrição, configure sua inscrição de e-mail.
      • Para o protocolo de Inscrição, clique em E-mail.
      • Para E-mail, especifique um endereço de e-mail.
    4. Clique em Criar.
      A inscrição de e-mail é criada e um URL de confirmação de inscrição é enviado para o endereço de e-mail especificado. A inscrição permanece no status Pendente até ser confirmada. Para confirmar sua nova inscrição de e-mail, abra o e-mail e clique no URL de confirmação.
  3. Para criar uma assinatura usando a CLI:
    1. Para criar uma assinatura de função, abra um prompt de comando e digite um comando semelhante ao seguinte:
      oci ons subscription create
      --compartment-id "<compartment-ocid>"
      --topic-id "<topic-ocid>" 
      --protocol "ORACLE_FUNCTIONS"
      --subscription-endpoint "<function-ocid>"
    2. Para criar uma assinatura de e-mail, abra um prompt de comando e digite um comando semelhante ao seguinte:
      oci ons subscription create
      --compartment-id "<compartment-ocid>"
      --topic-id "<topic-ocid>" 
      --protocol "EMAIL"
      --subscription-endpoint "team@example.com"
  4. Para criar uma assinatura usando a API:
    1. Para criar uma assinatura de função usando a API, use operações semelhantes às seguintes:
      POST /20181201/subscriptions
      Host: notification.us-phoenix-1.oraclecloud.com
      <authorization and other headers>
      {
        "topicId": "<topic_OCID>",
        "compartmentId": "<compartment_OCID>",
        "protocol": "ORACLE_FUNCTIONS",
        "endpoint": "<function_OCID>"
      } 
    2. Para criar uma assinatura de e-mail usando a API, use operações semelhantes às seguintes:
      POST /20181201/subscriptions
      Host: notification.us-phoenix-1.oraclecloud.com
      <authorization and other headers>
      {
        "topicId": "<topic_OCID>",
        "compartmentId": "<compartment_OCID>",  
        "protocol": "EMAIL",
        "endpoint": "team@example.com"
      
      } 

Crie o alarme

Crie o alarme que envia uma mensagem para o tópico sempre que o limite do alarme for excedido. O Notifications então entrega a mensagem a assinaturas ativas nesse tópico.

  1. Para criar o alarme usando a console:
    1. Abra o menu de navegação e clique em Observação e Gerenciamento. Em Monitoring, clique em Definições de Alarme.
    2. Clique em Criar alarme.
    3. Na página Criar alarme, em Definir alarme, configure seu limite:
      Na descrição da Métrica:
      • Compartimento: Selecione o compartimento que contém instâncias do serviço Compute de seu interesse.
      • Namespace da Métrica: oci_computeagent
      • Nome da Métrica: CpuUtilization
      • Intervalo: 1m
      • Estatística: Contagem
      Na regra do Acionador:
      • Operador: maior que
      • Valor: 90
      • Minutos de Atraso do Trigger: 1
    4. Para definir notificações de alarme, adicione o tópico criado anteriormente como destino.
      Em Destino:
      • Serviço de Destino: Notificações
      • Compartimento: (selecione o compartimento que contém seu tópico)
      • Tópico: (selecione seu tópico)
    5. Clique em Salvar alarme.
  2. Para criar o alarme usando a CLI, abra um prompt de comando e digite um comando semelhante ao seguinte:
    oci monitoring alarm create
    --display-name "My Alarm"
    --compartment-id "<compartment-ocid>" 
    --metric-compartment-id "<compartment-ocid>" 
    --namespace "oci_computeagent" 
    --query-text "CPUUtilization[1m].count() > 90"
    --severity "CRITICAL"
    --destinations "<topic-ocid>"
    --is-enabled true
  3. Para criar o alarme usando a API, use operações semelhantes às seguintes:
    POST /20180401/alarms
    Host: telemetry.us-phoenix-1.oraclecloud.com
    <authorization and other headers>
    {
      "displayName": "My Alarm",
      "compartmentId": "<compartment_OCID>",
      "metricCompartmentId": "<compartment_OCID>",
      "namespace": "oci_computeagent",
      "query": "MemoryUtilization[1m].max() > 90",
      "severity": "CRITICAL",
      "destinations":
        [
          "<topic_OCID>"
        ],
      "isEnabled": true
    }