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.
@@ -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 Any, Optional
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 botocore.exceptions import ProfileNotFound
13
- from boto3_assist.environment_services.environment_variables import EnvironmentVariables
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
- # cross_account_role_arn: Optional[str] = None,
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: Any = None
47
+ self.__session: Optional[boto3.Session] = None
50
48
  self.__client: Any = None
51
49
  self.__resource: Any = None
52
50
 
53
- self.__setup()
54
-
55
- def __setup(self):
56
- """Setup AWS session, client, and resource."""
57
-
58
- profile = self.aws_profile or EnvironmentVariables.AWS.profile()
59
- region = self.aws_region or EnvironmentVariables.AWS.region()
60
-
61
- logger.debug("Connecting without assuming a role.")
62
- self.__session = self.__get_aws_session(profile, region)
63
-
64
- if profile:
65
- print(f"Connecting with a profile: {profile}")
66
-
67
- if self.assume_role_arn:
68
- self.__assume_role()
69
-
70
- def __assume_role(self):
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
- logger.debug("Creating boto3 session")
136
- session = self.__create_boto3_session()
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.12.0'
1
+ __version__ = '0.13.0'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boto3_assist
3
- Version: 0.12.0
3
+ Version: 0.13.0
4
4
  Summary: Additional boto3 wrappers to make your life a little easier
5
5
  Author-email: Eric Wilson <boto3-assist@geekcafe.com>
6
6
  License-File: LICENSE-EXPLAINED.txt
@@ -1,9 +1,11 @@
1
1
  boto3_assist/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- boto3_assist/boto3session.py,sha256=eXmsOXsQoXaVnis6hiTXwNaRA6Vnjvj7sZnMUGRsrdU,6965
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/version.py,sha256=qHJ_q-NtoZ98rdflBB5GKtBzx_sUvAVe96rJSun_DEU,23
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.12.0.dist-info/METADATA,sha256=Lxa_QRidcIM16fqlmi0IQpW7CPBnWrphIktDAUuAvKc,2875
57
- boto3_assist-0.12.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
58
- boto3_assist-0.12.0.dist-info/licenses/LICENSE-EXPLAINED.txt,sha256=WFREvTpfTjPjDHpOLADxJpCKpIla3Ht87RUUGii4ODU,606
59
- boto3_assist-0.12.0.dist-info/licenses/LICENSE.txt,sha256=PXDhFWS5L5aOTkVhNvoitHKbAkgxqMI2uUPQyrnXGiI,1105
60
- boto3_assist-0.12.0.dist-info/RECORD,,
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,,