注意:
- 此教程需要访问 Oracle Cloud。要注册免费账户,请参阅开始使用 Oracle Cloud Infrastructure Free Tier 。
- 它使用 Oracle Cloud Infrastructure 身份证明、租户和区间示例值。完成实验室时,请将这些值替换为特定于您的云环境的值。
设置 Oracle Cloud Infrastructure Functions 以使用电子邮件发送成本使用情况报告
简介
可以根据需求自定义成本使用情况报告,也可以创建计划成本使用情况报告。根据计划,报告将被提取并保存在选定的 Oracle Cloud Infrastructure (OCI) 对象存储桶中。
要使用电子邮件发送此报告,我们需要部署 OCI Functions。将根据在 OCI 中创建的事件规则触发 OCI 函数。每当文件存储在存储桶中时,对象上载事件都会触发函数,OCI Functions 将自动为对象创建预先验证的请求 URL。此 URL 将通过电子邮件发送。
可以通过 OCI Email Delivery 服务或 OCI Notifications 服务接收电子邮件。本教程对这两种配置进行了说明。
目标
- 设置 OCI Functions 以使用电子邮件获取计划成本使用情况报告。
先决条件
-
在 Oracle Cloud Infrastructure Identity and Access Management (OCI IAM) 中创建动态组 OCI IAM 策略的访问权限,用于创建在存储桶中具有计划成本使用情况报告的函数。
-
访问所有必需的组件以查看其 Oracle Cloud 标识符 (OCID) 和其他相关信息。
-
访问 OCI Cloud Shell,以便创建、部署和调用函数。
-
OCI Functions 的网络资源需要可用。VCN 和子网配置。
任务 1:设置必需的 OCI IAM 策略和动态组
-
登录到 OCI 控制台。有关详细信息,请参阅登录到 Oracle Cloud 。
-
转到 OCI IAM 动态组并使用以下规则创建新的动态组。
-
转到 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:创建计划成本使用报表
-
转至开单和成本管理,然后选择成本管理。在成本分析下创建您自己的自定义成本使用情况报表,然后单击应用以保存报表。
-
单击计划报表并使用存储桶信息创建新的计划报表。您可以根据您的要求安排此项工作。
根据计划,报告将自动保存在给定 OCI 对象存储桶中。
任务 3:创建和部署函数代码
-
要创建应用程序,请转到开发人员服务,单击应用程序并在可用网络中创建应用程序。
-
转到 functions/applications 并创建函数。此函数将使用 OCI IAM 动态组和策略来访问事件。按照屏幕上的步骤创建函数。我们使用 Python 编写所需的逻辑代码,但您可以使用自己的语言,并根据需要更改逻辑。要编写代码,请在 OCI Cloud Shell 中打开函数
requirement.txt
文件和func.py
文件并编写代码。 -
复制
func.py
中的以下 Python 代码和requirement.txt
文件中的文本文件。-
func.py
:-
使用 OCI 电子邮件传送:
注:添加相应的电子邮件 ID 和简单邮件传输协议 (Simple Mail Transfer Protocol,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
-
-
在 OCI Cloud Shell 上使用以下命令更新注册表中的函数并部署最新代码。
fn -v deploy — app App_name
部署后,即可调用函数。要触发函数,需要创建事件规则。
任务 4:设置事件规则
-
在 OCI 中创建事件规则。在可观察性和管理下,单击事件服务、规则和创建规则。输入匹配规则,如下图所示,并将属性作为存储桶 ID。
注:创建的 OCI 对象存储存储桶应启用 emit 对象事件。
-
使用在任务 2 中创建的函数添加操作,如下图中所示。
现在,为函数创建触发器。
任务 5:使用 OCI 电子邮件传送或 OCI 通知设置电子邮件配置
-
使用 OCI 电子邮件传送(这需要公共 DNS 域):
-
在 OCI 中创建电子邮件域。转到 Developer Services(开发人员服务),然后选择 Email Delivery(电子邮件传送)。根据可用的公共 DNS 创建电子邮件域。电子邮件域名应与公共 DNS 名称相同。
-
通过在公共 DNS 记录中添加记录,在电子邮件域中配置域密钥标识的邮件 (DKIM) 和批准的发件人。有关设置电子邮件域和配置的更多信息,请参阅使用 OCI 电子邮件传送发送电子邮件的分步说明。
-
为您的用户创建 SMTP 凭证。生成 SMTP 凭证并保存它以供将来使用。必须在
func.py
文件中提供相同的已批准的电子邮件 ID 和 SMTP 凭证。
-
-
使用 OCI 通知服务:
-
要创建主题,请转至开发人员服务。在应用程序集成下,单击通知。
-
在主题页中,单击创建主题并输入所需的信息。
-
创建主题后,创建订阅。输入 Protocol(协议)作为
Email
和必需的电子邮件 ID。 -
电子邮件将发送到端点以确认订阅。
-
测试
将对象或任何文件上载到存储桶,并使用事件规则自动触发功能。
相关链接
确认
- 作者 - Samratha S P(高级云工程师)
更多学习资源
浏览 docs.oracle.com/learn 上的其他实验室,或者通过 Oracle Learning YouTube 频道访问更多免费学习内容。此外,请访问 education.oracle.com/learning-explorer 以成为 Oracle Learning Explorer。
有关产品文档,请访问 Oracle 帮助中心。
Set Up Oracle Cloud Infrastructure Functions to Send Cost Usage Report using Email
F96407-03
December 2024