boto3-assist 0.11.0__tar.gz → 0.12.0__tar.gz
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-0.11.0 → boto3_assist-0.12.0}/PKG-INFO +1 -1
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/pyproject.toml +5 -1
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/boto3session.py +23 -13
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/connection.py +3 -1
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/dynamodb/dynamodb.py +2 -4
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/dynamodb/dynamodb_connection.py +2 -0
- boto3_assist-0.12.0/src/boto3_assist/version.py +1 -0
- boto3_assist-0.12.0/tests/integration/cross_account_connection_test.py +78 -0
- boto3_assist-0.12.0/tests/integration/tenant.py +185 -0
- boto3_assist-0.12.0/tests/integration/tenant_services.py +48 -0
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/dynamodb_tests/dbmodels/cms/content_block.py +1 -1
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/dynamodb_tests/dbmodels/cms/page.py +1 -1
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/dynamodb_tests/dbmodels/cms/template.py +1 -1
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/dynamodb_tests/dynamodb_model_base_test.py +1 -1
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/dynamodb_tests/dynamodb_model_projections_test.py +2 -2
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/dynamodb_tests/dynamodb_model_serializtion_test.py +2 -2
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/dynamodb_tests/dynamodb_moto_sorting_test.py +1 -1
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/models_tests/serializable_model_person_test.py +1 -3
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/models_tests/serializable_model_user_test.py +1 -1
- boto3_assist-0.11.0/src/boto3_assist/version.py +0 -1
- boto3_assist-0.11.0/tests/__top/__init__.py +0 -25
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/.env.docker +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/.env.docker.001 +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/.env.docker.nosql.workbench +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/.env.unittest +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/.gitignore +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/.vscode/launch.json +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/.vscode/settings.json +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/.vscode/tasks.json +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/LICENSE-EXPLAINED.txt +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/LICENSE.txt +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/README.md +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/aws_regions_with_status.csv +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/aws_regions_with_status.json +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/devops/build.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/devops/readme.md +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/examples/__init__.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/examples/cloudwatch/log_report.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/examples/dynamodb/models/order_item_model.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/examples/dynamodb/models/order_model.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/examples/dynamodb/models/product_model.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/examples/dynamodb/models/user_model.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/examples/dynamodb/models/user_post_model.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/examples/dynamodb/order_example/main.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/examples/dynamodb/order_example/products.json +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/examples/dynamodb/services/order_item_service.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/examples/dynamodb/services/order_service.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/examples/dynamodb/services/product_service.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/examples/dynamodb/services/table_service.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/examples/dynamodb/services/user_post_service.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/examples/dynamodb/services/user_service.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/examples/dynamodb/services/user_service_client_example.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/examples/dynamodb/services/user_service_resource_example.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/examples/dynamodb/user_post_example/main.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/examples/ec2/regions_report.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/module-headers.txt +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/mypy.ini +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/requirements-dev.txt +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/requirements.txt +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/run-checks.sh +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/run_unit_tests.sh +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/__init__.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/aws_lambda/event_info.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/aws_lambda/mock_context.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/cloudwatch/cloudwatch_connection.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/cloudwatch/cloudwatch_connection_tracker.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/cloudwatch/cloudwatch_log_connection.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/cloudwatch/cloudwatch_logs.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/cloudwatch/cloudwatch_query.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/cognito/cognito_authorizer.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/cognito/cognito_connection.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/cognito/cognito_utility.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/cognito/jwks_cache.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/cognito/user.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/connection_tracker.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/dynamodb/dynamodb_helpers.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/dynamodb/dynamodb_importer.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/dynamodb/dynamodb_index.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/dynamodb/dynamodb_iservice.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/dynamodb/dynamodb_key.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/dynamodb/dynamodb_model_base.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/dynamodb/dynamodb_model_base_interfaces.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/dynamodb/dynamodb_reindexer.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/dynamodb/dynamodb_reserved_words.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/dynamodb/dynamodb_reserved_words.txt +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/dynamodb/readme.md +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/dynamodb/troubleshooting.md +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/ec2/ec2_connection.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/environment_services/__init__.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/environment_services/environment_loader.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/environment_services/environment_variables.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/errors/custom_exceptions.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/http_status_codes.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/models/serializable_model.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/s3/s3.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/s3/s3_bucket.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/s3/s3_connection.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/s3/s3_event_data.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/s3/s3_object.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/securityhub/securityhub.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/securityhub/securityhub_connection.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/ssm/connection.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/ssm/parameter_store/parameter_store.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/utilities/datetime_utility.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/utilities/dictionary_utility.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/utilities/file_operations.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/utilities/http_utility.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/utilities/logging_utility.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/utilities/numbers_utility.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/utilities/serialization_utility.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/utilities/string_utility.py +0 -0
- {boto3_assist-0.11.0 → boto3_assist-0.12.0}/tests/__init__.py +0 -0
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/dynamodb_tests/__init__.py +0 -0
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/dynamodb_tests/dbmodels/cms/base.py +0 -0
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/dynamodb_tests/dbmodels/simple_model.py +0 -0
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/dynamodb_tests/dbmodels/user_model.py +0 -0
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/dynamodb_tests/dbmodels/user_required_fields_model.py +0 -0
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/dynamodb_tests/dynamodb_reindex_test.py +0 -0
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/examples_test/__init__.py +0 -0
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/examples_test/user_service_test.py +0 -0
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/lambda_tests/__init__.py +0 -0
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/lambda_tests/event_info_test.py +0 -0
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/models_tests/__init__.py +0 -0
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/models_tests/models/person.py +0 -0
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/models_tests/models/user.py +0 -0
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/models_tests/serializable_model_wide_test.py +0 -0
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/parameter_store/__init__.py +0 -0
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/parameter_store/parameter_store_test.py +0 -0
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/s3/__init__.py +0 -0
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/s3/files/test.txt +0 -0
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/s3/s3_event_data_test.py +0 -0
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/s3/s3_file_delete_test.py +0 -0
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/s3/s3_file_upload_test.py +0 -0
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/utilities/__init__.py +0 -0
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/utilities/serialization_utility_test.py +0 -0
- {boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/utilities/string_utility_test.py +0 -0
|
@@ -8,10 +8,14 @@ packages = ["src/boto3_assist"]
|
|
|
8
8
|
[tool.pytest.ini_options]
|
|
9
9
|
pythonpath = ["src"]
|
|
10
10
|
testpaths = ["tests"]
|
|
11
|
+
markers = [
|
|
12
|
+
"integration: marks tests as integration (deselect with '-m \"not integration\"')"
|
|
13
|
+
]
|
|
14
|
+
addopts = "-m 'not integration'"
|
|
11
15
|
|
|
12
16
|
[project]
|
|
13
17
|
name = "boto3_assist"
|
|
14
|
-
version = "0.
|
|
18
|
+
version = "0.12.0"
|
|
15
19
|
|
|
16
20
|
authors = [
|
|
17
21
|
{ name="Eric Wilson", email="boto3-assist@geekcafe.com" }
|
|
@@ -27,7 +27,7 @@ class Boto3SessionManager:
|
|
|
27
27
|
aws_region: Optional[str] = None,
|
|
28
28
|
assume_role_arn: Optional[str] = None,
|
|
29
29
|
assume_role_session_name: Optional[str] = None,
|
|
30
|
-
cross_account_role_arn: Optional[str] = None,
|
|
30
|
+
# cross_account_role_arn: Optional[str] = None,
|
|
31
31
|
config: Optional[Config] = None,
|
|
32
32
|
aws_endpoint_url: Optional[str] = None,
|
|
33
33
|
aws_access_key_id: Optional[str] = None,
|
|
@@ -40,7 +40,7 @@ class Boto3SessionManager:
|
|
|
40
40
|
self.assume_role_arn = assume_role_arn
|
|
41
41
|
self.assume_role_session_name = assume_role_session_name
|
|
42
42
|
self.config = config
|
|
43
|
-
self.cross_account_role_arn = cross_account_role_arn
|
|
43
|
+
# # self.cross_account_role_arn = cross_account_role_arn
|
|
44
44
|
self.endpoint_url = aws_endpoint_url
|
|
45
45
|
self.aws_access_key_id = aws_access_key_id
|
|
46
46
|
self.aws_secret_access_key = aws_secret_access_key
|
|
@@ -57,36 +57,46 @@ class Boto3SessionManager:
|
|
|
57
57
|
|
|
58
58
|
profile = self.aws_profile or EnvironmentVariables.AWS.profile()
|
|
59
59
|
region = self.aws_region or EnvironmentVariables.AWS.region()
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
logger.debug("Connecting without assuming a role.")
|
|
64
|
-
self.__session = self.__get_aws_session(profile, region)
|
|
60
|
+
|
|
61
|
+
logger.debug("Connecting without assuming a role.")
|
|
62
|
+
self.__session = self.__get_aws_session(profile, region)
|
|
65
63
|
|
|
66
64
|
if profile:
|
|
67
65
|
print(f"Connecting with a profile: {profile}")
|
|
68
66
|
|
|
67
|
+
if self.assume_role_arn:
|
|
68
|
+
self.__assume_role()
|
|
69
|
+
|
|
69
70
|
def __assume_role(self):
|
|
70
71
|
"""Assume an AWS IAM role."""
|
|
71
72
|
try:
|
|
73
|
+
if not self.__session:
|
|
74
|
+
raise RuntimeError(
|
|
75
|
+
"Session must be established before assuming a role."
|
|
76
|
+
)
|
|
77
|
+
|
|
72
78
|
logger.debug(f"Assuming role {self.assume_role_arn}")
|
|
73
|
-
|
|
79
|
+
|
|
80
|
+
sts_client = self.__session.client("sts")
|
|
74
81
|
session_name = (
|
|
75
82
|
self.assume_role_session_name
|
|
76
83
|
or f"AssumeRoleSessionFor{self.service_name}"
|
|
77
84
|
)
|
|
78
|
-
|
|
79
|
-
raise ValueError("assume_role_arn is required")
|
|
85
|
+
|
|
80
86
|
assumed_role_response = sts_client.assume_role(
|
|
81
87
|
RoleArn=self.assume_role_arn,
|
|
82
88
|
RoleSessionName=session_name,
|
|
83
89
|
)
|
|
84
90
|
credentials = assumed_role_response["Credentials"]
|
|
91
|
+
|
|
92
|
+
# Now override the session with assumed credentials
|
|
85
93
|
self.__session = boto3.Session(
|
|
86
94
|
aws_access_key_id=credentials["AccessKeyId"],
|
|
87
95
|
aws_secret_access_key=credentials["SecretAccessKey"],
|
|
88
96
|
aws_session_token=credentials["SessionToken"],
|
|
97
|
+
region_name=self.aws_region,
|
|
89
98
|
)
|
|
99
|
+
logger.debug("Successfully assumed role and created new session.")
|
|
90
100
|
|
|
91
101
|
except Exception as e:
|
|
92
102
|
logger.error(f"Error assuming role: {e}")
|
|
@@ -117,9 +127,9 @@ class Boto3SessionManager:
|
|
|
117
127
|
"region": self.aws_region,
|
|
118
128
|
"aws_access_key_id": tmp_access_key_id,
|
|
119
129
|
"aws_secret_access_key": tmp_secret_access_key,
|
|
120
|
-
"aws_session_token":
|
|
121
|
-
|
|
122
|
-
|
|
130
|
+
"aws_session_token": (
|
|
131
|
+
"*******" if self.aws_session_token is not None else ""
|
|
132
|
+
),
|
|
123
133
|
}
|
|
124
134
|
)
|
|
125
135
|
logger.debug("Creating boto3 session")
|
|
@@ -30,6 +30,7 @@ class Connection:
|
|
|
30
30
|
aws_access_key_id: Optional[str] = None,
|
|
31
31
|
aws_secret_access_key: Optional[str] = None,
|
|
32
32
|
aws_end_point_url: Optional[str] = None,
|
|
33
|
+
assume_role_arn: Optional[str] = None,
|
|
33
34
|
) -> None:
|
|
34
35
|
self.__aws_profile = aws_profile
|
|
35
36
|
self.__aws_region = aws_region
|
|
@@ -37,7 +38,7 @@ class Connection:
|
|
|
37
38
|
self.__aws_secret_access_key = aws_secret_access_key
|
|
38
39
|
self.end_point_url = aws_end_point_url
|
|
39
40
|
self.__session: Boto3SessionManager | None = None
|
|
40
|
-
|
|
41
|
+
self.__assume_role_arn: Optional[str] = assume_role_arn
|
|
41
42
|
self.__service_name: str | None = service_name
|
|
42
43
|
|
|
43
44
|
if self.__service_name is None:
|
|
@@ -73,6 +74,7 @@ class Connection:
|
|
|
73
74
|
aws_access_key_id=self.aws_access_key_id,
|
|
74
75
|
aws_secret_access_key=self.aws_secret_access_key,
|
|
75
76
|
aws_endpoint_url=self.end_point_url,
|
|
77
|
+
assume_role_arn=self.__assume_role_arn,
|
|
76
78
|
)
|
|
77
79
|
|
|
78
80
|
tracker.add(service_name=self.service_name)
|
|
@@ -24,7 +24,6 @@ from boto3_assist.utilities.string_utility import StringUtility
|
|
|
24
24
|
logger = Logger()
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
|
|
28
27
|
class DynamoDB(DynamoDBConnection):
|
|
29
28
|
"""
|
|
30
29
|
DynamoDB. Wrapper for basic DynamoDB Connection and Actions
|
|
@@ -41,6 +40,7 @@ class DynamoDB(DynamoDBConnection):
|
|
|
41
40
|
aws_end_point_url: Optional[str] = None,
|
|
42
41
|
aws_access_key_id: Optional[str] = None,
|
|
43
42
|
aws_secret_access_key: Optional[str] = None,
|
|
43
|
+
assume_role_arn: Optional[str] = None,
|
|
44
44
|
) -> None:
|
|
45
45
|
super().__init__(
|
|
46
46
|
aws_profile=aws_profile,
|
|
@@ -48,6 +48,7 @@ class DynamoDB(DynamoDBConnection):
|
|
|
48
48
|
aws_end_point_url=aws_end_point_url,
|
|
49
49
|
aws_access_key_id=aws_access_key_id,
|
|
50
50
|
aws_secret_access_key=aws_secret_access_key,
|
|
51
|
+
assume_role_arn=assume_role_arn,
|
|
51
52
|
)
|
|
52
53
|
self.helpers: DynamoDBHelpers = DynamoDBHelpers()
|
|
53
54
|
self.log_dynamodb_item_size = (
|
|
@@ -55,7 +56,6 @@ class DynamoDB(DynamoDBConnection):
|
|
|
55
56
|
)
|
|
56
57
|
logger.setLevel(os.getenv("LOG_LEVEL", "INFO"))
|
|
57
58
|
|
|
58
|
-
|
|
59
59
|
def save(
|
|
60
60
|
self,
|
|
61
61
|
item: dict | DynamoDBModelBase,
|
|
@@ -169,7 +169,6 @@ class DynamoDB(DynamoDBConnection):
|
|
|
169
169
|
call_type: str = "resource",
|
|
170
170
|
) -> Dict[str, Any]: ...
|
|
171
171
|
|
|
172
|
-
|
|
173
172
|
def get(
|
|
174
173
|
self,
|
|
175
174
|
key: Optional[dict] = None,
|
|
@@ -344,7 +343,6 @@ class DynamoDB(DynamoDBConnection):
|
|
|
344
343
|
) -> dict:
|
|
345
344
|
pass
|
|
346
345
|
|
|
347
|
-
|
|
348
346
|
def delete(
|
|
349
347
|
self,
|
|
350
348
|
*,
|
{boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/dynamodb/dynamodb_connection.py
RENAMED
|
@@ -32,6 +32,7 @@ class DynamoDBConnection(Connection):
|
|
|
32
32
|
aws_end_point_url: Optional[str] = None,
|
|
33
33
|
aws_access_key_id: Optional[str] = None,
|
|
34
34
|
aws_secret_access_key: Optional[str] = None,
|
|
35
|
+
assume_role_arn: Optional[str] = None,
|
|
35
36
|
) -> None:
|
|
36
37
|
super().__init__(
|
|
37
38
|
service_name="dynamodb",
|
|
@@ -40,6 +41,7 @@ class DynamoDBConnection(Connection):
|
|
|
40
41
|
aws_access_key_id=aws_access_key_id,
|
|
41
42
|
aws_secret_access_key=aws_secret_access_key,
|
|
42
43
|
aws_end_point_url=aws_end_point_url,
|
|
44
|
+
assume_role_arn=assume_role_arn,
|
|
43
45
|
)
|
|
44
46
|
|
|
45
47
|
self.__dynamodb_client: DynamoDBClient | None = None
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '0.12.0'
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
import os
|
|
3
|
+
from typing import List
|
|
4
|
+
from boto3_assist.dynamodb.dynamodb import DynamoDB
|
|
5
|
+
from tests.integration.tenant_services import TenantServices
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@pytest.mark.integration
|
|
9
|
+
def test_cross_account_role_assumption_with_profile():
|
|
10
|
+
responses = []
|
|
11
|
+
|
|
12
|
+
profile_name = os.getenv("AWS_PROFILE")
|
|
13
|
+
|
|
14
|
+
connections: List[dict] = [
|
|
15
|
+
{
|
|
16
|
+
"profile_name": profile_name,
|
|
17
|
+
"aws_account": "959096737760",
|
|
18
|
+
"aws_region": "us-east-1",
|
|
19
|
+
"role_name": "CrossAccountAccessRole",
|
|
20
|
+
"table_name": "db-us-east-1",
|
|
21
|
+
"enabled": False,
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"profile_name": profile_name,
|
|
25
|
+
"aws_account": "959096737760",
|
|
26
|
+
"aws_region": "eu-west-2",
|
|
27
|
+
"role_name": "CrossAccountAccessRole",
|
|
28
|
+
"table_name": "db-eu-west-2",
|
|
29
|
+
"enabled": False,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"profile_name": profile_name,
|
|
33
|
+
"aws_account": "257932641017",
|
|
34
|
+
"aws_region": "us-east-1",
|
|
35
|
+
"role_name": "CrossAccountAccessRole",
|
|
36
|
+
"table_name": "aplos-nca-saas-production-demo-001-database",
|
|
37
|
+
"enabled": True,
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"profile_name": profile_name,
|
|
41
|
+
"aws_region": "us-east-1",
|
|
42
|
+
"aws_account": "211125601483",
|
|
43
|
+
"role_name": "CrossAccountAccessRole",
|
|
44
|
+
"table_name": "aplos-nca-saas-production-app-database",
|
|
45
|
+
"enabled": True,
|
|
46
|
+
},
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
for connection in connections:
|
|
50
|
+
role_arn = (
|
|
51
|
+
f"arn:aws:iam::{connection['aws_account']}:role/{connection['role_name']}"
|
|
52
|
+
)
|
|
53
|
+
if connection["enabled"]:
|
|
54
|
+
db = DynamoDB(
|
|
55
|
+
aws_profile=connection["profile_name"],
|
|
56
|
+
aws_region=connection["aws_region"],
|
|
57
|
+
assume_role_arn=role_arn,
|
|
58
|
+
)
|
|
59
|
+
ts: TenantServices = TenantServices(
|
|
60
|
+
db=db, table_name=connection["table_name"]
|
|
61
|
+
)
|
|
62
|
+
response = ts.list()
|
|
63
|
+
responses.append(response)
|
|
64
|
+
# print(response)
|
|
65
|
+
else:
|
|
66
|
+
responses.append(None)
|
|
67
|
+
|
|
68
|
+
print(len(responses))
|
|
69
|
+
assert len(responses) == 3
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def main():
|
|
73
|
+
test_cross_account_role_assumption_with_profile()
|
|
74
|
+
pass
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
if __name__ == "__main__":
|
|
78
|
+
main()
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tenant Model
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import datetime
|
|
6
|
+
from typing import Optional, Literal
|
|
7
|
+
from boto3_assist.dynamodb.dynamodb_index import (
|
|
8
|
+
DynamoDBIndex,
|
|
9
|
+
DynamoDBKey,
|
|
10
|
+
)
|
|
11
|
+
from boto3_assist.dynamodb.dynamodb_model_base import (
|
|
12
|
+
DynamoDBModelBase,
|
|
13
|
+
exclude_from_serialization,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
from boto3_assist.utilities.datetime_utility import DatetimeUtility
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class Tenant(DynamoDBModelBase):
|
|
20
|
+
"""Database Model for the Tenant Entity"""
|
|
21
|
+
|
|
22
|
+
def __init__(
|
|
23
|
+
self,
|
|
24
|
+
id: Optional[str] = None, # pylint: disable=w0622
|
|
25
|
+
) -> None:
|
|
26
|
+
super().__init__()
|
|
27
|
+
self.id: Optional[str] = id
|
|
28
|
+
self.name: Optional[str] = None
|
|
29
|
+
self.email: Optional[str] = None
|
|
30
|
+
self.subscription_id: Optional[str] = None
|
|
31
|
+
self.type: Optional[str] = None
|
|
32
|
+
self.__status: Optional[str] = None
|
|
33
|
+
self.status_message: str = ""
|
|
34
|
+
self.company_name: Optional[str] = None
|
|
35
|
+
self.created_utc: datetime.datetime = DatetimeUtility.get_utc_now()
|
|
36
|
+
self.modified_utc: datetime.datetime = DatetimeUtility.get_utc_now()
|
|
37
|
+
self.reindexed_utc: Optional[datetime.datetime] = None
|
|
38
|
+
self.__onboard_utc: Optional[datetime.datetime] = None
|
|
39
|
+
self.__setup_indexes()
|
|
40
|
+
|
|
41
|
+
def __setup_indexes(self):
|
|
42
|
+
self.indexes.add_primary(
|
|
43
|
+
DynamoDBIndex(
|
|
44
|
+
index_name="primary",
|
|
45
|
+
partition_key=DynamoDBKey(
|
|
46
|
+
attribute_name="pk",
|
|
47
|
+
value=lambda: f"tenant#{self.id if self.id else ''}",
|
|
48
|
+
),
|
|
49
|
+
sort_key=DynamoDBKey(
|
|
50
|
+
attribute_name="sk",
|
|
51
|
+
value=lambda: f"tenant#{self.id if self.id else ''}",
|
|
52
|
+
),
|
|
53
|
+
)
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
self.indexes.add_secondary(
|
|
57
|
+
DynamoDBIndex(
|
|
58
|
+
index_name="gsi0",
|
|
59
|
+
partition_key=DynamoDBKey(
|
|
60
|
+
attribute_name="gsi0_pk",
|
|
61
|
+
value="tenants#",
|
|
62
|
+
),
|
|
63
|
+
sort_key=DynamoDBKey(
|
|
64
|
+
attribute_name="gsi0_sk",
|
|
65
|
+
value=lambda: f"name#{self.__sort_name if self.__sort_name else ''}",
|
|
66
|
+
),
|
|
67
|
+
)
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
self.indexes.add_secondary(
|
|
71
|
+
DynamoDBIndex(
|
|
72
|
+
index_name="gsi1",
|
|
73
|
+
partition_key=DynamoDBKey(
|
|
74
|
+
attribute_name="gsi1_pk",
|
|
75
|
+
value="tenants#",
|
|
76
|
+
),
|
|
77
|
+
sort_key=DynamoDBKey(
|
|
78
|
+
attribute_name="gsi1_sk",
|
|
79
|
+
value=lambda: (
|
|
80
|
+
f"status#{self.status if self.status else ''}"
|
|
81
|
+
f"name#{self.__sort_name if self.__sort_name else ''}"
|
|
82
|
+
),
|
|
83
|
+
),
|
|
84
|
+
)
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
self.indexes.add_secondary(
|
|
88
|
+
DynamoDBIndex(
|
|
89
|
+
index_name="gsi2",
|
|
90
|
+
partition_key=DynamoDBKey(
|
|
91
|
+
attribute_name="gsi2_pk",
|
|
92
|
+
value="tenants#",
|
|
93
|
+
),
|
|
94
|
+
sort_key=DynamoDBKey(
|
|
95
|
+
attribute_name="gsi2_sk",
|
|
96
|
+
value=lambda: f"onboard-ts#{self.onboard_utc.timestamp() if self.onboard_utc else ''}",
|
|
97
|
+
),
|
|
98
|
+
)
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
@property
|
|
102
|
+
@exclude_from_serialization
|
|
103
|
+
def modifed_date(self) -> Optional[str]:
|
|
104
|
+
"""Backward compatibale db model for modified date"""
|
|
105
|
+
return str(self.modified_utc)
|
|
106
|
+
|
|
107
|
+
@modifed_date.setter
|
|
108
|
+
def modifed_date(self, value: Optional[str]) -> None:
|
|
109
|
+
v = DatetimeUtility.to_datetime_utc(value=value)
|
|
110
|
+
|
|
111
|
+
self.modified_utc = v or DatetimeUtility.get_utc_now()
|
|
112
|
+
|
|
113
|
+
@property
|
|
114
|
+
@exclude_from_serialization
|
|
115
|
+
def onboarding_date(self) -> Optional[str]:
|
|
116
|
+
"""Backward compatibale db model for modified date"""
|
|
117
|
+
return str(self.onboard_utc)
|
|
118
|
+
|
|
119
|
+
@onboarding_date.setter
|
|
120
|
+
def onboarding_date(self, value: Optional[str]) -> None:
|
|
121
|
+
self.onboard_utc = DatetimeUtility.to_datetime_utc(value=value)
|
|
122
|
+
|
|
123
|
+
@property
|
|
124
|
+
@exclude_from_serialization
|
|
125
|
+
def email_address(self) -> Optional[str]:
|
|
126
|
+
"""Backward compatibale db model for email address"""
|
|
127
|
+
return self.email
|
|
128
|
+
|
|
129
|
+
@email_address.setter
|
|
130
|
+
def email_address(self, value: Optional[str]) -> None:
|
|
131
|
+
self.email = value
|
|
132
|
+
|
|
133
|
+
@property
|
|
134
|
+
def onboard_utc(self) -> Optional[datetime.datetime]:
|
|
135
|
+
"""The UTC date and time the user was onboarded"""
|
|
136
|
+
return DatetimeUtility.to_datetime_utc(self.__onboard_utc)
|
|
137
|
+
|
|
138
|
+
@onboard_utc.setter
|
|
139
|
+
def onboard_utc(self, value: Optional[datetime.datetime]) -> None:
|
|
140
|
+
self.__onboard_utc = DatetimeUtility.to_datetime_utc(
|
|
141
|
+
value=value, default=DatetimeUtility.get_utc_now()
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
@property
|
|
145
|
+
def status(self) -> Optional[Literal["enabled", "disabled", "locked"]]:
|
|
146
|
+
"""The status of the tenant"""
|
|
147
|
+
|
|
148
|
+
return self.__status
|
|
149
|
+
|
|
150
|
+
@status.setter
|
|
151
|
+
def status(self, value: Optional[Literal["enabled", "disabled", "locked"]]) -> None:
|
|
152
|
+
if value is not None:
|
|
153
|
+
value = str(value).lower()
|
|
154
|
+
|
|
155
|
+
self.__status = value
|
|
156
|
+
|
|
157
|
+
@property
|
|
158
|
+
def __sort_name(self) -> Optional[str]:
|
|
159
|
+
if self.name is None:
|
|
160
|
+
return None
|
|
161
|
+
else:
|
|
162
|
+
return self.name.lower()
|
|
163
|
+
|
|
164
|
+
@property
|
|
165
|
+
def record_type(self) -> str:
|
|
166
|
+
"""
|
|
167
|
+
The type of record we are storing to help load the
|
|
168
|
+
correct object at runtime if needed.
|
|
169
|
+
"""
|
|
170
|
+
name = __name__.rsplit(".", maxsplit=1)[-1]
|
|
171
|
+
return name
|
|
172
|
+
|
|
173
|
+
@record_type.setter
|
|
174
|
+
def record_type(self, value: str) -> None:
|
|
175
|
+
pass
|
|
176
|
+
|
|
177
|
+
@property
|
|
178
|
+
def subscription(self) -> dict | None:
|
|
179
|
+
"""The tenants current subscription - if bound to one"""
|
|
180
|
+
return self.__subscription
|
|
181
|
+
|
|
182
|
+
@subscription.setter
|
|
183
|
+
def subscription(self, value: dict) -> None:
|
|
184
|
+
|
|
185
|
+
self.__subscription = value
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
from .tenant import Tenant
|
|
3
|
+
from boto3_assist.dynamodb.dynamodb import DynamoDB
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TenantServices:
|
|
7
|
+
|
|
8
|
+
def __init__(self, db: DynamoDB, table_name: str) -> None:
|
|
9
|
+
self.db: DynamoDB = db or DynamoDB()
|
|
10
|
+
self.table_name: str = table_name
|
|
11
|
+
|
|
12
|
+
def list(
|
|
13
|
+
self,
|
|
14
|
+
*,
|
|
15
|
+
status: Optional[str] = None,
|
|
16
|
+
ascending: bool = True,
|
|
17
|
+
do_projections: bool = False,
|
|
18
|
+
strongly_consistent: bool = False,
|
|
19
|
+
start_key: Optional[dict] = None,
|
|
20
|
+
) -> dict:
|
|
21
|
+
"""
|
|
22
|
+
List all Tenants within an optional status (enabled or )
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
start_key (Optional[str]): A start key for paged results.
|
|
26
|
+
do_projections (bool, optional): Determines if we do projections or not. Defaults to False.
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
dict: DynamoDB response dictionary
|
|
30
|
+
"""
|
|
31
|
+
model: Tenant = Tenant()
|
|
32
|
+
index_name: str = "gsi0"
|
|
33
|
+
if status:
|
|
34
|
+
model.status = status
|
|
35
|
+
index_name = "gsi1"
|
|
36
|
+
key = model.get_key(index_name).key()
|
|
37
|
+
response = self.db.query_by_criteria(
|
|
38
|
+
model=model,
|
|
39
|
+
index_name=index_name,
|
|
40
|
+
key=key,
|
|
41
|
+
start_key=start_key,
|
|
42
|
+
do_projections=do_projections,
|
|
43
|
+
table_name=self.table_name,
|
|
44
|
+
strongly_consistent=strongly_consistent,
|
|
45
|
+
ascending=ascending,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
return response
|
|
@@ -7,7 +7,7 @@ MIT License. See Project Root for the license information.
|
|
|
7
7
|
import datetime as dt
|
|
8
8
|
from boto3_assist.dynamodb.dynamodb_index import DynamoDBIndex, DynamoDBKey
|
|
9
9
|
from boto3_assist.utilities.string_utility import StringUtility
|
|
10
|
-
from tests.dynamodb_tests.models.cms.base import BaseCMSDBModel
|
|
10
|
+
from tests.unit.dynamodb_tests.models.cms.base import BaseCMSDBModel
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class ContentBlock(BaseCMSDBModel):
|
{boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/dynamodb_tests/dbmodels/cms/page.py
RENAMED
|
@@ -7,7 +7,7 @@ MIT License. See Project Root for the license information.
|
|
|
7
7
|
from typing import List, Dict, Any
|
|
8
8
|
import datetime as dt
|
|
9
9
|
from boto3_assist.dynamodb.dynamodb_index import DynamoDBIndex, DynamoDBKey
|
|
10
|
-
from tests.dynamodb_tests.dbmodels.cms.base import BaseCMSDBModel
|
|
10
|
+
from tests.unit.dynamodb_tests.dbmodels.cms.base import BaseCMSDBModel
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class Page(BaseCMSDBModel):
|
{boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/dynamodb_tests/dbmodels/cms/template.py
RENAMED
|
@@ -6,7 +6,7 @@ MIT License. See Project Root for the license information.
|
|
|
6
6
|
|
|
7
7
|
from typing import List
|
|
8
8
|
from boto3_assist.dynamodb.dynamodb_index import DynamoDBIndex, DynamoDBKey
|
|
9
|
-
from tests.dynamodb_tests.
|
|
9
|
+
from tests.unit.dynamodb_tests.dbmodels.cms.base import BaseCMSDBModel
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class Template(BaseCMSDBModel):
|
|
@@ -9,7 +9,7 @@ from typing import Dict, List
|
|
|
9
9
|
|
|
10
10
|
from boto3_assist.dynamodb.dynamodb_index import DynamoDBIndex
|
|
11
11
|
from boto3_assist.dynamodb.dynamodb_key import DynamoDBKey
|
|
12
|
-
from tests.dynamodb_tests.dbmodels.user_model import User
|
|
12
|
+
from tests.unit.dynamodb_tests.dbmodels.user_model import User
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class DynamoDBModelUnitTest(unittest.TestCase):
|
|
@@ -7,8 +7,8 @@ MIT License. See Project Root for the license information.
|
|
|
7
7
|
import unittest
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
from tests.dynamodb_tests.dbmodels.user_model import User
|
|
11
|
-
from tests.dynamodb_tests.dbmodels.simple_model import Simple
|
|
10
|
+
from tests.unit.dynamodb_tests.dbmodels.user_model import User
|
|
11
|
+
from tests.unit.dynamodb_tests.dbmodels.simple_model import Simple
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class DynamoDBModeProjectionlUnitTest(unittest.TestCase):
|
|
@@ -7,8 +7,8 @@ MIT License. See Project Root for the license information.
|
|
|
7
7
|
import unittest
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
from tests.dynamodb_tests.dbmodels.user_model import User
|
|
11
|
-
from tests.dynamodb_tests.dbmodels.user_required_fields_model import User as User2
|
|
10
|
+
from tests.unit.dynamodb_tests.dbmodels.user_model import User
|
|
11
|
+
from tests.unit.dynamodb_tests.dbmodels.user_required_fields_model import User as User2
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class DynamoDBModelSerializationUnitTest(unittest.TestCase):
|
|
@@ -12,7 +12,7 @@ from mypy_boto3_dynamodb import DynamoDBClient
|
|
|
12
12
|
|
|
13
13
|
from boto3_assist.dynamodb.dynamodb import DynamoDB
|
|
14
14
|
from boto3_assist.environment_services.environment_loader import EnvironmentLoader
|
|
15
|
-
from tests.dynamodb_tests.dbmodels.cms.page import Page
|
|
15
|
+
from tests.unit.dynamodb_tests.dbmodels.cms.page import Page
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
@moto.mock_aws
|
|
@@ -7,9 +7,7 @@ MIT License. See Project Root for the license information.
|
|
|
7
7
|
import unittest
|
|
8
8
|
from typing import Dict, List
|
|
9
9
|
from boto3_assist.models.serializable_model import SerializableModel
|
|
10
|
-
from tests.models_tests.models.person import Person
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
from tests.unit.models_tests.models.person import Person
|
|
13
11
|
|
|
14
12
|
|
|
15
13
|
class TestSerializableModel(unittest.TestCase):
|
|
@@ -7,7 +7,7 @@ MIT License. See Project Root for the license information.
|
|
|
7
7
|
import unittest
|
|
8
8
|
from typing import Dict, List, Any
|
|
9
9
|
from boto3_assist.models.serializable_model import SerializableModel
|
|
10
|
-
from tests.models_tests.models.user import User
|
|
10
|
+
from tests.unit.models_tests.models.user import User
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class TestSerializableModel(unittest.TestCase):
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '0.11.0'
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Geek Cafe, LLC
|
|
3
|
-
Maintainers: Eric Wilson
|
|
4
|
-
MIT License. See Project Root for the license information.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
import os
|
|
8
|
-
import sys
|
|
9
|
-
from pathlib import Path
|
|
10
|
-
|
|
11
|
-
VERBOSE: bool = os.getenv("VERBOSE") or False
|
|
12
|
-
|
|
13
|
-
if VERBOSE:
|
|
14
|
-
print("👋 init test paths for __top")
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
root_directory = Path(__file__).resolve().parent.parent.parent
|
|
18
|
-
src_directory = os.path.join(root_directory, "src")
|
|
19
|
-
# inject src path to python search path
|
|
20
|
-
sys.path.insert(0, src_directory)
|
|
21
|
-
|
|
22
|
-
if VERBOSE:
|
|
23
|
-
print("")
|
|
24
|
-
for p in sys.path:
|
|
25
|
-
print(f"👉 {p}")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boto3_assist-0.11.0 → boto3_assist-0.12.0}/examples/dynamodb/services/order_item_service.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/cloudwatch/cloudwatch_connection.py
RENAMED
|
File without changes
|
|
File without changes
|
{boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/cloudwatch/cloudwatch_log_connection.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/dynamodb/dynamodb_model_base.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/dynamodb/dynamodb_reserved_words.py
RENAMED
|
File without changes
|
{boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/dynamodb/dynamodb_reserved_words.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/environment_services/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/securityhub/securityhub_connection.py
RENAMED
|
File without changes
|
|
File without changes
|
{boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/ssm/parameter_store/parameter_store.py
RENAMED
|
File without changes
|
|
File without changes
|
{boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/utilities/dictionary_utility.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boto3_assist-0.11.0 → boto3_assist-0.12.0}/src/boto3_assist/utilities/serialization_utility.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/dynamodb_tests/dbmodels/cms/base.py
RENAMED
|
File without changes
|
{boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/dynamodb_tests/dbmodels/simple_model.py
RENAMED
|
File without changes
|
{boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/dynamodb_tests/dbmodels/user_model.py
RENAMED
|
File without changes
|
|
File without changes
|
{boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/dynamodb_tests/dynamodb_reindex_test.py
RENAMED
|
File without changes
|
|
File without changes
|
{boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/examples_test/user_service_test.py
RENAMED
|
File without changes
|
|
File without changes
|
{boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/lambda_tests/event_info_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/parameter_store/parameter_store_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/utilities/serialization_utility_test.py
RENAMED
|
File without changes
|
{boto3_assist-0.11.0/tests → boto3_assist-0.12.0/tests/unit}/utilities/string_utility_test.py
RENAMED
|
File without changes
|