您如何在AWS API调用中使用“ NextToken”

Geo*_*eet 6 python amazon-web-services boto3 aws-organizations

我遇到了一个小问题,我真的很难理解它的工作原理。我有一个正在编写的工具,该工具基本上进行描述组织来收集我们AWS组织中的所有账户。根据这里的文档它说它以帐户的json作为响应,在我的情况下将是数百个帐户。因此,我编写了一些非常简单的代码将角色切换到我们的主帐户并进行调用:

import boto3
import uuid
import pprint

iam_client = boto3.client('iam')
sts_client = boto3.client('sts')
org_client = boto3.client('organizations')


print("Starting in account: %s" % sts_client.get_caller_identity().get('Account'))

assumedRoleObject = sts_client.assume_role(
    RoleArn="arn:aws:iam::123456xxx:role/MsCrossAccountAccessRole",
    RoleSessionName="MasterPayer"
)

credentials = assumedRoleObject['Credentials']

org_client = boto3.client(
    'organizations',
    aws_access_key_id = credentials['AccessKeyId'],
    aws_secret_access_key = credentials['SecretAccessKey'],
    aws_session_token = credentials['SessionToken'],
)

getListAccounts = org_client.list_accounts(
    NextToken='string'
)
Run Code Online (Sandbox Code Playgroud)

但是当我执行代码时,出现以下错误:

“ botocore.errorfactory.InvalidInputException:调用ListAccounts操作时发生错误(InvalidInputException):您为nextToken指定了一个无效值。您必须从响应中获取该值,以响应上一次对API的调用。”

我真的很困惑那是什么意思。我看到了NextToken,并且可以在AWS文档中找到许多对它的引用,但是我不知道如何实际使用它。就像,我需要做什么?

Vin*_*t J 14

与其他答案相同,但有一个带有简单while循环的简短片段。

response = client.list_accounts()
results = response["Accounts"]
while "NextToken" in response:
    response = client.list_accounts(NextToken=response["NextToken"])
    results.extend(response["Accounts"])
Run Code Online (Sandbox Code Playgroud)


Tor*_*cht 8

不要从字面上看boto3示例(它们不是实际示例)。这是这样的:

1)第一次打电话给list_accounts您时,它不会带NextToken,所以很简单

getListAccounts = org_client.list_accounts()
Run Code Online (Sandbox Code Playgroud)

2)这将返回一个大致如下所示的JSON响应(这是保存在getListAccounts变量中的内容):

{
    "Accounts": [<lots of accounts information>], 
    "NextToken": <some token>
}
Run Code Online (Sandbox Code Playgroud)

请注意,NextToken只有在您拥有的帐户数量超过一个list_accounts呼叫可以返回的情况下才返回,通常是这样100(boto3文档没有说明默认情况下有多少个)。如果一次呼叫返回了所有帐户NextToken,则响应中没有任何信息!

3)因此,当且仅当在第一次致电中未返回所有帐户时,您现在才想返回更多帐户,并且您将必须使用NextToken来执行此操作:

getListAccountsMore = org_client.list_accounts(NextToken=getListAccounts['NextToken'])
Run Code Online (Sandbox Code Playgroud)

4)重复直到NextToken响应中不再返回no (然后您检索了所有帐户)。

在许多情况下,这就是AWS SDK处理分页的方式。您还将NextToken在其他服务客户端中看到的用法。


小智 5

相反,您可以使用 get_paginator api。找到下面的示例,在我的用例中,我必须获取 SSM 参数存储的所有值,并希望将其与字符串进行比较。

import boto3
import sys

LBURL = sys.argv[1].strip()
client = boto3.client('ssm')
p = client.get_paginator('describe_parameters')
paginator = p.paginate().build_full_result()
for page in paginator['Parameters']:
    response = client.get_parameter(Name=page['Name'])
    value = response['Parameter']['Value']
    if LBURL in value:
        print("Name is: " + page['Name'] + " and Value is: " + value)
Run Code Online (Sandbox Code Playgroud)