使用 ServiceNow 管理预警
本主题介绍如何在发生警报时提交自动 ServiceNow 票证。
在此方案中,只要 CPU 使用量超过预警指定的阈值,就会为您的呼叫工程师创建 ServiceNow 票证。
通过 Oracle Cloud Infrastructure 控制台、API 或 CLI 为云资源分配说明、标记或友好名称时,请勿输入机密信息。
此方案包括编写文件 ServiceNow 票证的函数(以及创建用于存储 ServiceNow 凭证的密钥)、将该函数和可选电子邮件作为订阅添加到主题,以及创建报警,以便在超过报警阈值时向该主题发送消息。消息将风扇传出到主题的订阅,其中除了包含函数外还包括组电子邮件地址。在收到消息时调用函数。
除此功能以外的所有内容都可以在控制台中设置。或者,您也可以使用 Oracle Cloud Infrastructure CLI 或 API,这样您就可以自己执行各个操作。
下图说明了常规处理流程:
将您的 ServiceNow 凭据存储在密钥中
创建后面的函数时将引用的密钥。
使用控制台创建密钥(还可以使用命令行界面 (command line interface,CLI) 或应用程序编程接口 (application programming interface,API) 创建密钥。
创建函数
从以下示例代码开始,创建用于提交 ServiceNow 票证的函数,然后授权该函数在使用 Oracle Cloud Infrastructure Vault 服务创建的密钥中访问 ServiceNow 凭证。
代码示例包括虚拟函数中使用的变量 SNOW_URL、SNOW_USER_ID_SEC 和 SNOW_USER_PWD_SEC。您可以选择直接从函数读取这些值,或者将值作为定制配置参数传递。
#####################################################
# 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使用动态组授予功能读取密钥的能力。您的函数必须具有此授权才能访问 ServiceNow 凭证,这些凭证存储在您之前创建的密钥中。
创建话题
创建将用于订阅和预警的主题。
主题是用于向订阅发送消息的通信渠道。每个主题名称在租户中都是唯一的。可以使用控制台、命令行界面 (command line interface,CLI) 或应用程序编程接口 (application programming interface,API) 创建主题。
必须部署函数,然后才能将其用于主题。
