使用物件 Lambda 進行轉換
MinIO 的物件 Lambda 使開發人員能夠以程式設計方式按需轉換物件。您可以根據您的使用案例轉換物件,例如編輯個人識別資訊 (PII)、使用來自其他來源的資訊來豐富資料,或在格式之間進行轉換。
概觀
物件 Lambda 處理常式是一個小型程式碼模組,用於轉換物件的內容並傳回結果。與 Amazon S3 物件 Lambda 函式類似,您可以使用來自應用程式的 GET 請求觸發 MinIO 物件 Lambda 處理常式函式。處理常式會從 MinIO 擷取要求的物件、轉換它,然後將修改後的資料傳回 MinIO 以傳送至原始應用程式。原始物件保持不變。
每個處理常式都是一個獨立的程序,多個處理常式可以轉換相同的資料。這讓您可以使用相同的物件來處理不同的用途,而無需維護原始物件的不同版本。
物件 Lambda 處理常式
您可以使用任何能夠傳送和接收 HTTP 請求的語言來撰寫處理常式函式。它必須能夠
接聽 HTTP POST 請求。
使用 URL 擷取原始物件。
傳回轉換後的內容和授權權杖。
建立函式
處理常式函式應執行下列步驟
從傳入的 POST 請求中擷取物件詳細資訊。
JSON 請求酬載的
getObjectContext
屬性包含有關原始物件的詳細資訊。若要建構回應,您需要下列值值
描述
inputS3Url
原始物件的預先簽署的 URL。呼叫應用程式會產生 URL 並在原始請求中傳送它。這讓處理常式能夠存取原始物件,而無需通常需要的 MinIO 認證。URL 的有效期限為一小時。
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 驗證回應,並將轉換後的資料傳回至原始呼叫應用程式。
回應標頭
處理常式必須在適當的回應標頭中包含 outputRoute
和 outputToken
值。這讓 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 以套用變更。
從應用程式觸發
若要從您的應用程式請求轉換後的物件
連線到 MinIO 部署。
透過加入帶有目標處理常式 ARN 的
lambdaArn
參數,設定物件 Lambda 目標。為原始物件產生預先簽署的 URL。
使用產生的 URL 來擷取轉換後的物件。
MinIO 將請求傳送至目標物件 Lambda 處理常式。處理常式將轉換後的內容傳回 MinIO,MinIO 會驗證回應並將其傳回應用程式。
範例
使用 Python、Go 和 curl
轉換物件的內容
建立並註冊物件 Lambda 處理常式。
建立儲存桶和要轉換的物件。
請求並顯示轉換後的物件內容。
先決條件
現有的 MinIO 部署
可運作的 Python (3.8+) 和 Golang 開發環境
建立處理常式
用 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_ENABLE
和 MINIO_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
。
建立儲存桶和物件,供處理常式轉換。
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/
呼叫處理常式
以下 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_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