文档

使用对象 Lambda 进行转换

MinIO 的对象 Lambda 使开发人员能够按需以编程方式转换对象。您可以根据用例需要转换对象,例如删除个人身份信息 (PII)、用来自其他来源的信息丰富数据或在格式之间转换。

概述

一个 对象 Lambda 处理程序 是一个小型代码模块,它转换对象的內容并返回结果。与 Amazon S3 对象 Lambda 函数 一样,您可以通过应用程序发出的 GET 请求触发 MinIO 对象 Lambda 处理程序函数。处理程序从 MinIO 检索请求的对象,对其进行转换,并将修改后的数据返回 MinIO,以发送到原始应用程序。原始对象保持不变。

每个处理程序都是一个独立的进程,多个处理程序可以转换相同的数据。这允许您将同一个对象用于不同的目的,而无需维护原始对象的多个版本。

对象 Lambda 处理程序

您可以使用任何能够发送和接收 HTTP 请求的语言编写处理程序函数。它必须能够

  • 侦听 HTTP POST 请求。

  • 使用 URL 检索原始对象。

  • 返回转换后的內容和授权令牌。

创建函数

处理程序函数应执行以下步骤

  1. 从传入的 POST 请求中提取对象详细信息。

    JSON 请求有效负载的 getObjectContext 属性包含有关原始对象的详细信息。要构建响应,您需要以下值

    说明

    inputS3Url

    原始对象的 预签名 URL。调用应用程序生成 URL 并将其发送到原始请求中。这允许处理程序访问原始对象,而无需通常所需的 MinIO 凭据。URL 的有效期为一个小时。

    outputRoute

    一个令牌,允许 MinIO 验证转换后对象的目的地。在 x-amz-request-route 标头中使用响应返回此值。

    outputToken

    一个令牌,允许 MinIO 验证响应。在响应中的 x-amz-request-token 标头中返回此值。

  2. 从 MinIO 检索原始对象。

    使用预签名 URL 从 MinIO 部署中检索对象。对象的內容位于响应的正文中。

  3. 根据需要转换对象。

    执行生成转换后对象所需的任何操作。由于调用应用程序正在等待响应,因此您可能希望避免潜在的长时间运行操作。

  4. 构建包含以下信息的响应

    • 转换后的对象內容。

    • 具有 outputRoute 令牌的 x-amz-request-route 标头。

    • 具有 outputToken 令牌的 x-amz-request-token 标头。

  5. 将响应返回给对象 Lambda。

    MinIO 验证响应并将转换后的数据发送回原始调用应用程序。

响应标头

处理程序**必须**在适当的响应头中包含outputRouteoutputToken 值。 这使得 MinIO 可以正确验证来自处理程序的响应。

注册处理程序

要使 MinIO 能够调用处理程序,请将处理程序函数注册为具有以下MinIO 服务器对象 Lambda 环境变量 的 Webhook。

MINIO_LAMBDA_WEBHOOK_ENABLE_functionname

启用或禁用处理程序函数的对象 Lambda。 对于多个处理程序,请为每个函数名称设置此环境变量。

MINIO_LAMBDA_WEBHOOK_ENDPOINT_functionname

为处理程序函数注册一个端点。 对于多个处理程序,请为每个函数端点设置此环境变量。

MinIO 还支持以下环境变量,用于经过身份验证的 Webhook 端点

MINIO_LAMBDA_WEBHOOK_AUTH_TOKEN_functionanme

指定不透明字符串或 JWT 授权令牌,用于对 Webhook 进行身份验证。

MINIO_LAMBDA_WEBHOOK_CLIENT_CERT_functionname

指定用于对 Webhook 进行 mTLS 身份验证的客户端证书。

MINIO_LAMBDA_WEBHOOK_CLIENT_KEY_functionname

指定用于对 Webhook 进行 mTLS 身份验证的私钥。

重启 MinIO 以应用更改。

从应用程序触发

要从您的应用程序请求转换后的对象

  1. 连接到 MinIO 部署。

  2. 通过添加具有所需处理程序的 ARN 的 lambdaArn 参数,设置对象 Lambda 目标。

  3. 为原始对象生成一个预签名 URL

  4. 使用生成的 URL 检索转换后的对象。

    MinIO 将请求发送到目标对象 Lambda 处理程序。 处理程序将转换后的内容返回到 MinIO,MinIO 验证响应并将其发送回应用程序。

示例

使用 Python、Go 和 curl 转换对象的内容

  • 创建并注册对象 Lambda 处理程序。

  • 创建要转换的存储桶和对象。

  • 请求并显示转换后的对象内容。

先决条件

  • 现有的 MinIO 部署

  • 有效的 Python (3.8+) 和 Golang 开发环境

  • MinIO Go SDK

创建处理程序

示例处理程序是用 Python 编写的,它使用调用者生成的预签名 URL 检索目标对象。 处理程序随后转换对象的内容并返回新文本。 它使用 Flask Web 框架 和 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':
      # Get the request event from the 'POST' call
      event = request.json

      # Get the object context
      object_context = event["getObjectContext"]

      # Get the presigned URL
      # Used to fetch the original object from MinIO
      s3_url = object_context["inputS3Url"]

      # Extract the route and request tokens from the input context
      request_route = object_context["outputRoute"]
      request_token = object_context["outputToken"]

      # Get the original S3 object using the presigned URL
      r = requests.get(s3_url)
      original_object = r.content.decode('utf-8')

      # Transform the text in the object by swapping the case of each char
      transformed_object = original_object.swapcase()

      # Return the object back to Object Lambda, with required headers
      # This sends the transformed data to MinIO
      # and then to the user
      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_ENABLEMINIO_LAMBDA_WEBHOOK_ENDPOINT 环境变量启动 MinIO,以将该函数注册到 MinIO。 要标识特定的对象 Lambda 处理程序,请将函数名称附加到环境变量名称的末尾。

以下命令在本地开发环境中启动 MinIO

MINIO_LAMBDA_WEBHOOK_ENABLE_myfunction=on MINIO_LAMBDA_WEBHOOK_ENDPOINT_myfunction=http://127.0.0.1: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 处理程序函数,首先创建一个要转换的对象。 然后使用 curl(在本例中)调用处理程序,使用来自 Go 函数的预签名 URL。

  1. 为处理程序创建要转换的存储桶和对象。

    mc alias set myminio/ http://127.0.0.1:9000 minioadmin minioadmin
    mc mb myminio/myfunctionbucket
    cat > testobject << EOF
    Hello, World!
    EOF
    mc cp testobject myminio/myfunctionbucket/
    
  2. 调用处理程序

    以下 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() {
    
       // Connect to the MinIO deployment
       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)
       }
    
       // Set the Lambda function target using its ARN
       reqParams := make(url.Values)
       reqParams.Set("lambdaArn", "arn:minio:s3-object-lambda::myfunction:webhook")
    
       // Generate a presigned url to access the original object
       presignedURL, err := s3Client.PresignedGetObject(context.Background(), "myfunctionbucket", "testobject", time.Duration(1000)*time.Second, reqParams)
       if err != nil {
          log.Fatalln(err)
       }
    
       // Print the URL to stdout
       fmt.Println(presignedURL)
    }
    

    在上面的代码中,替换以下值

    • my_admin_usermy_admin_password 替换为 MinIO 部署的用户凭据。

    • myfunction 替换为在 MINIO_LAMBDA_WEBHOOK_ENABLEMINIO_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