文件

使用物件 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

指定用於驗證 webhook 的不透明字串或 JWT 授權權杖。

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=https://127.0.0.1:5000 minio server /data

myfunction 取代為您的處理常式函數名稱,並將 /data 取代為本機部署的 MinIO 目錄位置。輸出類似如下

MinIO Object Storage Server
Copyright: 2015-2023 MinIO, Inc.
License: GNU AGPLv3 <https://gnu.dev.org.tw/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

  1. 建立儲存桶和物件,供處理常式轉換。

    mc alias set myminio/ https://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