boto3-assist 0.12.0__py3-none-any.whl → 0.13.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- boto3_assist/boto3session.py +36 -139
- boto3_assist/role_assumption_mixin.py +38 -0
- boto3_assist/session_setup_mixin.py +29 -0
- boto3_assist/version.py +1 -1
- {boto3_assist-0.12.0.dist-info → boto3_assist-0.13.0.dist-info}/METADATA +1 -1
- {boto3_assist-0.12.0.dist-info → boto3_assist-0.13.0.dist-info}/RECORD +9 -7
- {boto3_assist-0.12.0.dist-info → boto3_assist-0.13.0.dist-info}/WHEEL +0 -0
- {boto3_assist-0.12.0.dist-info → boto3_assist-0.13.0.dist-info}/licenses/LICENSE-EXPLAINED.txt +0 -0
- {boto3_assist-0.12.0.dist-info → boto3_assist-0.13.0.dist-info}/licenses/LICENSE.txt +0 -0
boto3_assist/boto3session.py
CHANGED
|
@@ -4,21 +4,14 @@ Maintainers: Eric Wilson
|
|
|
4
4
|
MIT License. See Project Root for the license information.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
from typing import
|
|
8
|
-
|
|
7
|
+
from typing import Optional, List, Any
|
|
9
8
|
import boto3
|
|
10
|
-
from aws_lambda_powertools import Logger
|
|
11
9
|
from botocore.config import Config
|
|
12
|
-
from
|
|
13
|
-
from
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
logger = Logger(__name__)
|
|
17
|
-
|
|
10
|
+
from .session_setup_mixin import SessionSetupMixin
|
|
11
|
+
from .role_assumption_mixin import RoleAssumptionMixin
|
|
18
12
|
|
|
19
|
-
class Boto3SessionManager:
|
|
20
|
-
"""Manages Boto3 Sessions"""
|
|
21
13
|
|
|
14
|
+
class Boto3SessionManager(SessionSetupMixin, RoleAssumptionMixin):
|
|
22
15
|
def __init__(
|
|
23
16
|
self,
|
|
24
17
|
service_name: str,
|
|
@@ -26,8 +19,9 @@ class Boto3SessionManager:
|
|
|
26
19
|
aws_profile: Optional[str] = None,
|
|
27
20
|
aws_region: Optional[str] = None,
|
|
28
21
|
assume_role_arn: Optional[str] = None,
|
|
22
|
+
assume_role_chain: Optional[List[str]] = None,
|
|
29
23
|
assume_role_session_name: Optional[str] = None,
|
|
30
|
-
|
|
24
|
+
assume_role_duration_seconds: Optional[int] = 3600,
|
|
31
25
|
config: Optional[Config] = None,
|
|
32
26
|
aws_endpoint_url: Optional[str] = None,
|
|
33
27
|
aws_access_key_id: Optional[str] = None,
|
|
@@ -37,154 +31,57 @@ class Boto3SessionManager:
|
|
|
37
31
|
self.service_name = service_name
|
|
38
32
|
self.aws_profile = aws_profile
|
|
39
33
|
self.aws_region = aws_region
|
|
40
|
-
self.assume_role_arn = assume_role_arn
|
|
41
|
-
self.assume_role_session_name = assume_role_session_name
|
|
42
34
|
self.config = config
|
|
43
|
-
# # self.cross_account_role_arn = cross_account_role_arn
|
|
44
35
|
self.endpoint_url = aws_endpoint_url
|
|
36
|
+
self.assume_role_chain = assume_role_chain or (
|
|
37
|
+
[assume_role_arn] if assume_role_arn else []
|
|
38
|
+
)
|
|
39
|
+
self.assume_role_session_name = (
|
|
40
|
+
assume_role_session_name or f"AssumeRoleSessionFor{service_name}"
|
|
41
|
+
)
|
|
42
|
+
self.assume_role_duration_seconds = assume_role_duration_seconds
|
|
45
43
|
self.aws_access_key_id = aws_access_key_id
|
|
46
44
|
self.aws_secret_access_key = aws_secret_access_key
|
|
47
45
|
self.aws_session_token = aws_session_token
|
|
48
46
|
|
|
49
|
-
self.__session:
|
|
47
|
+
self.__session: Optional[boto3.Session] = None
|
|
50
48
|
self.__client: Any = None
|
|
51
49
|
self.__resource: Any = None
|
|
52
50
|
|
|
53
|
-
self.
|
|
54
|
-
|
|
55
|
-
def
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
"""Assume an AWS IAM role."""
|
|
72
|
-
try:
|
|
73
|
-
if not self.__session:
|
|
74
|
-
raise RuntimeError(
|
|
75
|
-
"Session must be established before assuming a role."
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
logger.debug(f"Assuming role {self.assume_role_arn}")
|
|
79
|
-
|
|
80
|
-
sts_client = self.__session.client("sts")
|
|
81
|
-
session_name = (
|
|
82
|
-
self.assume_role_session_name
|
|
83
|
-
or f"AssumeRoleSessionFor{self.service_name}"
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
assumed_role_response = sts_client.assume_role(
|
|
87
|
-
RoleArn=self.assume_role_arn,
|
|
88
|
-
RoleSessionName=session_name,
|
|
89
|
-
)
|
|
90
|
-
credentials = assumed_role_response["Credentials"]
|
|
91
|
-
|
|
92
|
-
# Now override the session with assumed credentials
|
|
93
|
-
self.__session = boto3.Session(
|
|
94
|
-
aws_access_key_id=credentials["AccessKeyId"],
|
|
95
|
-
aws_secret_access_key=credentials["SecretAccessKey"],
|
|
96
|
-
aws_session_token=credentials["SessionToken"],
|
|
97
|
-
region_name=self.aws_region,
|
|
98
|
-
)
|
|
99
|
-
logger.debug("Successfully assumed role and created new session.")
|
|
100
|
-
|
|
101
|
-
except Exception as e:
|
|
102
|
-
logger.error(f"Error assuming role: {e}")
|
|
103
|
-
raise RuntimeError(f"Failed to assume role {self.assume_role_arn}") from e
|
|
104
|
-
|
|
105
|
-
def __get_aws_session(
|
|
106
|
-
self, aws_profile: Optional[str] = None, aws_region: Optional[str] = None
|
|
107
|
-
) -> boto3.Session | None:
|
|
108
|
-
"""Get a boto3 session for AWS."""
|
|
109
|
-
logger.debug({"profile": aws_profile, "region": aws_region})
|
|
110
|
-
try:
|
|
111
|
-
self.aws_profile = aws_profile or EnvironmentVariables.AWS.profile()
|
|
112
|
-
self.aws_region = aws_region or EnvironmentVariables.AWS.region()
|
|
113
|
-
tmp_access_key_id = self.aws_access_key_id
|
|
114
|
-
tmp_secret_access_key = self.aws_secret_access_key
|
|
115
|
-
if not EnvironmentVariables.AWS.display_aws_access_key_id():
|
|
116
|
-
tmp_access_key_id = (
|
|
117
|
-
"None" if tmp_access_key_id is None else "***************"
|
|
118
|
-
)
|
|
119
|
-
if not EnvironmentVariables.AWS.display_aws_secret_access_key():
|
|
120
|
-
tmp_secret_access_key = (
|
|
121
|
-
"None" if tmp_secret_access_key is None else "***************"
|
|
122
|
-
)
|
|
123
|
-
|
|
124
|
-
logger.debug(
|
|
125
|
-
{
|
|
126
|
-
"profile": self.aws_profile,
|
|
127
|
-
"region": self.aws_region,
|
|
128
|
-
"aws_access_key_id": tmp_access_key_id,
|
|
129
|
-
"aws_secret_access_key": tmp_secret_access_key,
|
|
130
|
-
"aws_session_token": (
|
|
131
|
-
"*******" if self.aws_session_token is not None else ""
|
|
132
|
-
),
|
|
133
|
-
}
|
|
51
|
+
self.__initialize()
|
|
52
|
+
|
|
53
|
+
def __initialize(self):
|
|
54
|
+
base_session = self._create_base_session(
|
|
55
|
+
self.aws_profile,
|
|
56
|
+
self.aws_region,
|
|
57
|
+
self.aws_access_key_id,
|
|
58
|
+
self.aws_secret_access_key,
|
|
59
|
+
self.aws_session_token,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
if self.assume_role_chain:
|
|
63
|
+
self.__session = self._assume_roles_in_chain(
|
|
64
|
+
base_session,
|
|
65
|
+
self.assume_role_chain,
|
|
66
|
+
self.assume_role_session_name,
|
|
67
|
+
self.assume_role_duration_seconds,
|
|
68
|
+
self.aws_region,
|
|
134
69
|
)
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
# if self.aws_profile or self.aws_region
|
|
138
|
-
# else boto3.Session()
|
|
139
|
-
|
|
140
|
-
except Exception as e:
|
|
141
|
-
logger.error(e)
|
|
142
|
-
raise RuntimeError("Failed to create a boto3 session.") from e
|
|
143
|
-
|
|
144
|
-
logger.debug({"session": session})
|
|
145
|
-
return session
|
|
70
|
+
else:
|
|
71
|
+
self.__session = base_session
|
|
146
72
|
|
|
147
73
|
@property
|
|
148
74
|
def client(self) -> Any:
|
|
149
|
-
"""Return the boto3 client connection."""
|
|
150
75
|
if not self.__client:
|
|
151
|
-
logger.debug(f"Creating {self.service_name} client")
|
|
152
76
|
self.__client = self.__session.client(
|
|
153
|
-
self.service_name,
|
|
154
|
-
config=self.config,
|
|
155
|
-
endpoint_url=self.endpoint_url,
|
|
77
|
+
self.service_name, config=self.config, endpoint_url=self.endpoint_url
|
|
156
78
|
)
|
|
157
|
-
|
|
158
79
|
return self.__client
|
|
159
80
|
|
|
160
81
|
@property
|
|
161
82
|
def resource(self) -> Any:
|
|
162
|
-
"""Return the boto3 resource connection."""
|
|
163
83
|
if not self.__resource:
|
|
164
|
-
logger.debug(f"Creating {self.service_name} resource")
|
|
165
84
|
self.__resource = self.__session.resource(
|
|
166
|
-
self.service_name,
|
|
167
|
-
config=self.config,
|
|
168
|
-
endpoint_url=self.endpoint_url,
|
|
85
|
+
self.service_name, config=self.config, endpoint_url=self.endpoint_url
|
|
169
86
|
)
|
|
170
87
|
return self.__resource
|
|
171
|
-
|
|
172
|
-
def __create_boto3_session(self) -> boto3.Session | None:
|
|
173
|
-
try:
|
|
174
|
-
logger.debug(f"Creating session for {self.service_name}")
|
|
175
|
-
session = boto3.Session(
|
|
176
|
-
profile_name=self.aws_profile,
|
|
177
|
-
region_name=self.aws_region,
|
|
178
|
-
aws_access_key_id=self.aws_access_key_id,
|
|
179
|
-
aws_secret_access_key=self.aws_secret_access_key,
|
|
180
|
-
aws_session_token=self.aws_session_token,
|
|
181
|
-
)
|
|
182
|
-
return session
|
|
183
|
-
except ProfileNotFound as e:
|
|
184
|
-
print(
|
|
185
|
-
f"An error occurred setting up the boto3 sessions. Profile not found: {e}"
|
|
186
|
-
)
|
|
187
|
-
raise e
|
|
188
|
-
except Exception as e:
|
|
189
|
-
print(f"An error occurred setting up the boto3 sessions: {e}")
|
|
190
|
-
raise e
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Geek Cafe, LLC
|
|
3
|
+
Maintainers: Eric Wilson
|
|
4
|
+
MIT License. See Project Root for the license information.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import boto3
|
|
8
|
+
from typing import List
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class RoleAssumptionMixin:
|
|
12
|
+
def _assume_roles_in_chain(
|
|
13
|
+
self,
|
|
14
|
+
base_session: boto3.Session,
|
|
15
|
+
role_chain: List[str],
|
|
16
|
+
session_name: str,
|
|
17
|
+
duration_seconds: int,
|
|
18
|
+
region: str,
|
|
19
|
+
) -> boto3.Session:
|
|
20
|
+
session = base_session
|
|
21
|
+
|
|
22
|
+
for role_arn in role_chain:
|
|
23
|
+
sts_client = session.client("sts")
|
|
24
|
+
response = sts_client.assume_role(
|
|
25
|
+
RoleArn=role_arn,
|
|
26
|
+
RoleSessionName=session_name,
|
|
27
|
+
DurationSeconds=duration_seconds,
|
|
28
|
+
)
|
|
29
|
+
creds = response["Credentials"]
|
|
30
|
+
|
|
31
|
+
session = boto3.Session(
|
|
32
|
+
aws_access_key_id=creds["AccessKeyId"],
|
|
33
|
+
aws_secret_access_key=creds["SecretAccessKey"],
|
|
34
|
+
aws_session_token=creds["SessionToken"],
|
|
35
|
+
region_name=region,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
return session
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Geek Cafe, LLC
|
|
3
|
+
Maintainers: Eric Wilson
|
|
4
|
+
MIT License. See Project Root for the license information.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import boto3
|
|
8
|
+
from typing import Optional
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class SessionSetupMixin:
|
|
12
|
+
def _create_base_session(
|
|
13
|
+
self,
|
|
14
|
+
aws_profile: Optional[str],
|
|
15
|
+
aws_region: Optional[str],
|
|
16
|
+
aws_access_key_id: Optional[str],
|
|
17
|
+
aws_secret_access_key: Optional[str],
|
|
18
|
+
aws_session_token: Optional[str],
|
|
19
|
+
) -> boto3.Session:
|
|
20
|
+
try:
|
|
21
|
+
return boto3.Session(
|
|
22
|
+
profile_name=aws_profile,
|
|
23
|
+
region_name=aws_region,
|
|
24
|
+
aws_access_key_id=aws_access_key_id,
|
|
25
|
+
aws_secret_access_key=aws_secret_access_key,
|
|
26
|
+
aws_session_token=aws_session_token,
|
|
27
|
+
)
|
|
28
|
+
except Exception as e:
|
|
29
|
+
raise RuntimeError(f"Failed to create boto3 session: {e}") from e
|
boto3_assist/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = '0.
|
|
1
|
+
__version__ = '0.13.0'
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
boto3_assist/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
boto3_assist/boto3session.py,sha256=
|
|
2
|
+
boto3_assist/boto3session.py,sha256=p4FKVSX5A-xNHdpRan8pgMoY4iIywNfwriyTfjQ-zTQ,2967
|
|
3
3
|
boto3_assist/connection.py,sha256=UJg6YHxVpz3F51Lih5cjfPhbkheRvXoJTpCilErNzkc,4523
|
|
4
4
|
boto3_assist/connection_tracker.py,sha256=UgfR9RlvXf3A4ssMr3gDMpw89ka8mSRvJn4M34SzhbU,4378
|
|
5
5
|
boto3_assist/http_status_codes.py,sha256=G0zRSWenwavYKETvDF9tNVUXQz3Ae2gXdBETYbjvJe8,3284
|
|
6
|
-
boto3_assist/
|
|
6
|
+
boto3_assist/role_assumption_mixin.py,sha256=PMUU5yC2FUBjFD1UokVkRY3CPB5zTw85AhIB5BMtbc8,1031
|
|
7
|
+
boto3_assist/session_setup_mixin.py,sha256=KgHOf560f2W_Qj04mnu4CiGHXAI_irjmQeEfhAJN3kA,865
|
|
8
|
+
boto3_assist/version.py,sha256=8jbyfDafOI8eZRtXgKR6mD8oxCBRAURo9UJ6grdsnZU,23
|
|
7
9
|
boto3_assist/aws_lambda/event_info.py,sha256=OkZ4WzuGaHEu_T8sB188KBgShAJhZpWASALKRGBOhMg,14648
|
|
8
10
|
boto3_assist/aws_lambda/mock_context.py,sha256=LPjHP-3YSoY6iPl1kPqJDwSVf1zLNTcukUunDtYcbK0,116
|
|
9
11
|
boto3_assist/cloudwatch/cloudwatch_connection.py,sha256=mnGWaLSQpHh5EeY7Ek_2o9JKHJxOELIYtQVMX1IaHn4,2480
|
|
@@ -53,8 +55,8 @@ boto3_assist/utilities/logging_utility.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5N
|
|
|
53
55
|
boto3_assist/utilities/numbers_utility.py,sha256=wzv9d0uXT_2_ZHHio7LBzibwxPqhGpvbq9HinrVn_4A,10160
|
|
54
56
|
boto3_assist/utilities/serialization_utility.py,sha256=nieqW9b71Dr0X2HPsNmCei6zoIbsPRl9fDAigBQkaUg,21730
|
|
55
57
|
boto3_assist/utilities/string_utility.py,sha256=0ChxbuT37xdG4y3cKzbNTHk4T3fl8lNMdOT7L5aJBQk,10382
|
|
56
|
-
boto3_assist-0.
|
|
57
|
-
boto3_assist-0.
|
|
58
|
-
boto3_assist-0.
|
|
59
|
-
boto3_assist-0.
|
|
60
|
-
boto3_assist-0.
|
|
58
|
+
boto3_assist-0.13.0.dist-info/METADATA,sha256=gLgFlW_mfJdcOGYgYtXdSFA7CgxdVRNg-kO-kwU2isA,2875
|
|
59
|
+
boto3_assist-0.13.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
60
|
+
boto3_assist-0.13.0.dist-info/licenses/LICENSE-EXPLAINED.txt,sha256=WFREvTpfTjPjDHpOLADxJpCKpIla3Ht87RUUGii4ODU,606
|
|
61
|
+
boto3_assist-0.13.0.dist-info/licenses/LICENSE.txt,sha256=PXDhFWS5L5aOTkVhNvoitHKbAkgxqMI2uUPQyrnXGiI,1105
|
|
62
|
+
boto3_assist-0.13.0.dist-info/RECORD,,
|
|
File without changes
|
{boto3_assist-0.12.0.dist-info → boto3_assist-0.13.0.dist-info}/licenses/LICENSE-EXPLAINED.txt
RENAMED
|
File without changes
|
|
File without changes
|