使用对象 Lambda 进行转换
MinIO的Object Lambda功能允许开发者在需要时以编程方式转换对象。 您可以根据您的用例需要转换对象,例如删除个人可识别信息(PII)、用其他来源的信息丰富数据,或者转换格式。
概述
一个 Object Lambda 处理程序 是一个小的代码模块,它转换对象的正文内容并返回结果。 与 Amazon S3 Object Lambda 函数 类似,您可以通过应用程序的GET请求触发MinIO Object Lambda处理程序函数。 处理程序从MinIO检索请求的对象,对其进行转换,然后将修改后的数据返回到MinIO,以便MinIO将其发送到原始应用程序。 原始对象保持不变。
每个处理程序都是一个独立的过程,并且可以有多个处理程序同时转换相同的数据。 这种方式允许您使用同一对象的不同用途,而无需维护原始对象的多个版本。
对象 Lambda 处理程序
您可以使用任何能够发送和接收HTTP请求的编程语言编写处理程序函数。 它必须能够:
侦听 HTTP POST 请求。
使用URL检索原始对象。
返回转换后的内容和相关授权令牌。
创建一个函数
处理器函数应执行以下步骤:
从传入的POST请求中提取对象详情。
JSON请求负载中的
getObjectContext
属性包含了原始对象的详细信息。 要构建响应,您需要以下值:Value
描述
inputS3Url
原始对象的 预签名URL。 调用应用程序生成URL并将其包含在原始请求中。 这允许处理程序在没有通常所需的MinIO凭据的情况下访问原始对象。 该URL的有效期为1小时。
outputRoute
一个令牌,允许MinIO验证转换对象的目的地。 在响应中以
x-amz-request-route
头部的值返回这个值。outputToken
一个令牌,允许MinIO验证响应。 在响应中,将这个值作为
x-amz-request-token
头部的值返回。从MinIO检索原始对象。
使用预签名的URL从MinIO部署中检索对象。 对象的内容在响应的正文中。
按照需求转换对象。
执行任何必要的操作来生成转换后的对象。 由于调用应用程序正在等待响应,您可能希望避免潜在的长时间运行的操作。
构造一个响应,包含以下信息:
转换后对象的内容。
一个包含
outputRoute
令牌的x-amz-request-route
头信息。一个包含
outputToken
令牌的x-amz-request-token
头信息。
将响应返回给对象lambda。
MinIO 验证响应,并将转换后的数据发送回原始调用应用程序。
Response headers
处理器 必须 在适当的响应头中包含 outputRoute
和 outputToken
值。
这允许 MinIO 正确验证处理器返回的响应。
注册处理程序
要使 MinIO 能够调用处理程序,请使用以下 MinIO 服务器对象 Lambda 环境变量 将处理程序函数注册为 Webhook:
MINIO_LAMBDA_WEBHOOK_ENABLE_functionname
启用或禁用处理程序函数的 Object Lambda。 对于多个处理程序,为每个函数名称设置此环境变量。
MINIO_LAMBDA_WEBHOOK_ENDPOINT_functionname
为处理程序函数注册一个端点。 对于多个处理程序,为每个函数端点设置此环境变量。
MinIO 还支持以下环境变量用于经过身份验证的 webhook 端点:
MINIO_LAMBDA_WEBHOOK_AUTH_TOKEN_functionanme
指定用于向 webhook 进行身份验证的透明字符串或 JWT 授权令牌。
MINIO_LAMBDA_WEBHOOK_CLIENT_CERT_functionname
指定用于与 webhook 进行 mTLS 身份验证的客户端证书。
MINIO_LAMBDA_WEBHOOK_CLIENT_KEY_functionname
指定用于与 webhook 进行 mTLS 身份验证的私钥。
要应用更改,请重新启动 MinIO。
或者,使用 MinIO Client 命令行工具配置 Object Lambda。 有关更多信息,请参阅 对象Lambda功能设置 。
从应用程序触发
要从您的应用程序请求转换后的对象:
连接到 MinIO 部署。
通过添加带有所需处理程序的 ARN 的
lambdaArn
参数来设置对象 Lambda 目标。生成原始对象的 预签名 URL。
使用生成的 URL 检索转换后的对象。
MinIO 将请求发送到目标对象Lambda处理程序。 处理程序将转换后的内容返回给 MinIO,MinIO 验证响应并将其发送回应用程序。
例子 —
使用 Python、Go 和 curl
转换对象的内容:
创建并注册一个对象Lambda处理程序。
创建一个存储桶和一个要转换的对象。
请求并显示转换后的对象内容。
先决条件:
现有的 MinIO <minio-installation>` 部署
有效的 Python (3.8+) 和 Golang 开发环境
创建处理程序
示例处理程序使用调用方生成的 预签名URL 检索目标对象。 然后,处理程序转换对象的内容并返回新文本。 它使用了 Flask网络框架 和Python 3.8+。
以下命令安装Flask和其他所需依赖项:
pip install flask requests
处理程序调用 swapcase()
来改变原始文本中每个字母的大小写。
然后,它将结果发送回MinIO,MinIO再将其返回给调用者。
from flask import Flask, request, abort, make_response
import requests
app = Flask(__name__)
@app.route('/', methods=['POST'])
def get_webhook():
if request.method == 'POST':
# 从'POST'调用中获取请求事件
event = request.json
# 获取对象上下文
object_context = event["getObjectContext"]
# 获取预签名URL
# 用于从MinIO获取原始对象
s3_url = object_context["inputS3Url"]
# 从输入上下文中提取路由和请求令牌
request_route = object_context["outputRoute"]
request_token = object_context["outputToken"]
# 使用预签名URL获取原始S3对象
r = requests.get(s3_url)
original_object = r.content.decode('utf-8')
# 通过交换每个字符的大小写来转换对象中的文本
transformed_object = original_object.swapcase()
# 将对象返回到对象Lambda,并带有必需的头部信息
# 这会将转换后的数据发送到MinIO
# 然后发送给用户。
resp = make_response(transformed_object, 200)
resp.headers['x-amz-request-route'] = request_route
resp.headers['x-amz-request-token'] = request_token
return resp
else:
abort(400)
if __name__ == '__main__':
app.run()
启动处理程序
在您的本地开发环境中启动处理程序的命令是:
python lambda_handler.py
输出类似于以下内容:
* Serving Flask app 'lambda_handler'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:5000
Press CTRL+C to quit
启动 MinIO
一旦处理程序运行起来,您就可以使用 MINIO_LAMBDA_WEBHOOK_ENABLE
和 MINIO_LAMBDA_WEBHOOK_ENDPOINT
环境变量来启动MinIO,并向MinIO注册函数。
为了识别特定的Object Lambda处理程序,请在环境变量的名称后面附加函数的名称。
以下命令在您的本地开发环境中启动MinIO:
MINIO_LAMBDA_WEBHOOK_ENABLE_myfunction=on MINIO_LAMBDA_WEBHOOK_ENDPOINT_myfunction=http://localhost:5000 minio server /data
将 myfunction
替换为您处理程序函数的名称,将 /data
替换为您本地部署的MinIO目录的位置。
输出类似于以下内容:
MinIO Object Storage Server
Copyright: 2015-2023 MinIO, Inc.
License: GNU AGPLv3 <https://www.gnu.org/licenses/agpl-3.0.html>
Version: RELEASE.2023-03-24T21-41-23Z (go1.19.7 linux/arm64)
Status: 1 Online, 0 Offline.
API: http://192.168.64.21:9000 http://127.0.0.1:9000
RootUser: minioadmin
RootPass: minioadmin
Object Lambda ARNs: arn:minio:s3-object-lambda::myfunction:webhook
测试处理程序
为了测试Lambda处理函数,首先创建一个转换对象。
然后使用Go函数中的预签名URL调用处理程序,在这种情况下使用 curl
。
为了让处理程序进行转换,需要创建一个存储桶和对象。
mc alias set myminio/ http://localhost:9000 minioadmin minioadmin mc mb myminio/myfunctionbucket cat > testobject << EOF Hello, World! EOF mc cp testobject myminio/myfunctionbucket/
调用处理程序
以下Go代码使用 MinIO Go SDK 生成一个预签名URL,并将其打印到
stdout
。package main import ( "context" "log" "net/url" "time" "fmt" "github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7/pkg/credentials" ) func main() { // 连接到 MinIO 部署 s3Client, err := minio.New("localhost:9000", &minio.Options{ Creds: credentials.NewStaticV4("my_admin_user", "my_admin_password", ""), Secure: false, }) if err != nil { log.Fatalln(err) } // 使用其 ARN 设置 Lambda 函数目标 reqParams := make(url.Values) reqParams.Set("lambdaArn", "arn:minio:s3-object-lambda::myfunction:webhook") // 生成预签名 url 来访问原始对象 presignedURL, err := s3Client.PresignedGetObject(context.Background(), "myfunctionbucket", "testobject", time.Duration(1000)*time.Second, reqParams) if err != nil { log.Fatalln(err) } // 将 URL 打印到标准输出 fmt.Println(presignedURL) }
在上述代码中,请替换以下值:
将
my_admin_user
和my_admin_password
替换为 MinIO 部署的用户凭据。将
myfunction
替换为在MINIO_LAMBDA_WEBHOOK_ENABLE
和MINIO_LAMBDA_WEBHOOK_ENDPOINT
环境变量中设置的相同函数名称。
为了检索转换后的对象,请使用
curl
执行Go代码以生成GET请求:curl -v $(go run presigned.go)
curl
运行Go代码,然后使用预签名的URL通过GET请求检索对象。 输出类似于以下内容:* Trying 127.0.0.1:9000... * Connected to localhost (127.0.0.1) port 9000 (#0) > GET /myfunctionbucket/testobject?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=minioadmin%2F20230406%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230406T184749Z&X-Amz-Expires=1000&X-Amz-SignedHeaders=host&lambdaArn=arn%3Aminio%3As3-object-lambda%3A%3Amyfunction%3Awebhook&X-Amz-Signature=68fe7e03929a7c0da38255121b2ae09c302840c06654d1b79d7907d942f69915 HTTP/1.1 > Host: localhost:9000 > User-Agent: curl/7.81.0 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < Content-Security-Policy: block-all-mixed-content < Strict-Transport-Security: max-age=31536000; includeSubDomains < Vary: Origin < Vary: Accept-Encoding < X-Amz-Id-2: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 < X-Amz-Request-Id: 17536CF16130630E < X-Content-Type-Options: nosniff < X-Xss-Protection: 1; mode=block < Date: Thu, 06 Apr 2023 18:47:49 GMT < Content-Length: 14 < Content-Type: text/plain; charset=utf-8 < hELLO, wORLD! * Connection #0 to host localhost left intact