使用 ServiceNow 管理警示

本主題說明如何在警示觸發時自動提交 ServiceNow 憑證。

在此情況下,只要 CPU 使用量超過警示指定的臨界值,就會為您的待命工程師建立 ServiceNow 許可證。

透過 Oracle Cloud Infrastructure 主控台、API 或 CLI,將描述、標記或易記的名稱指派給您的雲端資源時,請勿輸入機密資訊。

此案例涉及將函數寫入 ServiceNow 回報項目 (並建立密碼以儲存您的 ServiceNow 證明資料)、將該函數和選擇性電子郵件新增為訂閱主題,以及建立超過警示臨界值時傳送訊息至該主題的警示。訊息會將訊息傳送給主題的訂閱,其中除了功能之外還包含群組電子郵件地址。收到訊息時會呼叫函數。

除了上述功能以外,還可以在主控台中設定。或者,您也可以使用 Oracle Cloud Infrastructure CLI 或 API 自行執行個別作業。

下圖說明一般處理程序流程:



servicenow-notifications-oracle.zip

將您的 ServiceNow 憑證儲存於加密密碼中

建立稍後當您建立函數時所要參照的加密密碼。

使用主控台建立加密密碼 (您也可以使用命令行介面 (CLI) 或應用程式設計介面 (API) 建立加密密碼)。

  1. 開啟導覽功能表,按一下識別與安全,然後按一下保存庫
  2. 在「清單範圍」下的「區間」清單中,按一下您要建立加密密碼的區間名稱。
  3. 從區間中的保存庫清單中,執行下列其中一項作業:
    • 按一下您要建立加密密碼的保存庫名稱。
    • 為加密密碼建立新的保存庫,然後按一下保存庫的名稱。
  4. 建立 username 密碼:
    1. 按一下加密密碼,然後按一下建立加密密碼
    2. 在「建立加密密碼」對話方塊中,從「在區間中建立」清單中選擇區間。加密密碼可以存在於保存庫所在的區間之外。)
    3. 按一下名稱,然後輸入識別加密密碼的名稱。請避免在此欄位中輸入任何機密資訊。
      範例名稱:servicenow_username_plain_text
    4. 按一下描述,然後輸入簡短的加密密碼描述來協助識別它。請避免在此欄位中輸入任何機密資訊。
      範例描述:servicenow_username_plain_text
    5. 選擇匯入保存庫時,要用來加密加密加密密碼內容的主要加密金鑰 (金鑰必須屬於相同的保存庫)。
    6. 針對「加密密碼類型樣板」,選擇純文字
    7. 按一下加密內容,然後輸入您的 ServiceNow 使用者名稱:
      <your-servicenow-username>
    8. 按一下建立加密密碼 (Create Secret)
    9. 請注意加密密碼 OCID。

建立函數

從下面的範例程式碼開始建立 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 證明資料。

  1. 尋找並記下下列格式的函數 OCID:
    ocid1.fnfunc.oc1.iad.<exampleuniqueID>

    指定下列規則,將函數包含在相關動態群組中:

    resource.id = '<function-ocid>'

    或者,您可以建立包含所有函數的動態群組:

    ALL{resource.type=’fnfunc’, resource.compartment.id=’<compartment_OCID>’}
  2. 新增下列原則以授予動態群組加密密碼存取。
    allow dynamic-group <dynamic-group-name> to read secret-family in tenancy

    若要授權存取其他 Oracle Cloud Infrastructure 資源 (例如運算執行處理) 的功能,請將該功能包含在動態群組中,並建立原則以授予動態群組對這些資源的存取。

建立主題

建立您將用於訂閱和警示的主題。

主題是將訊息傳送給訂閱的通訊通道。每個主題名稱在整個租用戶中都是唯一的。您可以使用主控台、命令行介面 (CLI) 或應用程式設計介面 (API) 建立主題。

您必須先部署函數,才能搭配主題使用。

  1. 若要使用主控台來建立主題:
    1. 開啟導覽功能表並按一下開發人員服務。在「應用程式整合」底下,按一下通知
    2. 按一下主題清單頂端的建立主題
    3. 在「建立主題」對話方塊中,設定您的主題:
      • 名稱:指定主題的易記名稱。它在整個租用戶必須是唯一的;驗證會區分大小寫。請避免輸入機密資訊。
      • 描述:選擇性輸入主題的描述。請避免輸入機密資訊。
    4. 按一下建立
  2. 若要使用 CLI 建立主題,請開啟指令提示,然後輸入類似下列的指令:
    oci ons topic create
    --name "My Topic"
    --compartment-id "<compartment-ocid>"
  3. 若要使用 API 建立主題,請使用類似下列的作業:
    POST /20181201/topics
    Host: notification.us-phoenix-1.oraclecloud.com
    <authorization and other headers>
    {
      "name": "My Topic",
      "compartmentId": "<compartment_OCID>"
    }
    

建立訂閱

建立主題的訂閱。

訂閱是主題的一個端點。發布的訊息會傳送給每個主題的訂閱。

您必須先部署函數,才能將其與訂閱搭配使用,而且必須具備 FN_INVOCATION 權限才能將函數新增為主題的訂閱。

  1. 若要使用主控台建立函數訂閱:
    1. 開啟導覽功能表並按一下開發人員服務。在「應用程式整合」底下,按一下通知。按一下您要新增訂閱的主題名稱。
    2. 在主題詳細資訊頁面上,按一下建立訂閱
    3. 在「建立訂閱」對話方塊中,設定您的函數訂閱。函數訂閱不需要確認。
      • 若為「訂閱」協定,請按一下函數
      • 針對「函數區間」,按一下包含您函數的區間。
      • 針對「函數應用程式」,按一下包含您函數的應用程式。
      • 針對「函數」,按一下您的函數。
    4. 按一下建立
  2. 若要使用主控台建立選擇性的電子郵件訂閱,請執行下列動作:
    1. 開啟導覽功能表並按一下開發人員服務。在「應用程式整合」底下,按一下通知。按一下您要新增訂閱的主題名稱。
    2. 在主題詳細資訊頁面上,按一下建立訂閱
    3. 在「建立訂閱」對話方塊中,設定您的電子郵件訂閱。
      • 如需訂閱協定,請按一下電子郵件
      • 針對「電子郵件」,指定電子郵件地址。
    4. 按一下建立
      會建立電子郵件訂閱,並傳送訂閱確認 URL 至指定的電子郵件地址。訂閱在確認前會維持待處理狀態。若要確認您的新電子郵件訂閱,請開啟該電子郵件並按一下確認 URL。
  3. 若要使用 CLI 建立訂閱,請執行下列動作:
    1. 若要建立函數訂閱,請開啟命令提示字元,然後輸入類似下列的命令:
      oci ons subscription create
      --compartment-id "<compartment-ocid>"
      --topic-id "<topic-ocid>" 
      --protocol "ORACLE_FUNCTIONS"
      --subscription-endpoint "<function-ocid>"
    2. 若要建立電子郵件訂閱,請開啟命令提示字元,然後輸入類似下列的命令:
      oci ons subscription create
      --compartment-id "<compartment-ocid>"
      --topic-id "<topic-ocid>" 
      --protocol "EMAIL"
      --subscription-endpoint "team@example.com"
  4. 若要使用 API 建立訂閱,請執行下列動作:
    1. 若要使用 API 建立函數訂閱,請使用類似下列的作業:
      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. 若要使用 API 建立電子郵件訂閱,請使用類似下列的作業:
      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"
      
      } 

建立警示

建立在超過警示臨界值時,傳送訊息給主題的警示。「通知」會接著將訊息傳遞給該主題中的作用中訂閱。

  1. 如果要使用主控台來建立警示:
    1. 開啟導覽功能表並按一下可觀察性與管理。在監督底下,按一下警示定義
    2. 按一下建立警示
    3. 建立警示頁面的定義警示下,設定您的臨界值:
      在「測量結果」描述下:
      • 區間:選取包含感興趣運算執行處理的區間。
      • 度量命名空間:oci_computeagent
      • 測量結果名稱:CpuUtilization
      • 間隔: 1m
      • 統計資料:計數
      在「觸發器」規則之下:
      • 運算子:大於
      • 值: 90
      • 觸發延遲分鐘數: 1
    4. 若要定義警示通知,請將您先前建立的主題新增為目的地。
      在目的地:
      • 目的地服務:通知
      • 區間:(選取包含您主題的區間)
      • 主題:(選取您的主題)
    5. 按一下儲存警示
  2. 若要使用 CLI 建立警示,請開啟命令提示字元,然後輸入類似下列的命令:
    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. 若要使用 API 建立警示,請使用類似下列的作業:
    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
    }