-
Notifications
You must be signed in to change notification settings - Fork 1
/
deploy.py
145 lines (111 loc) · 4.95 KB
/
deploy.py
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import os
import requests
# The directory that contains all `.properties.example` files
PROPERTIES_DIR = "common/src/main/resources/properties/"
# The environment variable with the Slack webhook URL
SLACK_WEBHOOK_ENV_VAR = "SLACK_WEBHOOK_URL"
# Dictionary that maps example file names to a dictionary where the keys
# are the PROPERTIES (KEYS), and the values are ENVIRONMENT VARIABLES
ENV_VALUES = {
"server.properties.example": {
# AWS Properties
"aws_access_key": "AWS_ACCESS_KEY_ID",
"aws_secret_key": "AWS_SECRET_ACCESS_KEY",
"s3_bucket_url": "S3_BUCKET_URL",
"s3_bucket_name": "S3_BUCKET_NAME",
"s3_upload_dir": "S3_UPLOAD_DIR",
# Database Properties
"database_url": "DB_DOMAIN",
"database_username": "DB_USERNAME",
"database_password": "DB_PASSWORD",
# Email Properties
"email_send_password": "GMAIL_APP_PASSWORD",
"email_should_send": "GMAIL_APP_ENABLED",
# JWT Properties
"jwt_secret_key": "JWT_SECRET_KEY",
# Slack Properties
"slack_webhook_url": SLACK_WEBHOOK_ENV_VAR,
"slack_enabled": "SLACK_ENABLED",
# Stripe Properties
"stripe_api_secret_key": "STRIPE_API_SECRET_KEY",
"stripe_webhook_signing_secret": "STRIPE_WEBHOOK_SIGNING_SECRET",
},
}
# Whether or not to log errors to Slack
SEND_SLACK = True
def main():
global SEND_SLACK
# Enable logging deploy errors to Slack if the webhook url is set in the environment
SEND_SLACK = True if SLACK_WEBHOOK_ENV_VAR in os.environ else False
# Iterate through every item in the given directory
dir_contents = os.listdir(PROPERTIES_DIR)
for file_name in dir_contents:
# Only copy/modify .properties.example files
if not file_name.endswith(".properties.example"):
continue
print("Reading:", file_name)
out_file_name = file_name[:-8] # Strips the ".example" from the file name
print("Writing:", out_file_name)
with open(PROPERTIES_DIR + out_file_name, "w") as file_properties:
with open(PROPERTIES_DIR + file_name, "r") as file_example:
process_properties(file_name, file_example, file_properties)
def process_properties(example_file_name, file_example, file_properties):
"""
Given the name of an example file and IO files for reading and writing, copies
the contents of the example file to the properties file. All placeholder
values present in ENV_VALUES are replaced with their respective values.
:param example_file_name: the name of the example file.
:param file_example: the IO file to read with example properties.
:param file_properties: the IO file to write the production properties.
:return: void
"""
# If no replacement values are provided, copy the .example file as-is
if example_file_name not in ENV_VALUES:
for line in file_example:
file_properties.write(line)
return
# Key: property, value: environment variable
replacement_dict = ENV_VALUES[example_file_name]
# Otherwise, copy and replace the placeholders with environment variables
for line in file_example:
line_split = line.split("=", 1)
# Copy the whole line if it did not split correctly
if len(line_split) != 2:
file_properties.write(line)
continue
# Copy the the whole line if no replacement var is provided
key_placeholder = line_split[0].strip() # The key before the "="
if key_placeholder not in replacement_dict:
file_properties.write(line)
continue
# Else, copy the line and replace the placeholder
if key_placeholder in replacement_dict:
env_var = replacement_dict[key_placeholder]
env_var = env_var if not env_var.startswith("$") else env_var[1:] # Strip leading "$"
# Get the value of the environment variable
out_value = os.environ.get(env_var)
# Ensure the desired environment variable is actually set
if out_value is None:
out_value = "${}".format(env_var) # Set value to environment variable name
error_msg = "`[{}]`: Replacing empty environment variable: `${}`".format(example_file_name, env_var)
handle_error(error_msg)
out_line = "{} = {}\n".format(key_placeholder, out_value)
file_properties.write(out_line)
continue
def handle_error(error_msg):
"""
Handles printing error messages and sending them to Slack, if applicable.
:param error_msg: the error message to log.
:return: void
"""
print(error_msg)
if SEND_SLACK:
try:
webhook_url = os.environ.get(SLACK_WEBHOOK_ENV_VAR)
payload = {
"text": error_msg
}
requests.post(webhook_url, json=payload)
except Exception as e:
print("Failed to send Slack alert:", e)
main()