Repository navigation
Expand file tree
/
Copy pathhttps_to_amqps.py
More file actions
120 lines (96 loc) · 3.63 KB
/
Copy pathhttps_to_amqps.py
File metadata and controls
120 lines (96 loc) · 3.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
"""
Lambda function to connect https to amqps
"""
import json
import os
import boto3
import pika
print('Loading function')
CREDENTIALS = None
class MissingEnvVarsException(Exception):
pass
def get_credentials(bucket: str, path: str, encryption_context: str) -> dict:
"""
Gets RabbitMq credentials from s3
:param bucket:Configuration Bucket
:param path: Path to encrypted configuration file
:param encryption_context: Encryption context used during encryption
:return: Credentials to access Rabbitmq
"""
global CREDENTIALS
if CREDENTIALS is None:
client = boto3.client("s3")
file = client.get_object(Bucket=bucket, Key=path)
client = boto3.client("kms")
response = client.decrypt(
CiphertextBlob=file['Body'].read(),
EncryptionContext=encryption_context)
CREDENTIALS = json.loads(response["Plaintext"])
return CREDENTIALS
def respond(err: dict, res: dict = None) -> dict:
"""
Generates an API Gateway response with elements to for the api caller
:param err: (object) With error information
:param res: (dict) Containing the response to return to the user
:return: (dict) Response in API Gateway format
"""
return {
'statusCode': '400' if err else '200',
'body': json.dumps(err) if err else json.dumps(res),
'headers': {
'Content-Type': 'application/json',
},
}
def direct_message_to_rabbitmq(credentials: dict, host: str, vhost: str, body: dict) -> dict:
"""
Receives a message from API Gateway and forwards it to RabbitMQ
:param credentials: (dict) containing the username and password to accesss rabbit
:param host: host address to access RabbitMq
:param vhost: rabbitmq vhost
:param body: Message to forward to RabbitMq
:return: Returns the message forwarded to RabbitMq
"""
print("Forward to RabbitMq")
uri = "amqps://{}:{}@{}/{}".format(
credentials["username"],
credentials["password"],
host,
vhost)
connection = pika.connection.URLParameters(uri)
connection = pika.BlockingConnection(connection)
channel = connection.channel()
properties = pika.spec.BasicProperties(priority=int(body["priority"]))
channel.basic_publish(exchange=body["exchange"],
body=json.dumps(body),
properties=properties,
routing_key="")
return body
def lambda_handler(event: dict, context: object) -> dict:
"""
Receives a message from API Gateway and forwards it to RabbitMQ
:param event: (dict) with the users request to the API Gateway
:param context: (object)
:return: (dict) Response in API Gateway format
"""
print("Set env variables")
host = os.getenv("ADDRESS")
vhost = os.getenv("VHOST")
app_name = os.getenv("APPNAME")
encryption_context = os.getenv("ENCRYPTION_CONTEXT")
config_bucket = os.getenv("CONFIG_BUCKET")
config_path = os.getenv("CONFIG_PATH")
if not host and not vhost and not app_name and not config_path and not config_bucket:
raise MissingEnvVarsException
print("Set up operation behaviour")
operation = event["context"]["http-method"]
operations = {
'POST': direct_message_to_rabbitmq
}
credentials = get_credentials(config_bucket, config_path, encryption_context)
print("Get payload")
body = event['body-json']
if operation in operations:
return respond(
None, operations[operation](
credentials, host, vhost, body))
return respond({"message": 'Unsupported method "{}"'.format(operation)})