boto3是否有类似awscli的凭证缓存机制?

11

使用awscli时,~/.aws/cli/cache中有一个凭据缓存,可以让我缓存凭据一段时间。这在使用MFA时非常有帮助。boto3是否具有类似的功能,还是我必须显式地缓存从 session = boto3.session.Session(profile_name='CTO:Admin') 返回的凭据?


你最终解决了这个问题吗? - KunalC
4个回答

5

已经存在。

http://boto3.readthedocs.org/en/latest/guide/configuration.html#assume-role-provider

当你指定一个包含IAM角色配置的配置文件时,boto3会发出AssumeRole调用来检索临时凭证。后续的boto3 API调用将使用缓存的临时凭证,直到它们过期,此时boto3将自动刷新凭证。boto3不会将这些临时凭证写入磁盘。这意味着AssumeRole调用中的临时凭证仅在单个Session内在内存中缓存。从该会话创建的所有客户端将共享相同的临时凭证。


5
使用 .aws/credentials 和 .aws/config 文件,但不使用 .aws/cli/cache。所有缓存仅存在于内存中,因此仅在 Python 脚本运行时存在,但是我找不到实现 JSONFileCache 中所述的持久缓存。 - n2ygk
这个例子向您展示如何设置缓存到文件。https://github.com/mixja/boto3-session-cache#update-december-2017 - Naliba

3
我为您创建了一个Python库,为您提供了这个功能-请参阅https://github.com/mixja/boto3-session-cache 示例:
import boto3_session_cache

# This returns a regular boto3 client object with the underlying session configured with local credential cache 
client = boto3_session_cache.client('ecs')
ecs_clusters = client.list_clusters()

请问您能否更新一下您的答案,加入您在库中的更新内容吗?这对我们非常有用。 - Roman

2
总结上述要点,以下是一个工作示例:
from os import path
import os
import sys
import json
import datetime
from distutils.spawn import find_executable
from botocore.exceptions import ProfileNotFound
import boto3
import botocore


def json_encoder(obj):
    """JSON encoder that formats datetimes as ISO8601 format."""
    if isinstance(obj, datetime.datetime):
        return obj.isoformat()
    else:
        return obj


class JSONFileCache(object):
    """JSON file cache.
    This provides a dict like interface that stores JSON serializable
    objects.
    The objects are serialized to JSON and stored in a file.  These
    values can be retrieved at a later time.
    """

    CACHE_DIR = path.expanduser(path.join('~', '.aws', 'ansible-ec2', 'cache'))

    def __init__(self, working_dir=CACHE_DIR):
        self._working_dir = working_dir

    def __contains__(self, cache_key):
        actual_key = self._convert_cache_key(cache_key)
        return path.isfile(actual_key)

    def __getitem__(self, cache_key):
        """Retrieve value from a cache key."""
        actual_key = self._convert_cache_key(cache_key)
        try:
            with open(actual_key) as f:
                return json.load(f)
        except (OSError, ValueError, IOError):
            raise KeyError(cache_key)

    def __setitem__(self, cache_key, value):
        full_key = self._convert_cache_key(cache_key)
        try:
            file_content = json.dumps(value, default=json_encoder)
        except (TypeError, ValueError):
            raise ValueError("Value cannot be cached, must be "
                             "JSON serializable: %s" % value)
        if not path.isdir(self._working_dir):
            os.makedirs(self._working_dir)
        with os.fdopen(os.open(full_key,
                               os.O_WRONLY | os.O_CREAT, 0o600), 'w') as f:
            f.truncate()
            f.write(file_content)

    def _convert_cache_key(self, cache_key):
        full_path = path.join(self._working_dir, cache_key + '.json')
        return full_path


session = boto3.session.Session()

try:
    cred_chain = session._session.get_component('credential_provider')
except ProfileNotFound:
    print "Invalid Profile"
    sys.exit(1)

provider = cred_chain.get_provider('assume-role')
provider.cache = JSONFileCache()

# Do something with the session...
ec2 = session.resource('ec2')

1
最初,凭证缓存和临时凭证的自动更新是AWSCLI的一部分,但this commit(以及一些随后的提交)将该功能移至botocore,这意味着现在也可以在boto3中使用。

1
有没有一种方法可以实际共享~/.aws/cli/cache文件?由于没有更好的方法,我从awscli/customizations/assumerole.py中复制了JSONFileCache,但是我得到了“ValueError: Value cannot be cached, must be JSON serializable:” 我用json.dumps进行了探索,发现过期日期时间是破坏序列化的原因。我可以自己编写这个序列化的版本,但我认为我可能错过了一些明显的东西。谢谢。 - n2ygk
1
你需要添加 datetime.datetime 的自定义 JSON 编码。从 awscli/utils.py 中添加 json_encode 函数,并将其添加为默认编码器 json.dumps(value, default=json_encoder) - Rickard von Essen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接