2016-05-18 87 views
6

Próbuję wyświetlić instancje dla wartości znaczników różnych kluczy znaczników Dla np.> Jednego klucza znacznika - Środowisko, inny klucz znacznika - Rola. Mój kod jest podany poniżej:Jakie są prawidłowe sposoby pisania filtrów Boto3 w celu użycia niestandardowej nazwy znacznika?

import argparse 
import boto3 

AWS_ACCESS_KEY_ID = '<Access Key>' 
AWS_SECRET_ACCESS_KEY = '<Secret Key>' 

def get_ec2_instances(Env,Role): 
    ec2 = boto3.client("ec2", region) 
    reservations = ec2.describe_instances(Filters={"tag:environment" : Env, "tag:role" : Role}) 
    for reservation in reservations["Reservations"] : 
     for instance in reservation["Instances"]: 
      print "%s" % (instance.tags['Name']) 

if __name__ == '__main__': 

    regions = ['us-east-1','us-west-1','us-west-2','eu-west-1','sa-east-1', 
       'ap-southeast-1','ap-southeast-2','ap-northeast-1'] 
    parser = argparse.ArgumentParser() 
    parser.add_argument('Env', default="environment", help='value for tag:environment'); 
    parser.add_argument('Role', default="role", help='value for tag:role'); 
    args = parser.parse_args() 

    for region in regions: get_ec2_instances(args.Env, args.Role) 

Po uruchomieniu tego skryptu: python script.py arg1 arg2

otrzymuję następujący błąd

Traceback (most recent call last): 
    File "script.py", line 27, in <module> 
    for region in regions: get_ec2_instances(args.Env, args.Role) 
    File "script.py", line 10, in get_ec2_instances 
    reservations = ec2.describe_instances(Filters={"tag:environment" : Env, "tag:role" : Role}) 
    File "/usr/local/lib/python2.7/dist-packages/botocore/client.py", line 258, in _api_call 
    return self._make_api_call(operation_name, kwargs) 
    File "/usr/local/lib/python2.7/dist-packages/botocore/client.py", line 524, in _make_api_call 
    api_params, operation_model, context=request_context) 
    File "/usr/local/lib/python2.7/dist-packages/botocore/client.py", line 577, in _convert_to_request_dict 
    api_params, operation_model) 
    File "/usr/local/lib/python2.7/dist-packages/botocore/validate.py", line 270, in serialize_to_request 
    raise ParamValidationError(report=report.generate_report()) 
botocore.exceptions.ParamValidationError: Parameter validation failed: 
Invalid type for parameter Filters, value: {'tag:role': 'arg1', 'tag:environment': 'arg2'}, type: <type 'dict'>, valid types: <type 'list'>, <type 'tuple'> 

Odpowiedz

9

To wygląda znajomo, ja zmodyfikować to dla ktoś gdzieś ;-). W rzeczywistości kod, który napisałem, jest w pośpiechu i nie został poprawnie przetestowany (I nie zawracam sobie głowy zmianą ciągu znaków w% i zastąpieniem go str.format()). W rzeczywistości użycie parametru Filters nie jest poprawnie udokumentowane w AWS.

Aby dowiedzieć się więcej o poprawnej metodzie filtrów, skorzystaj z bloga Russell Ballestrini Filtering AWS resources with Boto3.

  1. Filtry przyjmują wartość listy, a informacje w tagach powinny być zgodne z dict. stąd [{}]
  2. Dokumentacja Boto3 jest dość niejednoznaczna, jeśli chodzi o sposób podania nazwy znacznika. Jest mylące bez przykładów, kiedy mówią, że możesz użyć tagu: klucz. Tak wielu ludzi po prostu zrobi [{"tag:keyname","Values": [""] }] i to nie działa. (Właściwie kod źródłowy zakładam, że programista wie, jak działają filtry, więc poprawiam tylko strukturę).
  3. W rzeczywistości MUSISZ wyraźnie określić parę "Nazwa" i "Wartości". Tak więc prawidłowym sposobem określenia nazwy znacznika jest [{"Name" :"tag:keyname", "Values":[""] }]. To trudne.

więc poprawny sposób formatowania filtrów, jeśli chcesz użyć jako przykład

filters = [{'Name':'tag:environment', 'Values':[Env]}, 
      {'Name':'tag:role', 'Values':[Role]} 
      ] 

(aktualizacja) i upewnić argparse potrwać wartość ciągu, po prostu egzekwować argument do podjęcia wartości ciągów

parser.add_argument('Env', type=str, default="environment", help='value for tag:environment'); 
parser.add_argument('Role', type=str,default="role", help='value for tag:role'); 
0

Fix ENV i roli, jak nie jestem pewien, czy moja odpowiedź mootmoot będzie działać, ponieważ Array dla wartości expects strun.

reservervations = ec2.describe_instances(
     Filters=[ 
      {'Name': 'tag:environment', 'Values': ['%s'], 'Name': 'tag:role', 'Values': ['%s']} % (Env, Role), 
     ]] 
    ).get(
     'Reservations', [] 
    )