我使用boto库,版本信息:
boto==2.38.0
botocore==0.81.0
我在一个EC2实例上使用boto.utils.get_instance_metadata()
,它的元数据是为了使用我与实例关联的安全凭证。有时凭证在meta_data['iam']['security-credentials']['ROLE_NAME']
下,但其他时候'security-credentials'只是指向一个空字典。
除了尝试boto3
之外,还有什么建议/解释吗?
刚刚弄清楚,这是因为boto.utils.get_instance_metadata()
返回<class 'boto.utils.LazyLoadMetadata'>
的实例而不是真正的dict
。它的内部dict
结构体也是LazyLoadMetadata
的成员。对于可以惰性获取的数据,这个类提供的迭代器似乎只返回已经被显式访问过的项/值。因为与实例关联的凭据是临时的,所以惰性地获取它们是有意义的。
的例子:
>>> import boto.utils
>>> meta_data = boto.utils.get_instance_metadata()
>>> creds = meta_data.get('iam', {}).get('security-credentials', {})
>>> debug_vals = list(creds.iteritems())
>>> debug_vals
[('ROLE_NAME', None)]
>>>
>>> creds # printing the object evaluates/loads the entire 'tree'
{'ROLE_NAME': {u'Code': u'Success', u'LastUpdated': u'2015-10-20T15:19:27Z', u'AccessKeyId': u'AQW...', u'SecretAccessKey': u'LmA...', u'Token': u'AQ...', u'Expiration': u'2015-10-20T21:36:17Z', u'Type': u'AWS-HMAC'}}
>>>
>>>
>>> debug_vals # old instance was already populated, so it won't change
[('ROLE_NAME', None)]
>>>
>>> debug_vals2 = list(creds.iteritems()) # a new call to iteritems gets the fully loaded tree
>>> debug_vals2
[('ROLE_NAME', {u'Code': u'Success', u'LastUpdated': u'2015-10-20T15:19:27Z', u'AccessKeyId': u'AQW...', u'SecretAccessKey': u'LmA...', u'Token': u'AQ...', u'Expiration': u'2015-10-20T21:36:17Z', u'Type': u'AWS-HMAC'}}]
# THE END
所以如果你直接访问它们,你会找到期望值。如果你对它们进行迭代,你可能会得到意想不到的结果。