clear-skies-aws 1.10.2__py3-none-any.whl → 2.0.1__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 (73) hide show
  1. {clear_skies_aws-1.10.2.dist-info → clear_skies_aws-2.0.1.dist-info}/METADATA +36 -35
  2. clear_skies_aws-2.0.1.dist-info/RECORD +4 -0
  3. {clear_skies_aws-1.10.2.dist-info → clear_skies_aws-2.0.1.dist-info}/WHEEL +1 -1
  4. clear_skies_aws-2.0.1.dist-info/licenses/LICENSE +21 -0
  5. clear_skies_aws-1.10.2.dist-info/LICENSE +0 -7
  6. clear_skies_aws-1.10.2.dist-info/RECORD +0 -71
  7. clearskies_aws/__init__.py +0 -2
  8. clearskies_aws/actions/__init__.py +0 -108
  9. clearskies_aws/actions/action_aws.py +0 -118
  10. clearskies_aws/actions/assume_role.py +0 -102
  11. clearskies_aws/actions/assume_role_test.py +0 -72
  12. clearskies_aws/actions/ses.py +0 -194
  13. clearskies_aws/actions/ses_test.py +0 -89
  14. clearskies_aws/actions/sns.py +0 -64
  15. clearskies_aws/actions/sns_test.py +0 -77
  16. clearskies_aws/actions/sqs.py +0 -82
  17. clearskies_aws/actions/sqs_test.py +0 -127
  18. clearskies_aws/actions/step_function.py +0 -66
  19. clearskies_aws/actions/step_function_test.py +0 -103
  20. clearskies_aws/backends/__init__.py +0 -12
  21. clearskies_aws/backends/dynamo_db_backend.py +0 -614
  22. clearskies_aws/backends/dynamo_db_backend_test.py +0 -300
  23. clearskies_aws/backends/dynamo_db_condition_parser.py +0 -365
  24. clearskies_aws/backends/dynamo_db_condition_parser_test.py +0 -266
  25. clearskies_aws/backends/dynamo_db_parti_ql_backend.py +0 -1123
  26. clearskies_aws/backends/dynamo_db_parti_ql_backend_test.py +0 -544
  27. clearskies_aws/backends/sqs_backend.py +0 -80
  28. clearskies_aws/backends/sqs_backend_test.py +0 -31
  29. clearskies_aws/contexts/__init__.py +0 -10
  30. clearskies_aws/contexts/cli.py +0 -19
  31. clearskies_aws/contexts/cli_websocket_mock.py +0 -33
  32. clearskies_aws/contexts/lambda_api_gateway.py +0 -30
  33. clearskies_aws/contexts/lambda_api_gateway_web_socket.py +0 -30
  34. clearskies_aws/contexts/lambda_elb.py +0 -30
  35. clearskies_aws/contexts/lambda_http_gateway.py +0 -30
  36. clearskies_aws/contexts/lambda_invocation.py +0 -48
  37. clearskies_aws/contexts/lambda_sns.py +0 -43
  38. clearskies_aws/contexts/lambda_sqs_standard_partial_batch.py +0 -51
  39. clearskies_aws/contexts/lambda_sqs_standard_partial_batch_test.py +0 -66
  40. clearskies_aws/contexts/wsgi.py +0 -19
  41. clearskies_aws/di/__init__.py +0 -1
  42. clearskies_aws/di/standard_dependencies.py +0 -60
  43. clearskies_aws/handlers/__init__.py +0 -2
  44. clearskies_aws/handlers/secrets_manager_rotation.py +0 -174
  45. clearskies_aws/handlers/simple_body_routing.py +0 -39
  46. clearskies_aws/input_outputs/__init__.py +0 -8
  47. clearskies_aws/input_outputs/cli_websocket_mock.py +0 -12
  48. clearskies_aws/input_outputs/lambda_api_gateway.py +0 -105
  49. clearskies_aws/input_outputs/lambda_api_gateway_test.py +0 -87
  50. clearskies_aws/input_outputs/lambda_api_gateway_web_socket.py +0 -8
  51. clearskies_aws/input_outputs/lambda_elb.py +0 -21
  52. clearskies_aws/input_outputs/lambda_http_gateway.py +0 -12
  53. clearskies_aws/input_outputs/lambda_invocation.py +0 -34
  54. clearskies_aws/input_outputs/lambda_sns.py +0 -52
  55. clearskies_aws/input_outputs/lambda_sqs_standard.py +0 -54
  56. clearskies_aws/mocks/__init__.py +0 -1
  57. clearskies_aws/mocks/actions/__init__.py +0 -6
  58. clearskies_aws/mocks/actions/ses.py +0 -28
  59. clearskies_aws/mocks/actions/sns.py +0 -23
  60. clearskies_aws/mocks/actions/sqs.py +0 -23
  61. clearskies_aws/mocks/actions/step_function.py +0 -26
  62. clearskies_aws/secrets/__init__.py +0 -7
  63. clearskies_aws/secrets/additional_configs/__init__.py +0 -54
  64. clearskies_aws/secrets/additional_configs/iam_db_auth.py +0 -29
  65. clearskies_aws/secrets/additional_configs/iam_db_auth_with_ssm.py +0 -92
  66. clearskies_aws/secrets/additional_configs/mysql_connection_dynamic_producer_via_ssh_cert_bastion.py +0 -81
  67. clearskies_aws/secrets/additional_configs/mysql_connection_dynamic_producer_via_ssm_bastion.py +0 -141
  68. clearskies_aws/secrets/akeyless_with_ssm_cache.py +0 -46
  69. clearskies_aws/secrets/parameter_store.py +0 -50
  70. clearskies_aws/secrets/parameter_store_test.py +0 -18
  71. clearskies_aws/secrets/secrets_manager.py +0 -75
  72. clearskies_aws/secrets/secrets_manager_test.py +0 -18
  73. clearskies_aws/web_socket_connection_model.py +0 -43
@@ -1,39 +0,0 @@
1
- import clearskies
2
-
3
-
4
- class SimpleBodyRouting(clearskies.handlers.Routing):
5
- def __init__(self, di):
6
- super().__init__(di)
7
-
8
- _configuration_defaults = {
9
- "routes": {},
10
- "route_key": "route",
11
- }
12
-
13
- def handler_classes(self, configuration):
14
- # not actually used but required by base
15
- return []
16
-
17
- def _check_configuration(self, configuration):
18
- for config_name in ["route_key", "routes"]:
19
- if not configuration.get(config_name):
20
- raise KeyError(f"Missing required configuration for SimpleBodyRouting handler: '{config_name}'")
21
- if not isinstance(configuration["routes"], dict):
22
- raise ValueError(f"COnfiguration 'routes' for handler SimpleBodyRouting must be a dictionary, but instead I got something else.")
23
-
24
- def handle(self, input_output):
25
- body = input_output.json_body(required=True)
26
- if not body or not body.get(self.configuration("route_key")):
27
- return self.error(input_output, "Not Found", 404)
28
-
29
- route = body[self.configuration("route_key")]
30
- if route not in self.configuration("routes"):
31
- return self.error(input_output, "Not Found", 404)
32
- return input_output.respond(self._di.call_function(
33
- self.configuration("routes")[route],
34
- request_data=body,
35
- **input_output.context_specifics(),
36
- ), 200)
37
-
38
- def documentation(self):
39
- return []
@@ -1,8 +0,0 @@
1
- from .cli_websocket_mock import CLIWebsocketMock
2
- from .lambda_api_gateway import LambdaAPIGateway
3
- from .lambda_api_gateway_web_socket import LambdaAPIGatewayWebSocket
4
- from .lambda_elb import LambdaELB
5
- from .lambda_http_gateway import LambdaHTTPGateway
6
- from .lambda_invocation import LambdaInvocation
7
- from .lambda_sqs_standard import LambdaSqsStandard
8
- from .lambda_sns import LambdaSns
@@ -1,12 +0,0 @@
1
- import clearskies
2
- class CLIWebsocketMock(clearskies.input_outputs.CLI):
3
- def context_specifics(self):
4
- connection_id = self.json_body().get("connection_id")
5
- if not connection_id:
6
- raise KeyError("When using the CLIWebsocketMock you must provide connection_id in the request body")
7
-
8
- return {
9
- "event": {},
10
- "context": {},
11
- "connection_id": connection_id,
12
- }
@@ -1,105 +0,0 @@
1
- from clearskies.input_outputs.input_output import InputOutput
2
- import json
3
- import base64
4
- import urllib
5
- class LambdaAPIGateway(InputOutput):
6
- _event = None
7
- _context = None
8
- _request_headers = None
9
- _request_method = None
10
- _path = None
11
- _resource = None
12
- _query_parameters = None
13
- _path_parameters = None
14
- _cached_body = None
15
- _body_was_cached = False
16
-
17
- def __init__(self, event, context):
18
- self._event = event
19
- self._context = context
20
- self._request_method = event.get('httpMethod', '').upper()
21
- self._path = event.get('path')
22
- self._resource = event.get('resource')
23
- self._query_parameters = event.get('queryStringParameters', {})
24
- self._path_parameters = event.get('pathParameters', {})
25
- self._request_headers = {}
26
- for (key, value) in event.get('headers', {}).items():
27
- self._request_headers[key.lower()] = value
28
-
29
- def respond(self, body, status_code=200):
30
- if not self.has_header('content-type'):
31
- self.set_header('content-type', 'application/json; charset=UTF-8')
32
-
33
- is_base64 = False
34
- if type(body) == bytes:
35
- is_base64 = True
36
- final_body = base64.encodebytes(body).decode('utf8')
37
- elif type(body) == str:
38
- final_body = body
39
- else:
40
- final_body = json.dumps(body)
41
-
42
- return {
43
- "isBase64Encoded": is_base64,
44
- "statusCode": status_code,
45
- "headers": self._response_headers,
46
- "body": final_body,
47
- }
48
-
49
- def has_body(self):
50
- return bool(self.get_body())
51
-
52
- def get_body(self):
53
- if not self._body_was_cached:
54
- self._cached_body = self._event.get('body')
55
- if self._cached_body is not None and self._event.get('isBase64Encoded'):
56
- self._cached_body = base64.decodebytes(self._cached_body.encode('utf-8')).decode('utf-8')
57
- return self._cached_body
58
-
59
- def get_request_method(self):
60
- return self._request_method
61
-
62
- def get_script_name(self):
63
- return ''
64
-
65
- def get_path_info(self):
66
- return self._path
67
-
68
- def get_query_string(self):
69
- return urllib.parse.urlencode(self._query_parameters)
70
-
71
- def get_content_type(self):
72
- return self.get_request_header('content-type', True)
73
-
74
- def get_protocol(self):
75
- return 'https'
76
-
77
- def has_request_header(self, header_name):
78
- return header_name.lower() in self._request_headers
79
-
80
- def get_request_header(self, header_name, silent=False):
81
- if not header_name.lower() in self._request_headers:
82
- if not silent:
83
- raise KeyError(f"HTTP header '{header_name}' was not found in request")
84
- return ''
85
- return self._request_headers[header_name.lower()]
86
-
87
- def get_query_parameter(self, key):
88
- return self._query_parameters[key] if key in self._query_parameters else []
89
-
90
- def get_query_parameters(self):
91
- return self._query_parameters
92
-
93
- def context_specifics(self):
94
- return {
95
- "event": self._event,
96
- "context": self._context,
97
- }
98
-
99
- def get_client_ip(self):
100
- # I haven't actually tested with an API gateway yet to figure out which of these works...
101
- sourceIp = self._event.get('requestContext', {}).get('identity', {}).get('sourceIp')
102
- if sourceIp:
103
- return sourceIp
104
-
105
- return self.get_request_header('x-forwarded-for', silent=True)
@@ -1,87 +0,0 @@
1
- import unittest
2
- from collections import OrderedDict
3
-
4
- from .lambda_api_gateway import LambdaAPIGateway
5
-
6
-
7
- class LambdaAPIGatewayTest(unittest.TestCase):
8
- dummy_event = {
9
- 'httpMethod': 'GET',
10
- 'path': '/test',
11
- 'resource': 'bob',
12
- 'queryStringParameters': {
13
- 'q': 'hey',
14
- 'bob': 'sup'
15
- },
16
- 'pathParameters': None,
17
- 'headers': {
18
- 'Content-Type': 'application/json'
19
- },
20
- }
21
-
22
- def test_respond(self):
23
- aws_lambda = LambdaAPIGateway(self.dummy_event, {})
24
- aws_lambda.set_headers({'bob': 'hey', 'jane': 'kay'})
25
- aws_lambda.set_header('hey', 'sup')
26
- aws_lambda.clear_header('bob')
27
- response = aws_lambda.respond({'some': 'data'}, 200)
28
- self.assertEqual(
29
- {
30
- "isBase64Encoded": False,
31
- "statusCode": 200,
32
- "headers": OrderedDict(
33
- [
34
- ("JANE", "kay"),
35
- ("HEY", "sup"),
36
- ("CONTENT-TYPE", "application/json; charset=UTF-8"),
37
- ]
38
- ),
39
- "body": '{"some": "data"}',
40
- },
41
- response,
42
- )
43
-
44
- def test_headers(self):
45
- aws_lambda = LambdaAPIGateway({
46
- **self.dummy_event,
47
- **{
48
- 'headers': {
49
- 'Content-Type': 'application/json',
50
- 'AUTHORIZATION': 'hey',
51
- 'X-Auth': 'asdf',
52
- }
53
- }
54
- }, {})
55
- self.assertEqual("hey", aws_lambda.get_request_header("authorizatiON"))
56
- self.assertEqual("asdf", aws_lambda.get_request_header("x-auth"))
57
- self.assertTrue(aws_lambda.has_request_header('authorization'))
58
- self.assertTrue(aws_lambda.has_request_header('x-auth'))
59
- self.assertFalse(aws_lambda.has_request_header('bearer'))
60
-
61
- def test_body_plain(self):
62
- aws_lambda = LambdaAPIGateway({**self.dummy_event, **{'body': '{"hey": "sup"}', 'isBase64Encoded': False}}, {})
63
-
64
- self.assertEqual({"hey": "sup"}, aws_lambda.json_body())
65
- self.assertEqual('{"hey": "sup"}', aws_lambda.get_body())
66
- self.assertTrue(aws_lambda.has_body())
67
-
68
- def test_body_base64(self):
69
- aws_lambda = LambdaAPIGateway({
70
- **self.dummy_event,
71
- **{
72
- 'body': 'eyJoZXkiOiAic3VwIn0=',
73
- 'isBase64Encoded': True
74
- }
75
- }, {})
76
-
77
- self.assertEqual({"hey": "sup"}, aws_lambda.json_body())
78
- self.assertEqual('{"hey": "sup"}', aws_lambda.get_body())
79
- self.assertTrue(aws_lambda.has_body())
80
-
81
- def test_path(self):
82
- aws_lambda = LambdaAPIGateway(self.dummy_event, {})
83
- self.assertEqual("/test", aws_lambda.get_path_info())
84
-
85
- def test_query_string(self):
86
- aws_lambda = LambdaAPIGateway(self.dummy_event, {})
87
- self.assertEqual("q=hey&bob=sup", aws_lambda.get_query_string())
@@ -1,8 +0,0 @@
1
- from .lambda_api_gateway import LambdaAPIGateway
2
- class LambdaAPIGatewayWebSocket(LambdaAPIGateway):
3
- def context_specifics(self):
4
- return {
5
- "event": self._event,
6
- "context": self._context,
7
- "connection_id": self._event["requestContext"]["connectionId"],
8
- }
@@ -1,21 +0,0 @@
1
- from .lambda_api_gateway import LambdaAPIGateway
2
- class LambdaELB(LambdaAPIGateway):
3
- _event = None
4
- _context = None
5
- _request_headers = None
6
- _request_method = None
7
- _path = None
8
- _query_parameters = None
9
-
10
- def __init__(self, event, context):
11
- self._event = event
12
- self._context = context
13
- self._request_method = event.get('httpMethod', 'GET').upper()
14
- self._path = event.get('path', '/')
15
- self._query_parameters = event.get('queryStringParameters', {})
16
- self._request_headers = {}
17
- for (key, value) in event.get('headers', {}).items():
18
- self._request_headers[key.lower()] = value
19
-
20
- def get_client_ip(self):
21
- return self.get_request_header('x-forwarded-for')
@@ -1,12 +0,0 @@
1
- from .lambda_api_gateway import LambdaAPIGateway
2
- class LambdaHTTPGateway(LambdaAPIGateway):
3
- def __init__(self, event, context):
4
- self._event = event
5
- self._context = context
6
- self._path = event.get('requestContext', {}).get('http', {}).get('path')
7
- self._request_method = event.get('requestContext', {}).get('http', {}).get('method').upper()
8
- self._query_parameters = event['queryStringParameters'] if event['queryStringParameters'] is not None else {}
9
- self._path_parameters = event['pathParameters']
10
- self._request_headers = {}
11
- for (key, value) in event['headers'].items():
12
- self._request_headers[key.lower()] = value
@@ -1,34 +0,0 @@
1
- from .lambda_api_gateway import LambdaAPIGateway
2
- import json
3
- from clearskies.handlers.exceptions import ClientError
4
- class LambdaInvocation(LambdaAPIGateway):
5
- def __init__(
6
- self,
7
- event,
8
- context,
9
- method=None,
10
- url=None,
11
- ):
12
- self._event = event
13
- self._context = context
14
- self._path = url if url else ''
15
- self._request_method = method.upper() if method else 'GET'
16
- self._query_parameters = {}
17
- self._path_parameters = []
18
- self._request_headers = {}
19
-
20
- def has_body(self):
21
- return True
22
-
23
- def get_body(self):
24
- return self._event
25
-
26
- def json_body(self, required=True, allow_non_json_bodies=False):
27
- # we ignore the allow_non_json_bodies flag here because with the way invoking lambdas works,
28
- # the event already is an object, so it's a moot point.
29
- if required and not self._event:
30
- raise ClientError("Request body was not valid JSON")
31
- return self._event
32
-
33
- def respond(self, body, status_code=200):
34
- return body.decode('utf-8') if type(body) == bytes else body
@@ -1,52 +0,0 @@
1
- from .lambda_api_gateway import LambdaAPIGateway
2
- from clearskies.handlers.exceptions import ClientError
3
- import json
4
- class LambdaSns(LambdaAPIGateway):
5
- def __init__(self, event, context, url=None, method=None):
6
- self._event = event
7
- self._context = context
8
- self._path = url if url else ''
9
- self._request_method = method.upper() if method else 'GET'
10
- record = event['Records'][0]['Sns']['Message']
11
- try:
12
- self._record = json.loads(record)
13
- except json.JSONDecodeError as e:
14
- raise ClientError("The message from AWS was not a serialized JSON string. The lambda_sns context for clearskies only accepts serialized JSON")
15
-
16
- def respond(self, body, status_code=200):
17
- pass
18
-
19
- def get_body(self):
20
- return self._record
21
-
22
- def request_data(self, required=True, allow_non_json_bodies=False):
23
- return self.json_body(required=required, allow_non_json_bodies=allow_non_json_bodies)
24
-
25
- def json_body(self, required=True, allow_non_json_bodies=False):
26
- if not self._record:
27
- if required:
28
- raise ClientError("No SNS message found")
29
- return {}
30
-
31
- return self._record
32
-
33
- def get_query_string(self):
34
- raise NotImplementedError("The query string doesn't exist in an SNS context")
35
-
36
- def get_content_type(self):
37
- raise NotImplementedError("Content type doesn't exist in an SNS context")
38
-
39
- def get_protocol(self):
40
- raise NotImplementedError("A request protocol is not defined in an SNS context")
41
-
42
- def has_request_header(self, header_name):
43
- raise NotImplementedError("SNS contexts don't have request headers")
44
-
45
- def get_request_header(self, header_name, silent=True):
46
- raise NotImplementedError("SNS contexts don't have request headers")
47
-
48
- def get_query_parameter(self, key):
49
- raise NotImplementedError("SNS contexts don't have query parameters")
50
-
51
- def get_query_parameters(self):
52
- raise NotImplementedError("SNS contexts don't have query parameters")
@@ -1,54 +0,0 @@
1
- from .lambda_api_gateway import LambdaAPIGateway
2
- from clearskies.handlers.exceptions import ClientError
3
- import json
4
- class LambdaSqsStandard(LambdaAPIGateway):
5
- def __init__(self, record, event, context, url=None, method=None):
6
- self._record = record
7
- self._context = context
8
- self._event = event
9
- self._path = url if url else ''
10
- self._request_method = method.upper() if method else 'GET'
11
-
12
- def respond(self, body, status_code=200):
13
- pass
14
-
15
- def get_body(self):
16
- return self._record
17
-
18
- def has_body(self):
19
- return True
20
-
21
- def request_data(self, required=True, allow_non_json_bodies=False):
22
- return self.json_body(required=required, allow_non_json_bodies=allow_non_json_bodies)
23
-
24
- def json_body(self, required=True, allow_non_json_bodies=False):
25
- if not self._record:
26
- if required:
27
- raise ClientError("SQS message was not valid JSON")
28
- return {}
29
-
30
- try:
31
- return json.loads(self._record)
32
- except json.JSONDecodeError:
33
- raise ClientError("SQS message was not valid JSON")
34
-
35
- def get_query_string(self):
36
- raise NotImplementedError("The query string doesn't exist in an SQS context")
37
-
38
- def get_content_type(self):
39
- raise NotImplementedError("Content type doesn't exist in an SQS context")
40
-
41
- def get_protocol(self):
42
- raise NotImplementedError("A request protocol is not defined in an SQS context")
43
-
44
- def has_request_header(self, header_name):
45
- raise NotImplementedError("SQS contexts don't have request headers")
46
-
47
- def get_request_header(self, header_name, silent=True):
48
- raise NotImplementedError("SQS contexts don't have request headers")
49
-
50
- def get_query_parameter(self, key):
51
- raise NotImplementedError("SQS contexts don't have query parameters")
52
-
53
- def get_query_parameters(self):
54
- raise NotImplementedError("SQS contexts don't have query parameters")
@@ -1 +0,0 @@
1
- from . import actions
@@ -1,6 +0,0 @@
1
- from .ses import SES
2
- from .sns import SNS
3
- from .sqs import SQS
4
- from .step_function import StepFunction
5
-
6
- __all__ = ["SES", "SNS", "SQS", "StepFunction"]
@@ -1,28 +0,0 @@
1
- from ...actions.ses import SES as BaseSES
2
- class SES(BaseSES):
3
- calls = None
4
-
5
- def __init__(self, environment, boto3, di):
6
- super().__init__(environment, boto3, di)
7
-
8
- @classmethod
9
- def mock(cls, di):
10
- cls.calls = []
11
- di.mock_class(BaseSES, SES)
12
-
13
- def __call__(self, model) -> None:
14
- """Send a notification as configured."""
15
- if SES.calls == None:
16
- SES.calls = []
17
- utcnow = self.di.build('utcnow')
18
- if self.when and not self.di.call_function(self.when, model=model):
19
- return
20
-
21
- SES.calls.append({
22
- "from": self.sender,
23
- "to": self._resolve_destination("to", model),
24
- "cc": self._resolve_destination("cc", model),
25
- "bcc": self._resolve_destination("bcc", model),
26
- "subject": self._resolve_subject(model, utcnow),
27
- "message": self._resolve_message_as_html(model, utcnow),
28
- })
@@ -1,23 +0,0 @@
1
- from types import ModuleType
2
- from clearskies import Model
3
- from ...actions.sns import SNS as BaseSNS
4
- class SNS(BaseSNS):
5
- calls = None
6
-
7
- def __init__(self, environment, boto3, di):
8
- super().__init__(environment, boto3, di)
9
-
10
- @classmethod
11
- def mock(cls, di):
12
- cls.calls = []
13
- di.mock_class(BaseSNS, SNS)
14
-
15
- def _execute_action(self, client: ModuleType, model: Model) -> None:
16
- """Send a notification as configured."""
17
- if SNS.calls == None:
18
- SNS.calls = []
19
-
20
- SNS.calls.append({
21
- "TopicArn": self.get_topic_arn(model),
22
- "Message": self.get_message_body(model),
23
- })
@@ -1,23 +0,0 @@
1
- from types import ModuleType
2
- from clearskies import Model
3
- from ...actions.sqs import SQS as BaseSQS
4
- class SQS(BaseSQS):
5
- calls = None
6
-
7
- def __init__(self, environment, boto3, di):
8
- super().__init__(environment, boto3, di)
9
-
10
- @classmethod
11
- def mock(cls, di):
12
- cls.calls = []
13
- di.mock_class(BaseSQS, SQS)
14
-
15
- def _execute_action(self, client: ModuleType, model: Model) -> None:
16
- """Send a notification as configured."""
17
- if SQS.calls == None:
18
- SQS.calls = []
19
-
20
- SQS.calls.append({
21
- "QueueUrl": self.get_queue_url(model),
22
- "MessageBody": self.get_message_body(model),
23
- })
@@ -1,26 +0,0 @@
1
- from types import ModuleType
2
- from clearskies import Model
3
- from ...actions.step_function import StepFunction as BaseStepFunction
4
- class StepFunction(BaseStepFunction):
5
- calls = None
6
-
7
- def __init__(self, environment, boto3, di):
8
- super().__init__(environment, boto3, di)
9
-
10
- @classmethod
11
- def mock(cls, di):
12
- StepFunction.calls = []
13
- di.mock_class(BaseStepFunction, StepFunction)
14
-
15
- def _execute_action(self, client: ModuleType, model: Model) -> None:
16
- """Send a notification as configured."""
17
- if StepFunction.calls == None:
18
- StepFunction.calls = []
19
-
20
- StepFunction.calls.append({
21
- "stateMachineArn": self.get_arn(model),
22
- "input": self.get_message_body(model),
23
- })
24
-
25
- if self.column_to_store_execution_arn:
26
- model.save({self.column_to_store_execution_arn: "mock_execution_arn"})
@@ -1,7 +0,0 @@
1
- from clearskies import BindingConfig
2
- from .parameter_store import ParameterStore
3
- from .secrets_manager import SecretsManager
4
- from .akeyless_with_ssm_cache import AkeylessWithSsmCache
5
- from . import additional_configs
6
- def akeyless_with_ssm_cache(*args, **kwargs):
7
- return BindingConfig(AkeylessWithSsmCache, *args, **kwargs)
@@ -1,54 +0,0 @@
1
- from .mysql_connection_dynamic_producer_via_ssh_cert_bastion import MySQLConnectionDynamicProducerViaSSHCertBastion
2
- from .mysql_connection_dynamic_producer_via_ssm_bastion import MySQLConnectionDynamicProducerViaSSMBastion
3
- from .iam_db_auth import IAMDBAuth
4
- from .iam_db_auth_with_ssm import IAMDBAuthWithSSM
5
- def mysql_connection_dynamic_producer_via_ssh_cert_bastion(
6
- producer_name=None,
7
- bastion_host=None,
8
- bastion_name=None,
9
- bastion_region=None,
10
- bastion_username=None,
11
- public_key_file_path=None,
12
- cert_issuer_name=None,
13
- database_host=None,
14
- database_name=None,
15
- local_proxy_port=None,
16
- ):
17
- return MySQLConnectionDynamicProducerViaSSHCertBastion(
18
- producer_name=producer_name,
19
- bastion_host=bastion_host,
20
- bastion_name=bastion_name,
21
- bastion_region=bastion_region,
22
- bastion_username=bastion_username,
23
- cert_issuer_name=cert_issuer_name,
24
- public_key_file_path=public_key_file_path,
25
- database_host=database_host,
26
- database_name=database_name,
27
- local_proxy_port=local_proxy_port,
28
- )
29
- def mysql_connection_dynamic_producer_via_ssm_bastion(
30
- producer_name=None,
31
- bastion_instance_id=None,
32
- bastion_name=None,
33
- bastion_region=None,
34
- bastion_username=None,
35
- public_key_file_path=None,
36
- database_host=None,
37
- database_name=None,
38
- local_proxy_port=None,
39
- ):
40
- return MySQLConnectionDynamicProducerViaSSMBastion(
41
- producer_name=producer_name,
42
- bastion_instance_id=bastion_instance_id,
43
- bastion_name=bastion_name,
44
- bastion_region=bastion_region,
45
- bastion_username=bastion_username,
46
- public_key_file_path=public_key_file_path,
47
- database_host=database_host,
48
- database_name=database_name,
49
- local_proxy_port=local_proxy_port,
50
- )
51
- def iam_db_auth():
52
- return IAMDBAuth()
53
- def iam_db_auth_with_ssm():
54
- return IAMDBAuthWithSSM()
@@ -1,29 +0,0 @@
1
- import clearskies
2
- import os
3
- class IAMDBAuth(clearskies.di.AdditionalConfig):
4
- def provide_boto3(self):
5
- import boto3
6
- return boto3
7
-
8
- def provide_connection_details(self, environment, boto3):
9
- """
10
- I really need to make these configurable - both the values themselves and the environment
11
- variables that things get pulled from.
12
- """
13
- endpoint = environment.get('db_endpoint')
14
- username = environment.get('db_username')
15
- database = environment.get('db_database')
16
- region = environment.get('AWS_REGION')
17
- ssl_ca_bundle_name = environment.get('ssl_ca_bundle_filename')
18
- os.environ['LIBMYSQL_ENABLE_CLEARTEXT_PLUGIN'] = '1'
19
-
20
- rds_api = boto3.Session().client('rds')
21
- rds_token = rds_api.generate_db_auth_token(DBHostname=endpoint, Port='3306', DBUsername=username, Region=region)
22
-
23
- return {
24
- 'username': username,
25
- 'password': rds_token,
26
- 'host': endpoint,
27
- 'database': database,
28
- 'ssl_ca': ssl_ca_bundle_name,
29
- }