clear-skies-aws 1.10.2__py3-none-any.whl → 2.0.2__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.
Files changed (86) hide show
  1. {clear_skies_aws-1.10.2.dist-info → clear_skies_aws-2.0.2.dist-info}/METADATA +36 -35
  2. clear_skies_aws-2.0.2.dist-info/RECORD +63 -0
  3. {clear_skies_aws-1.10.2.dist-info → clear_skies_aws-2.0.2.dist-info}/WHEEL +1 -1
  4. clear_skies_aws-2.0.2.dist-info/licenses/LICENSE +21 -0
  5. clearskies_aws/__init__.py +15 -2
  6. clearskies_aws/actions/__init__.py +13 -106
  7. clearskies_aws/actions/action_aws.py +74 -57
  8. clearskies_aws/actions/assume_role.py +43 -30
  9. clearskies_aws/actions/ses.py +82 -73
  10. clearskies_aws/actions/sns.py +27 -30
  11. clearskies_aws/actions/sqs.py +32 -33
  12. clearskies_aws/actions/step_function.py +38 -31
  13. clearskies_aws/backends/__init__.py +11 -4
  14. clearskies_aws/backends/backend.py +106 -0
  15. clearskies_aws/backends/dynamo_db_backend.py +150 -155
  16. clearskies_aws/backends/dynamo_db_condition_parser.py +40 -80
  17. clearskies_aws/backends/dynamo_db_parti_ql_backend.py +179 -337
  18. clearskies_aws/backends/sqs_backend.py +32 -51
  19. clearskies_aws/configs/__init__.py +0 -0
  20. clearskies_aws/contexts/__init__.py +23 -10
  21. clearskies_aws/contexts/cli_web_socket_mock.py +19 -0
  22. clearskies_aws/contexts/lambda_alb.py +76 -0
  23. clearskies_aws/contexts/lambda_api_gateway.py +75 -28
  24. clearskies_aws/contexts/lambda_api_gateway_web_socket.py +56 -29
  25. clearskies_aws/contexts/lambda_invocation.py +15 -44
  26. clearskies_aws/contexts/lambda_sns.py +8 -33
  27. clearskies_aws/contexts/lambda_sqs_standard_partial_batch.py +14 -36
  28. clearskies_aws/di/__init__.py +6 -1
  29. clearskies_aws/di/aws_additional_config_auto_import.py +37 -0
  30. clearskies_aws/di/inject/__init__.py +6 -0
  31. clearskies_aws/di/inject/boto3.py +15 -0
  32. clearskies_aws/di/inject/boto3_session.py +13 -0
  33. clearskies_aws/di/inject/parameter_store.py +15 -0
  34. clearskies_aws/{handlers → endpoints}/secrets_manager_rotation.py +76 -55
  35. clearskies_aws/endpoints/simple_body_routing.py +41 -0
  36. clearskies_aws/input_outputs/__init__.py +21 -8
  37. clearskies_aws/input_outputs/{cli_websocket_mock.py → cli_web_socket_mock.py} +9 -3
  38. clearskies_aws/input_outputs/lambda_alb.py +53 -0
  39. clearskies_aws/input_outputs/lambda_api_gateway.py +106 -88
  40. clearskies_aws/input_outputs/lambda_api_gateway_web_socket.py +69 -6
  41. clearskies_aws/input_outputs/lambda_input_output.py +87 -0
  42. clearskies_aws/input_outputs/lambda_invocation.py +77 -26
  43. clearskies_aws/input_outputs/lambda_sns.py +66 -39
  44. clearskies_aws/input_outputs/lambda_sqs_standard.py +70 -40
  45. clearskies_aws/mocks/actions/ses.py +25 -19
  46. clearskies_aws/mocks/actions/sns.py +18 -12
  47. clearskies_aws/mocks/actions/sqs.py +18 -12
  48. clearskies_aws/mocks/actions/step_function.py +19 -13
  49. clearskies_aws/models/__init__.py +0 -0
  50. clearskies_aws/models/web_socket_connection_model.py +182 -0
  51. clearskies_aws/secrets/__init__.py +13 -7
  52. clearskies_aws/secrets/additional_configs/__init__.py +10 -2
  53. clearskies_aws/secrets/additional_configs/iam_db_auth.py +26 -16
  54. clearskies_aws/secrets/additional_configs/iam_db_auth_with_ssm.py +43 -39
  55. clearskies_aws/secrets/additional_configs/mysql_connection_dynamic_producer_via_ssh_cert_bastion.py +30 -31
  56. clearskies_aws/secrets/additional_configs/mysql_connection_dynamic_producer_via_ssm_bastion.py +70 -49
  57. clearskies_aws/secrets/akeyless_with_ssm_cache.py +32 -18
  58. clearskies_aws/secrets/parameter_store.py +34 -32
  59. clearskies_aws/secrets/secrets.py +16 -0
  60. clearskies_aws/secrets/secrets_manager.py +78 -57
  61. clear_skies_aws-1.10.2.dist-info/LICENSE +0 -7
  62. clear_skies_aws-1.10.2.dist-info/RECORD +0 -71
  63. clearskies_aws/actions/assume_role_test.py +0 -72
  64. clearskies_aws/actions/ses_test.py +0 -89
  65. clearskies_aws/actions/sns_test.py +0 -77
  66. clearskies_aws/actions/sqs_test.py +0 -127
  67. clearskies_aws/actions/step_function_test.py +0 -103
  68. clearskies_aws/backends/dynamo_db_backend_test.py +0 -300
  69. clearskies_aws/backends/dynamo_db_condition_parser_test.py +0 -266
  70. clearskies_aws/backends/dynamo_db_parti_ql_backend_test.py +0 -544
  71. clearskies_aws/backends/sqs_backend_test.py +0 -31
  72. clearskies_aws/contexts/cli.py +0 -19
  73. clearskies_aws/contexts/cli_websocket_mock.py +0 -33
  74. clearskies_aws/contexts/lambda_elb.py +0 -30
  75. clearskies_aws/contexts/lambda_http_gateway.py +0 -30
  76. clearskies_aws/contexts/lambda_sqs_standard_partial_batch_test.py +0 -66
  77. clearskies_aws/contexts/wsgi.py +0 -19
  78. clearskies_aws/di/standard_dependencies.py +0 -60
  79. clearskies_aws/handlers/simple_body_routing.py +0 -39
  80. clearskies_aws/input_outputs/lambda_api_gateway_test.py +0 -87
  81. clearskies_aws/input_outputs/lambda_elb.py +0 -21
  82. clearskies_aws/input_outputs/lambda_http_gateway.py +0 -12
  83. clearskies_aws/secrets/parameter_store_test.py +0 -18
  84. clearskies_aws/secrets/secrets_manager_test.py +0 -18
  85. clearskies_aws/web_socket_connection_model.py +0 -43
  86. clearskies_aws/{handlers → endpoints}/__init__.py +1 -1
@@ -1,72 +0,0 @@
1
- import unittest
2
- from unittest.mock import MagicMock, call
3
-
4
- from .assume_role import AssumeRole
5
-
6
-
7
- class AssumeRoleTest(unittest.TestCase):
8
- def test_with_external_id(self):
9
- sts = MagicMock()
10
- sts.assume_role = MagicMock(
11
- return_value={
12
- "Credentials": {
13
- "AccessKeyId": "access-key",
14
- "SecretAccessKey": "secret-key",
15
- "SessionToken": "session-token",
16
- }
17
- }
18
- )
19
- boto3 = MagicMock()
20
- boto3.client = MagicMock(return_value=sts)
21
- boto3.Session = MagicMock(return_value='MOAR BOTO')
22
-
23
- assume_role = AssumeRole(role_arn='aws:arn:role/name', external_id='12345')
24
- self.assertEqual("MOAR BOTO", assume_role(boto3))
25
- boto3.client.assert_called_with("sts")
26
- boto3.Session.assert_called_with(
27
- aws_access_key_id="access-key",
28
- aws_secret_access_key="secret-key",
29
- aws_session_token="session-token",
30
- )
31
- sts.assume_role.assert_called_with(
32
- RoleArn='aws:arn:role/name',
33
- RoleSessionName="clearkies-aws",
34
- DurationSeconds=3600,
35
- ExternalId="12345",
36
- )
37
-
38
- def test_with_source(self):
39
- sts = MagicMock()
40
- sts.assume_role = MagicMock(
41
- return_value={
42
- "Credentials": {
43
- "AccessKeyId": "access-key",
44
- "SecretAccessKey": "secret-key",
45
- "SessionToken": "session-token",
46
- }
47
- }
48
- )
49
- boto3 = MagicMock()
50
- boto3.client = MagicMock(return_value=sts)
51
- boto3.Session = MagicMock(return_value='MOAR BOTO')
52
- source = MagicMock(return_value=boto3)
53
-
54
- assume_role = AssumeRole(
55
- role_arn='aws:arn:role/name',
56
- source=source,
57
- role_session_name="sup",
58
- duration=7200,
59
- )
60
- self.assertEqual("MOAR BOTO", assume_role("not-boto3"))
61
- boto3.client.assert_called_with("sts")
62
- boto3.Session.assert_called_with(
63
- aws_access_key_id="access-key",
64
- aws_secret_access_key="secret-key",
65
- aws_session_token="session-token",
66
- )
67
- sts.assume_role.assert_called_with(
68
- RoleArn='aws:arn:role/name',
69
- RoleSessionName="sup",
70
- DurationSeconds=7200,
71
- )
72
- source.assert_called_with("not-boto3")
@@ -1,89 +0,0 @@
1
- import unittest
2
- from unittest.mock import MagicMock, call
3
- from .ses import SES
4
- import clearskies
5
- from ..di import StandardDependencies
6
- class SESTest(unittest.TestCase):
7
- def setUp(self):
8
- self.di = StandardDependencies()
9
- self.di.bind('environment', {'AWS_REGION': 'us-east-2'})
10
- self.ses = MagicMock()
11
- self.ses.send_email = MagicMock()
12
- self.boto3 = MagicMock()
13
- self.boto3.client = MagicMock(return_value=self.ses)
14
- self.environment = MagicMock()
15
- self.environment.get = MagicMock(return_value='us-east-1')
16
-
17
- def test_send(self):
18
- ses = SES(self.environment, self.boto3, self.di)
19
- ses.configure(
20
- 'test@example.com', to='jane@example.com', subject='welcome!', message_template='hi {{ model.id }}!'
21
- )
22
- model = MagicMock()
23
- model.id = 'asdf'
24
- ses(model)
25
- self.ses.send_email.assert_has_calls([
26
- call(
27
- Destination={
28
- 'ToAddresses': ['jane@example.com'],
29
- 'CcAddresses': [],
30
- 'BccAddresses': []
31
- },
32
- Message={
33
- 'Body': {
34
- 'Html': {
35
- 'Charset': 'utf-8',
36
- 'Data': 'hi asdf!'
37
- },
38
- 'Text': {
39
- 'Charset': 'utf-8',
40
- 'Data': 'hi asdf!'
41
- }
42
- },
43
- 'Subject': {
44
- 'Charset': 'utf-8',
45
- 'Data': 'welcome!'
46
- }
47
- },
48
- Source='test@example.com'
49
- ),
50
- ])
51
-
52
- def test_send_callable(self):
53
- ses = SES(self.environment, self.boto3, self.di)
54
- ses.configure(
55
- 'test@example.com',
56
- to=lambda model: 'jane@example.com',
57
- bcc=lambda model: ['bob@example.com', 'greg@example.com'],
58
- subject='welcome!',
59
- message_template='hi {{ model.id }}!'
60
- )
61
- model = MagicMock()
62
- model.id = 'asdf'
63
- ses(model)
64
- self.ses.send_email.assert_has_calls([
65
- call(
66
- Destination={
67
- 'ToAddresses': ['jane@example.com'],
68
- 'CcAddresses': [],
69
- 'BccAddresses': ['bob@example.com', 'greg@example.com']
70
- },
71
- Message={
72
- 'Body': {
73
- 'Html': {
74
- 'Charset': 'utf-8',
75
- 'Data': 'hi asdf!'
76
- },
77
- 'Text': {
78
- 'Charset': 'utf-8',
79
- 'Data': 'hi asdf!'
80
- }
81
- },
82
- 'Subject': {
83
- 'Charset': 'utf-8',
84
- 'Data': 'welcome!'
85
- }
86
- },
87
- Source='test@example.com'
88
- ),
89
- ])
@@ -1,77 +0,0 @@
1
- import unittest
2
- import boto3
3
-
4
- from unittest.mock import MagicMock, call
5
- from .sns import SNS
6
- import clearskies
7
- from ..di import StandardDependencies
8
- import json
9
- from collections import OrderedDict
10
- class User(clearskies.Model):
11
- def __init__(self, memory_backend, columns):
12
- super().__init__(memory_backend, columns)
13
-
14
- def columns_configuration(self):
15
- return OrderedDict([
16
- clearskies.column_types.string('name'),
17
- clearskies.column_types.email('email'),
18
- ])
19
- class SNSTest(unittest.TestCase):
20
- def setUp(self):
21
- self.di = StandardDependencies()
22
- self.di.bind('environment', {'AWS_REGION': 'us-east-2'})
23
- self.users = self.di.build(User)
24
- self.sns = MagicMock()
25
- self.sns.publish = MagicMock()
26
- self.boto3 = MagicMock()
27
- self.boto3.client = MagicMock(return_value=self.sns)
28
- self.when = None
29
- self.environment = MagicMock()
30
- self.environment.get = MagicMock(return_value='us-east-1')
31
-
32
- def always(self, model):
33
- self.when = model
34
- return True
35
-
36
- def never(self, model):
37
- self.when = model
38
- return False
39
-
40
- def test_send(self):
41
- sns = SNS(self.environment, self.boto3, self.di)
42
- sns.configure(
43
- topic='arn:aws:my-topic',
44
- when=self.always,
45
- )
46
- user = self.users.model({
47
- "id": "1-2-3-4",
48
- "name": "Jane",
49
- "email": "jane@example.com",
50
- })
51
- sns(user)
52
- self.sns.publish.assert_has_calls([
53
- call(
54
- TopicArn='arn:aws:my-topic',
55
- Message=json.dumps({
56
- "id": "1-2-3-4",
57
- "name": "Jane",
58
- "email": "jane@example.com",
59
- }),
60
- ),
61
- ])
62
- self.assertEqual(id(user), id(self.when))
63
-
64
- def test_not_now(self):
65
- sns = SNS(self.environment, self.boto3, self.di)
66
- sns.configure(
67
- topic='arn:aws:my-topic',
68
- when=self.never,
69
- )
70
- user = self.users.model({
71
- "id": "1-2-3-4",
72
- "name": "Jane",
73
- "email": "jane@example.com",
74
- })
75
- sns(user)
76
- self.sns.publish.assert_not_called()
77
- self.assertEqual(id(user), id(self.when))
@@ -1,127 +0,0 @@
1
- import unittest
2
- from unittest.mock import MagicMock, call
3
- from .sqs import SQS
4
- import clearskies
5
- from ..di import StandardDependencies
6
- import json
7
- from collections import OrderedDict
8
- class User(clearskies.Model):
9
- def __init__(self, memory_backend, columns):
10
- super().__init__(memory_backend, columns)
11
-
12
- def columns_configuration(self):
13
- return OrderedDict([
14
- clearskies.column_types.string('name'),
15
- clearskies.column_types.email('email'),
16
- ])
17
- class SQSTest(unittest.TestCase):
18
- def setUp(self):
19
- self.di = StandardDependencies()
20
- self.di.bind('environment', {'AWS_REGION': 'us-east-2'})
21
- self.users = self.di.build(User)
22
- self.sqs = MagicMock()
23
- self.sqs.send_message = MagicMock()
24
- self.boto3 = MagicMock()
25
- self.boto3.client = MagicMock(return_value=self.sqs)
26
- self.when = None
27
- self.environment = MagicMock()
28
- self.environment.get = MagicMock(return_value='us-east-1')
29
-
30
- def always(self, model):
31
- self.when = model
32
- return True
33
-
34
- def never(self, model):
35
- self.when = model
36
- return False
37
-
38
- def test_send(self):
39
- sqs = SQS(self.environment, self.boto3, self.di)
40
- sqs.configure(
41
- queue_url='https://queue.example.com',
42
- when=self.always,
43
- )
44
- user = self.users.model({
45
- "id": "1-2-3-4",
46
- "name": "Jane",
47
- "email": "jane@example.com",
48
- })
49
- sqs(user)
50
- self.sqs.send_message.assert_has_calls([
51
- call(
52
- QueueUrl='https://queue.example.com',
53
- MessageBody=json.dumps({
54
- "id": "1-2-3-4",
55
- "name": "Jane",
56
- "email": "jane@example.com",
57
- }),
58
- ),
59
- ])
60
- self.assertEqual(id(user), id(self.when))
61
-
62
- def test_send_message_group_id(self):
63
- sqs = SQS(self.environment, self.boto3, self.di)
64
- sqs.configure(
65
- queue_url='https://queue.example.com',
66
- when=self.always,
67
- message_group_id='heysup',
68
- )
69
- user = self.users.model({
70
- "id": "1-2-3-4",
71
- "name": "Jane",
72
- "email": "jane@example.com",
73
- })
74
- sqs(user)
75
- self.sqs.send_message.assert_has_calls([
76
- call(
77
- QueueUrl='https://queue.example.com',
78
- MessageGroupId='heysup',
79
- MessageBody=json.dumps({
80
- "id": "1-2-3-4",
81
- "name": "Jane",
82
- "email": "jane@example.com",
83
- }),
84
- ),
85
- ])
86
- self.assertEqual(id(user), id(self.when))
87
-
88
- def test_send_message_group_id_callable(self):
89
- sqs = SQS(self.environment, self.boto3, self.di)
90
- sqs.configure(
91
- queue_url='https://queue.example.com',
92
- when=self.always,
93
- message_group_id=lambda model: model.id,
94
- )
95
- user = self.users.model({
96
- "id": "1-2-3-4",
97
- "name": "Jane",
98
- "email": "jane@example.com",
99
- })
100
- sqs(user)
101
- self.sqs.send_message.assert_has_calls([
102
- call(
103
- QueueUrl='https://queue.example.com',
104
- MessageGroupId='1-2-3-4',
105
- MessageBody=json.dumps({
106
- "id": "1-2-3-4",
107
- "name": "Jane",
108
- "email": "jane@example.com",
109
- }),
110
- ),
111
- ])
112
- self.assertEqual(id(user), id(self.when))
113
-
114
- def test_not_now(self):
115
- sqs = SQS(self.environment, self.boto3, self.di)
116
- sqs.configure(
117
- queue_url='https://queue.example.com',
118
- when=self.never,
119
- )
120
- user = self.users.model({
121
- "id": "1-2-3-4",
122
- "name": "Jane",
123
- "email": "jane@example.com",
124
- })
125
- sqs(user)
126
- self.sqs.send_message.assert_not_called()
127
- self.assertEqual(id(user), id(self.when))
@@ -1,103 +0,0 @@
1
- import unittest
2
- from unittest.mock import MagicMock, call
3
- from .step_function import StepFunction
4
- import clearskies
5
- from ..di import StandardDependencies
6
- import json
7
- from collections import OrderedDict
8
- class User(clearskies.Model):
9
- def __init__(self, memory_backend, columns):
10
- super().__init__(memory_backend, columns)
11
-
12
- def columns_configuration(self):
13
- return OrderedDict([
14
- clearskies.column_types.email('email'),
15
- clearskies.column_types.string('execution_arn'),
16
- ])
17
- class StepFunctionTest(unittest.TestCase):
18
- def setUp(self):
19
- self.di = StandardDependencies()
20
- self.di.bind('environment', {'AWS_REGION': 'us-east-2'})
21
- memory_backend = self.di.build("memory_backend")
22
- self.users = self.di.build(User)
23
- self.user = self.users.create({
24
- "id": "1-2-3-4",
25
- "email": "blah@example.com",
26
- })
27
- self.step_function = MagicMock()
28
- self.step_function.start_execution = MagicMock(return_value={"executionArn":"aws:arn:execution"})
29
- self.boto3 = MagicMock()
30
- self.boto3.client = MagicMock(return_value=self.step_function)
31
- self.when = None
32
- self.environment = MagicMock()
33
- self.environment.get = MagicMock(return_value='us-east-2')
34
-
35
- def always(self, model):
36
- self.when = model
37
- return True
38
-
39
- def never(self, model):
40
- self.when = model
41
- return False
42
-
43
- def test_execute(self):
44
- step_function = StepFunction(self.environment, self.boto3, self.di)
45
- step_function.configure(
46
- arn='aws::arn:us-east-2:step/asdf-er',
47
- when=self.always,
48
- column_to_store_execution_arn="execution_arn",
49
- )
50
- step_function(self.user)
51
- self.step_function.start_execution.assert_has_calls([
52
- call(
53
- stateMachineArn='aws::arn:us-east-2:step/asdf-er',
54
- input=json.dumps({
55
- "id": self.user.id,
56
- "email": self.user.email,
57
- "execution_arn": None,
58
- }),
59
- ),
60
- ])
61
- self.assertEqual(id(self.user), id(self.when))
62
- self.assertEqual("aws:arn:execution", self.user.execution_arn)
63
-
64
- def test_region_switch(self):
65
- self.boto3.client.side_effect = [self.step_function, self.step_function]
66
- step_function = StepFunction(self.environment, self.boto3, self.di)
67
- step_function.configure(
68
- arn='aws::arn:eu-west-1:step/asdf-er',
69
- when=self.always,
70
- column_to_store_execution_arn="execution_arn",
71
- )
72
- step_function(self.user)
73
- self.step_function.start_execution.assert_has_calls([
74
- call(
75
- stateMachineArn='aws::arn:eu-west-1:step/asdf-er',
76
- input=json.dumps({
77
- "id": self.user.id,
78
- "email": self.user.email,
79
- "execution_arn": None,
80
- }),
81
- ),
82
- ])
83
- self.assertEqual(id(self.user), id(self.when))
84
- self.assertEqual("aws:arn:execution", self.user.execution_arn)
85
- self.boto3.client.assert_has_calls([
86
- call("stepfunctions", region_name="us-east-2"),
87
- call("stepfunctions", region_name="eu-west-1"),
88
- ])
89
-
90
- def test_not_now(self):
91
- step_function = StepFunction(self.environment, self.boto3, self.di)
92
- step_function.configure(
93
- arn='aws::arn:us-east-2:step-function/asdf-er',
94
- when=self.never,
95
- )
96
- user = self.users.model({
97
- "id": "1-2-3-4",
98
- "name": "Jane",
99
- "email": "jane@example.com",
100
- })
101
- step_function(user)
102
- self.step_function.start_execution.assert_not_called()
103
- self.assertEqual(id(user), id(self.when))