2016-07-01 24 views
6

Sto provando a creare un semplice Python Lambda che crei istantanee del nostro database Elasticsearch. Questo viene fatto tramite Elasticsearch's REST API utilizzando semplici richieste HTTP.Esecuzione di una richiesta HTTP firmata per AWS Elasticsearch in Python

Tuttavia, per AWS, devo firmare queste richieste. Ho la sensazione che possa essere raggiunto tramite i client di basso livello boto3 probabilmente con generate_presigned_url, ma non riesco a capire come richiamare correttamente questa funzione. Ad esempio, quali sono gli ClientMethod validi? Ho provato ESHttpGet ma senza alcun risultato.

Qualcuno può indicarmi la giusta direzione?

+0

Ok ha fatto qualche ricerca. Non pensare che 'generate_presigned_url' sia la strada da percorrere. Penso che le sole operazioni disponibili per me siano operazioni ES di alto livello elencate nei documenti: http://boto3.readthedocs.io/en/latest/reference/services/es.html#ElasticsearchService.Client.generate_presigned_url – Alec

risposta

5

Ci sono diverse estensioni Python alla libreria delle richieste che eseguiranno la firma SigV4 per te. Ho usato this one e funziona bene.

+0

Sì, I speravo di mantenerlo solo su 'boto3' e' botocore', ma ho finito con l'uso di 'AWSAuthConnection' in' boto' - sembra che faccia il trucco. – Alec

3

Ho recentemente pubblicato requests-aws-sign, che fornisce la firma delle richieste AWS V4 per la libreria di richieste Python.

Se guardi allo this code vedrai come puoi usare Botocore per generare la firma della richiesta V4.

6

Ho faticato un po 'per fare una cosa simile. Attualmente la libreria boto3 non supporta la creazione di richieste firmate, sebbene dal momento che I raised an issue con esse sia diventata una richiesta di funzionalità.

Ecco quello che ho fatto nel frattempo utilizzando DavidMuller's library menzionati sopra e boto3 per ottenere i miei STS credenziali di sessione:

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()) 

Spero che questo consente di risparmiare qualcuno un po 'di tempo.

+0

'boto3.Session()' ha funzionato per me. – Hexy