我正在尝试制作一个简单的Python Lambda,它可以为我们的Elasticsearch数据库创建快照。这是通过Elasticsearch's REST API使用简单的HTTP请求完成的。
但是,对于AWS,我必须签署这些请求。我有一种感觉,它可以通过boto3
的低级客户端来实现,可能是generate_presigned_url
,但我不能在我的生活中找出如何正确调用此函数。例如,有效的ClientMethod
是什么?我试过ESHttpGet
,但无济于事。
有人能指出我正确的方向吗?
答案 0 :(得分:9)
我挣扎了一段时间做类似的事情。目前,boto3库并不支持发出已签名的es请求,但由于我raised an issue与它们一起成为了一个功能请求。
以下是我在此期间使用上面提到的DavidMuller's library和boto3获取我的STS会话凭据所做的事情:
import boto3
from aws_requests_auth.aws_auth import AWSRequestsAuth
from elasticsearch import Elasticsearch, RequestsHttpConnection
session = boto3.session.Session()
credentials = session.get_credentials().get_frozen_credentials()
es_host = 'search-my-es-domain.eu-west-1.es.amazonaws.com'
awsauth = AWSRequestsAuth(
aws_access_key=credentials.access_key,
aws_secret_access_key=credentials.secret_key,
aws_token=credentials.token,
aws_host=es_host,
aws_region=session.region_name,
aws_service='es'
)
# use the requests connection_class and pass in our custom auth class
es = Elasticsearch(
hosts=[{'host': es_host, 'port': 443}],
http_auth=awsauth,
use_ssl=True,
verify_certs=True,
connection_class=RequestsHttpConnection
)
print(es.info())
希望这能节省一些时间。
答案 1 :(得分:7)
请求库有几个Python扩展,它们将为您执行SigV4签名。我使用了this one,效果很好。
答案 2 :(得分:3)
我最近发布了requests-aws-sign,它为Python请求库提供了AWS V4请求签名。
如果查看this code,您将看到如何使用Botocore生成V4请求签名。
答案 3 :(得分:1)
虽然其他答案都很好,但我想避免使用外部软件包。显然,botocore
本身具有签署请求的所有必需功能,这只是查看源代码而已。这就是我最终直接发送AWS API请求的内容(出于演示目的,这些内容经过了硬编码):
import boto3
import botocore.credentials
from botocore.awsrequest import AWSRequest
from botocore.endpoint import BotocoreHTTPSession
from botocore.auth import SigV4Auth
params = '{"name": "hello"}'
headers = {
'Host': 'ram.ap-southeast-2.amazonaws.com',
}
request = AWSRequest(method="POST", url="https://ram.ap-southeast-2.amazonaws.com/createresourceshare", data=params, headers=headers)
SigV4Auth(boto3.Session().get_credentials(), "ram", "ap-southeast-2").add_auth(request)
session = BotocoreHTTPSession()
r = session.send(request.prepare())
答案 4 :(得分:0)
为什么不只使用请求?
import requests
headers = {'Content-Type': 'application/json',}
data = '{"director": "Burton, Tim", "genre": ["Comedy","Sci-Fi","R-rated"],"profit" : 98 , "year": 1996, "actor": ["Jack Nicholson","PierceBrosnan","Sarah Jessica Parker"], "title": "Mars Attacks!"}'
response = requests.post('https://search-your-awsendpoint.us-west-2.es.amazonaws.com/yourindex/_yourdoc/', headers=headers, data=data)
这对我有用