1+ import argparse
2+ import json
3+ import os
4+ from enum import Enum
5+
6+ import boto3
7+ from botocore .exceptions import ClientError
8+
9+
10+ class Environments (str , Enum ):
11+ DEV = 'dev'
12+ PROD = 'prod'
13+ LOCAL = 'local'
14+ TEST = 'test'
15+
16+
17+ class ConfigAssembler :
18+ """
19+ Assembles the TechTix (Backend) config file
20+ """
21+
22+ def __init__ (self , aws_region = 'ap-southeast-1' , environment = Environments .DEV .value ):
23+ self .__input_environment = environment
24+ self .__project_name = 'sparcs-events'
25+
26+ # Determine the deployment stage, defaulting to 'dev' for None or 'local' environments
27+ if not self .__input_environment or self .__input_environment == Environments .LOCAL .value :
28+ self .__stage = Environments .DEV .value
29+ else :
30+ self .__stage = self .__input_environment
31+
32+ self .__region = 'ap-southeast-1' if aws_region is None else aws_region
33+ self .__ssm_client = boto3 .client ('ssm' , region_name = self .__region )
34+ self .__secrets_client = boto3 .client ('secretsmanager' , region_name = self .__region )
35+ self .__base_dir = os .getcwd ()
36+
37+ def __get_parameter (self , key , decrypt = False ) -> str :
38+ """
39+ Retrieves parameter values from SSM
40+
41+ :param key: key of parameter value to be retrieved
42+ :param decrypt: flag if value is decrypted
43+ :return: parameter value string
44+ """
45+ kwargs = {'Name' : key , 'WithDecryption' : decrypt }
46+ value = ''
47+ try :
48+ resp = self .__ssm_client .get_parameter (** kwargs )
49+ except ClientError as e :
50+ print (f'Error: { e .response ["Error" ]["Code" ]} - { key } ' )
51+ else :
52+ value = resp ['Parameter' ]['Value' ]
53+ return value
54+
55+ def __get_secret (self , secret_arn ) -> str :
56+ """
57+ Retrieves secret value from AWS Secrets Manager
58+
59+ :param secret_arn: ARN of the secret to retrieve
60+ :return: secret value string
61+ """
62+ try :
63+ resp = self .__secrets_client .get_secret_value (SecretId = secret_arn )
64+ return resp ['SecretString' ]
65+ except ClientError as e :
66+ print (f'Error retrieving secret: { e .response ["Error" ]["Code" ]} - { secret_arn } ' )
67+ return ''
68+
69+ @staticmethod
70+ def escape_env_value (value : str ) -> str :
71+ return value .replace ('$' , '$$' )
72+
73+ @staticmethod
74+ def write_config (file_handle , key , value ) -> None :
75+ """
76+ Writes specified config key-value in the config file
77+
78+ :param file_handle: File pointer
79+ :param key: key of config
80+ :param value: value of config
81+ :return: None
82+ """
83+ entry = f'{ key } ={ ConfigAssembler .escape_env_value (str (value ))} \n '
84+ file_handle .write (entry )
85+
86+ def construct_config_file (self ) -> None :
87+ """
88+ Constructs the config file for Helix
89+
90+ :return: None
91+ """
92+
93+ region = 'ap-southeast-1'
94+ stage = self .__stage
95+ entities_table = self .__get_parameter (f"/{ stage } -sparcs-events-entities" )
96+ registrations_table = self .__get_parameter (f"/{ stage } -sparcs-events-registrations" )
97+ preregistrations_table = self .__get_parameter (f"/{ stage } -sparcs-events-preregistrations" )
98+ evaluations_table = self .__get_parameter (f"/{ stage } -sparcs-events-evaluations" )
99+ events_table = self .__get_parameter (f"/{ stage } -sparcs-events" )
100+ email_queue = self .__get_parameter (f"/sparcs-events-email-queue-url-{ stage } " )
101+ certificate_queue = self .__get_parameter (f"/sparcs-events-certificate-queue-url-{ stage } " )
102+ s3_bucket = self .__get_parameter (f"/{ stage } -sparcs-events-file-bucket" )
103+
104+ userpool_id = f"techtix/cognito-user-pool-id-{ stage } "
105+ userpool_client_id = f"techtix/cognito-user-pool-client-id-{ stage } "
106+
107+ if self .__input_environment == Environments .LOCAL .value or stage == Environments .LOCAL .value :
108+ frontend_url = 'http://localhost:3000'
109+ else :
110+ frontend_url = self .__get_parameter (f"techtix/frontend-url-{ stage } " )
111+
112+ # Determine if this is a local environment
113+ is_local = (
114+ self .__input_environment == Environments .LOCAL .value
115+ or self .__input_environment == Environments .TEST .value
116+ )
117+
118+ config_file = f'{ self .__base_dir } /.env'
119+
120+ with open (config_file , 'w' , encoding = 'utf-8' ) as file_handle :
121+ self .write_config (file_handle , 'REGION' , region )
122+ self .write_config (file_handle , 'FRONTEND_URL' , frontend_url )
123+ self .write_config (file_handle , 'ENTITIES_TABLE' , entities_table )
124+ self .write_config (file_handle , 'REGISTRATIONS_TABLE' , registrations_table )
125+ self .write_config (file_handle , 'PREREGISTRATIONS_TABLE' , preregistrations_table )
126+ self .write_config (file_handle , 'EVALUATIONS_TABLE' , evaluations_table )
127+ self .write_config (file_handle , 'EVENTS_TABLE' , events_table )
128+ self .write_config (file_handle , 'EMAIL_QUEUE' , email_queue )
129+ self .write_config (file_handle , 'CERTIFICATE_QUEUE' , certificate_queue )
130+ self .write_config (file_handle , 'S3_BUCKET' , s3_bucket )
131+ self .write_config (file_handle , 'USERPOOL_ID' , userpool_id )
132+ self .write_config (file_handle , 'USERPOOL_CLIENT_ID' , userpool_client_id )
133+ self .write_config (file_handle , 'STAGE' , stage )
134+
135+ print (f'Configuration file created successfully at: { config_file } ' )
136+
137+
138+ if __name__ == '__main__' :
139+ print (Environments )
140+ parser = argparse .ArgumentParser (description = 'TechTix (Backend) Configuration Assembler' )
141+ parser .add_argument ('-r' , '--region' , help = 'AWS Region (default: ap-southeast-1)' )
142+ parser .add_argument ('-s' , '--stage' , help = 'Environment Name (default: dev)' )
143+ args = parser .parse_args ()
144+
145+ print ('Arguments:' , args )
146+ region = args .region
147+ input_stage = args .stage
148+
149+ config_assembler = ConfigAssembler (region , input_stage )
150+ config_assembler .construct_config_file ()
0 commit comments