附註:

設定 Oracle Cloud Infrastructure Functions 以使用電子郵件傳送成本使用狀況報表

簡介

您可以根據需求自訂成本使用量報表,也可以建立排定的成本使用量報表。依照排程,系統會在選取的 Oracle Cloud Infrastructure (OCI) Object Storage 貯體中提取並儲存報告。

若要使用電子郵件傳送此報表,我們必須部署 OCI 函數。OCI 函數將根據 OCI 中建立的事件規則觸發。每當檔案儲存在儲存桶中時,物件上傳事件會觸發函數,而 OCI 函數將可自動化建立物件的預先認證要求 URL。此 URL 將透過電子郵件傳送。

您可以透過 OCI Email Delivery 服務或 OCI Notifications 服務接收電子郵件。這兩個配置都會在本教學課程中說明。

目標

必要條件

作業 1:設定必要的 OCI IAM 原則和動態群組

  1. 登入 OCI 主控台。如需詳細資訊,請參閱登入 Oracle Cloud

  2. 請前往 OCI IAM 動態群組,然後使用下列規則建立新的動態群組。

    建立動態群組

  3. 請前往 OCI IAM 原則,並使用下列敘述句建立 OCI IAM 原則。

    allow dynamic-group dynamicgroup_name to manage buckets in compartment CompartmentName where all {target.bucket.name='bucket_name'}
    
    allow dynamic-group dynamicgroup_name to manage objects in compartment CompartmentName where all {target.bucket.name='bucket_name'}
    
    Allow service metering_overlay to manage objects in compartment CompartmentName where all {target.bucket.name='bucket_name', any {request.permission='OBJECT_CREATE', request.permission='OBJECT_DELETE', request.permission='OBJECT_READ'}}
    

    若要使用 OCI 通知服務傳送電子郵件,必須在 OCI IAM 原則中新增下列敘述句,才能存取 OCI 通知主題

    allow dynamic-group dynamicgroup_name to use ons-topics in compartment CompartmentName
    

作業 2:建立排定成本使用量報表

  1. 前往 Billing and Cost Management 並選取成本管理。在成本分析下建立您自己的自訂成本用途報表,然後按一下套用以儲存報表。

    建立成本報表

  2. 按一下排定的報表,然後使用您的儲存桶資訊建立新的排定報表。您可以根據您的需求排定此排程。

    建立排定的報表

    根據排程,報表將自動儲存在指定的 OCI 物件儲存的儲存桶中。

作業 3:建立與部署功能代碼

  1. 若要建立應用程式,請前往開發人員服務,按一下應用程式,然後在可用的網路中建立應用程式。

  2. 前往函數 / 應用程式並建立函數。此函數將使用 OCI IAM 動態群組和原則來存取事件。請依照畫面上的步驟來建立函數。我們使用 Python 編寫必要的邏輯程式碼,但您可以使用自己的語言,並視需要變更邏輯。若要撰寫程式碼,請開啟 OCI Cloud Shell 中的函數 requirement.txt 檔案和 func.py 檔案,然後撰寫程式碼。

    在 Cloud Shell 和程式碼編輯器中建立函數

  3. 複製 func.py 中的下列 Python 程式碼和 requirement.txt 檔案中的文字檔。

    • func.py:

      • 使用 OCI 電子郵件傳遞:

        注意:新增個別的電子郵件 ID 和簡易郵件傳輸協定 (SMTP) 詳細資訊。

        import oci
        import json
        import io
        import logging
        import smtplib
        from os.path import basename
        from email.mime.application import MIMEApplication
        from email.mime.multipart import MIMEMultipart
        from email.mime.text import MIMEText
        from email.utils import COMMASPACE, formatdate
        from datetime import datetime
        import ssl
        import email.utils
        from email.message import EmailMessage
        
        def handler(ctx, data: io.BytesIO = None):
           funDataStr = data.read().decode('utf-8')
        
        #Convert the log data to json
           funData =  json.loads(funDataStr)
        
        #Set up OCI configuration using resource principal
           signer = oci.auth.signers.get_resource_principals_signer()
        #Create Object Storage client
           object_storage_client = oci.object_storage.ObjectStorageClient({},signer=signer)
        
        # Extract object details from the event
           object_name = funData['data']['resourceName']
           namespace = funData['data']['additionalDetails']['namespace']
           bucket_name = funData['data']['additionalDetails']['bucketName']
        # Download the object
        #get_object_response = object_storage_client.get_object(namespace, bucket_name, object_name)
        #object_content = str(get_object_response.data.text)
           create_preauthenticated_request_response = object_storage_client.create_preauthenticated_request(
              namespace_name = namespace,
              bucket_name = bucket_name,
              create_preauthenticated_request_details=oci.object_storage.models.CreatePreauthenticatedRequestDetails(
                 name = "prestorage",
                 access_type = "ObjectRead",
                 time_expires = datetime.strptime(
                    "2024-06-05T04:25:22.344Z",
                    "%Y-%m-%dT%H:%M:%S.%fZ"),
                 object_name = object_name))
           #logging.getLogger().info(create_preauthenticated_request_response.data)
           logging.getLogger().info("created pre authenticated url")
           string = str(create_preauthenticated_request_response.data)
           #response = create_preauthenticated_request_response.data().decode('utf-8')
           url = json.loads(string)
           logging.getLogger().info(url)
           temporary_url = f"{url['full_path']}"
           logging.getLogger().info(temporary_url)
        
        #Set your email credentials
           sender_email = "test@domain"
           sender_name = "Tester"
        
        #Set the recipient email address
           recipient_email = "xyz@oracle.com"
           USERNAME_SMTP = "SMTPOCID"
           password_smtp = "************"
           HOST = "smtp_email"
           PORT = 587
        
        #Create the email content
           subject = "Cost Usage Report"
           body = temporary_url
           message = EmailMessage()
           message['From'] = email.utils.formataddr((sender_name, sender_email))
           message['To'] = recipient_email
           message['Subject'] = subject
           message.set_content(body)
           try:
              server = smtplib.SMTP(HOST, PORT)
              server.ehlo()
              server.starttls(context=ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH, cafile=None, capath=None))
              server.ehlo()
              server.login(USERNAME_SMTP, password_smtp)
              logging.getLogger().info("SMTP server logged in")
              server.sendmail(sender_email, recipient_email, message.as_string())
              #server.send_message(message)
              server.close()
           except Exception as e:
              logging.getLogger().info(f"Error: {e}")
           else:
              logging.getLogger().info('Email sent successfully!')
        
      • 使用 OCI 通知:

        注意:更新 OCID 主題 (建立通知的步驟會在「工作 5」中說明)。

        import oci
        import json
        import io
        import logging
        import smtplib
        from os.path import basename
        from email.mime.application import MIMEApplication
        from email.mime.multipart import MIMEMultipart
        from email.mime.text import MIMEText
        from email.utils import COMMASPACE, formatdate
        from datetime import datetime
        import ssl
        import email.utils
        from email.message import EmailMessage
        
        def handler(ctx, data: io.BytesIO = None):
           funDataStr = data.read().decode('utf-8')
        
        # Convert the log data to json
           funData =  json.loads(funDataStr)
        
        # Set up OCI configuration using resource principal
           signer = oci.auth.signers.get_resource_principals_signer()
        # Create Object Storage client
           object_storage_client = oci.object_storage.ObjectStorageClient({},signer=signer)
           ons_client = oci.ons.NotificationDataPlaneClient({},signer=signer)
        # Extract object details from the event
        
        
           object_name = funData['data']['resourceName']
           namespace = funData['data']['additionalDetails']['namespace']
           bucket_name = funData['data']['additionalDetails']['bucketName']
        
        # Download the object
           create_preauthenticated_request_response = object_storage_client.create_preauthenticated_request(
              namespace_name = namespace,
              bucket_name = bucket_name,
              create_preauthenticated_request_details=oci.object_storage.models.CreatePreauthenticatedRequestDetails(
                 name = "prestorage",
                 access_type = "ObjectRead",
                 time_expires = datetime.strptime(
                    "2024-06-05T04:25:22.344Z",
                    "%Y-%m-%dT%H:%M:%S.%fZ"),
                 object_name = object_name))
        #logging.getLogger().info(create_preauthenticated_request_response.data)
           logging.getLogger().info("created pre authenticated url")
           string = str(create_preauthenticated_request_response.data)
        #response = create_preauthenticated_request_response.data().decode('utf-8')
           url = json.loads(string)
        
           logging.getLogger().info(url)
           temporary_url = f"{url['full_path']}"
           logging.getLogger().info(temporary_url)
        #to send mail using notification
           publish_message_response = ons_client.publish_message(
              topic_id="ocid1.onstopic.oc1.iad.************",
              message_details=oci.ons.models.MessageDetails(
                 body=temporary_url,
                 title="Cost-usage report"),
           message_type="RAW_TEXT")
           logging.getLogger().info(publish_message_response)
           logging.getLogger().info('Email sent successfully!')
        
    • requirement.txt:

      fdk>=0.1.68
      oci
      
  4. 使用 OCI Cloud Shell 上的下列命令,更新登錄中的功能並部署最新的程式碼。

    fn -v deploy — app App_name
    

部署之後,即可呼叫您的函數。若要觸發函數,必須建立事件規則。

作業 4:設定事件規則

  1. 在 OCI 中建立事件規則。在可觀測性與管理下,按一下事件服務規則建立規則。輸入比對規則 (如下列影像所示),其屬性為您的儲存桶 ID。

    注意: 建立的 OCI 物件儲存的儲存桶必須啟用發出物件事件

    建立事件規則

  2. 新增動作,如下列影像中所示,其中含有在「工作 2」中建立的函數。

    動作

    現在,會建立函數的觸發程式。

作業 5:使用 OCI 電子郵件傳遞或 OCI 通知設定電子郵件組態

測試

將物件或任何檔案上傳至儲存桶,系統將會使用事件規則自動觸發函數。

認可

其他學習資源

瀏覽 docs.oracle.com/learn 的其他實驗室,或前往 Oracle Learning YouTube 頻道存取更多免費學習內容。此外,請造訪 education.oracle.com/learning-explorer 以成為 Oracle Learning Explorer。

如需產品文件,請造訪 Oracle Help Center