16
16
17
17
18
18
def get_sha256_hash (file_path ):
19
- logger .debug ('Hashing "%s " using SHA256' % file_path )
20
- BUF_SIZE = 65536 # lets read stuff in 64kb chunks!
19
+ logger .debug (f 'Hashing "{ file_path } " using SHA256' )
20
+ BUF_SIZE = 65536 # let's read stuff in 64kb chunks!
21
21
sha256 = hashlib .sha256 ()
22
22
with open (file_path , 'rb' ) as f :
23
23
while True :
@@ -31,7 +31,7 @@ def get_sha256_hash(file_path):
31
31
32
32
33
33
def process_parameters_with_prefix (param_prefix , cred_path , aws_region , aws_access_key = None , aws_secret_key = None , dryrun = False ):
34
- logger .debug ('Searching for parameters with a prefix of %s' % param_prefix )
34
+ logger .debug (f 'Searching for parameters with a prefix of { param_prefix } ' )
35
35
36
36
def get_parameters (parameter_names_list ):
37
37
parameter_list = []
@@ -53,29 +53,29 @@ def process_parameter(param_name, param_value):
53
53
if os .path .exists (full_cred_path ):
54
54
existing_file_sha256_hash = get_sha256_hash (full_cred_path )
55
55
new_file_full_path = temp_dir + os .sep + filename + '.new'
56
- logger .debug ('Storing retrieved value for parameter "%s " in "%s"' % ( param_name , new_file_full_path ) )
56
+ logger .debug (f 'Storing retrieved value for parameter "{ param_name } " in "{ new_file_full_path } "' )
57
57
with open (new_file_full_path , 'w' ) as f :
58
58
f .write (param_value )
59
59
new_file_sha256_hash = get_sha256_hash (new_file_full_path )
60
60
logger .debug ('Comparing file hashes' )
61
61
if existing_file_sha256_hash != new_file_sha256_hash :
62
62
if not existing_file_sha256_hash :
63
- logger .info ('This is a new credentials file: "%s"' % filename )
63
+ logger .info (f 'This is a new credentials file: "{ filename } "' )
64
64
else :
65
- logger .info ("Contents don't match - replacing \" %s \" contents with value from parameter store" % full_cred_path )
65
+ logger .info (f "Contents don't match - replacing \" { full_cred_path } \" contents with value from parameter store" )
66
66
if not dryrun :
67
67
if os .path .exists (new_file_full_path ) and os .stat (new_file_full_path ).st_size > 0 :
68
68
shutil .copyfile (new_file_full_path , full_cred_path )
69
69
else :
70
- logger .error ('file %s is missing or zero length - NOT replacing' % new_file_full_path )
70
+ logger .error (f 'file { new_file_full_path } is missing or zero length - NOT replacing' )
71
71
else :
72
- logger .info ('*** Dryrun selected - will NOT update "%s"' % full_cred_path )
72
+ logger .info (f '*** Dryrun selected - will NOT update "{ full_cred_path } "' )
73
73
else :
74
- logger .info ('Contents of existing "%s " MATCH with value for "%s " from parameter store' % ( full_cred_path , param_name ) )
74
+ logger .info (f 'Contents of existing "{ full_cred_path } " MATCH with value for "{ param_name } " from parameter store' )
75
75
76
76
# Cleanup
77
77
if new_file_full_path :
78
- logger .debug ('Removing %s' % new_file_full_path )
78
+ logger .debug (f 'Removing { new_file_full_path } ' )
79
79
os .remove (new_file_full_path )
80
80
81
81
def get_parameters_with_prefix (prefix , next_token = None ):
@@ -84,7 +84,7 @@ def get_parameters_with_prefix(prefix, next_token=None):
84
84
query_result = ssm .describe_parameters (Filters = [{'Key' : 'Name' , 'Values' : [prefix ]}], NextToken = next_token )
85
85
else :
86
86
query_result = ssm .describe_parameters (Filters = [{'Key' : 'Name' , 'Values' : [prefix ]}])
87
- logger .debug ("Query result %s" % str (query_result ))
87
+ logger .debug (f "Query result { str (query_result )} " )
88
88
if 'ResponseMetadata' in query_result :
89
89
if 'HTTPStatusCode' in query_result ['ResponseMetadata' ]:
90
90
if query_result ['ResponseMetadata' ]['HTTPStatusCode' ] == 200 :
@@ -99,7 +99,7 @@ def get_parameters_with_prefix(prefix, next_token=None):
99
99
else :
100
100
logger .debug ("No next token, storing" )
101
101
parameter_list .extend (query_result ['Parameters' ])
102
- logger .debug ("Parameter List %s" % parameter_list )
102
+ logger .debug (f "Parameter List { parameter_list } " )
103
103
return parameter_list
104
104
105
105
@@ -130,6 +130,78 @@ def get_parameters_with_prefix(prefix, next_token=None):
130
130
process_parameter (parameter_name , parameter_value )
131
131
132
132
133
+ def create_aws_cred_file (key_id , secret , file_location , cred_filename , profile_name , aws_region ):
134
+ file_path = f'{ file_location } { os .sep } { cred_filename } '
135
+ if os .path .exists (file_path ):
136
+ # File already exists - append to it
137
+ with open (file_path , 'a' ) as cred_file :
138
+ cred_file .write ('\n ' )
139
+ cred_file .write (f'[{ profile_name } ]\n ' )
140
+ if aws_region :
141
+ cred_file .write (f'region={ aws_region } \n ' )
142
+ cred_file .write (f'aws_access_key_id={ key_id } \n ' )
143
+ cred_file .write (f'aws_secret_access_key={ secret } \n ' )
144
+ else :
145
+ with open (file_path , 'w' ) as cred_file :
146
+ cred_file .write (f'[{ profile_name } ]\n ' )
147
+ if aws_region :
148
+ cred_file .write (f'region={ aws_region } \n ' )
149
+ cred_file .write (f'aws_access_key_id={ key_id } \n ' )
150
+ cred_file .write (f'aws_secret_access_key={ secret } \n ' )
151
+ return file_path
152
+
153
+
154
+ def write_aws_cli_creds (key_id , secret , base_cred_path , aws_cred_list ):
155
+ aws_creds_tuples = []
156
+ have_all_info = False
157
+ for i , val in enumerate (aws_cred_list ):
158
+ if (i % 3 ) == 0 :
159
+ logging .debug (f'save-aws-creds - filename: { val } ' )
160
+ filename = val
161
+ elif (i % 3 ) == 1 :
162
+ logging .debug (f'save-aws-creds - profile name: { val } ' )
163
+ if '#' in val :
164
+ profile = val .replace ('#' , ' ' )
165
+ else :
166
+ profile = val
167
+ else :
168
+ logging .debug (f'save-aws-creds - region: { val } ' )
169
+ if 'none' in val .lower ():
170
+ region = None
171
+ else :
172
+ region = val
173
+ have_all_info = True
174
+
175
+ if have_all_info :
176
+ aws_creds_tuples .append ((filename , profile , region ))
177
+ have_all_info = False
178
+
179
+ if len (aws_creds_tuples ) > 0 :
180
+ logging .debug ('Provided with the following tuples:' )
181
+ logging .debug (f'{ aws_creds_tuples } ' )
182
+
183
+ # write to a tmp file first
184
+ temp_dir = tempfile .gettempdir ()
185
+ if not os .path .exists (temp_dir ):
186
+ os .makedirs (temp_dir )
187
+
188
+ aws_cred_files = []
189
+ for f , p , r in aws_creds_tuples :
190
+ tmp_cred_filepath = create_aws_cred_file (key_id , secret , temp_dir , f , p , r )
191
+ if tmp_cred_filepath not in aws_cred_files :
192
+ aws_cred_files .append (tmp_cred_filepath )
193
+
194
+ # Now copy the tmp files to the base_cred_path
195
+ for cred_file in aws_cred_files :
196
+ filename = cred_file .split (os .sep )[- 1 ]
197
+ new_file_path = f"{ base_cred_path } { os .sep } { filename } "
198
+ logger .info (f'Saving AWS Credentials to { new_file_path } ' )
199
+ shutil .copyfile (cred_file , new_file_path )
200
+ # Cleanup
201
+ logger .debug (f'Removing { cred_file } ' )
202
+ os .remove (cred_file )
203
+
204
+
133
205
if __name__ == "__main__" :
134
206
135
207
description = "Script to get all parameters from AWS Parameter\n "
@@ -147,6 +219,7 @@ def get_parameters_with_prefix(prefix, next_token=None):
147
219
parser .add_argument ("--param-prefix" , help = "Parameter prefix" , dest = 'param_prefix' , required = True )
148
220
parser .add_argument ("--credentials-path" , help = "Where credentials are stored" , dest = 'cred_path' , default = '/credentials/' )
149
221
parser .add_argument ("--verbose" , help = "Turn on DEBUG logging" , action = 'store_true' , required = False )
222
+ parser .add_argument ("--save-aws-creds" , help = "Save AWS Creds [filename, profile]" , nargs = '*' )
150
223
parser .add_argument ("--dryrun" , help = "Do a dryrun - no changes will be performed" , dest = 'dryrun' ,
151
224
action = 'store_true' , default = False ,
152
225
required = False )
@@ -163,8 +236,23 @@ def get_parameters_with_prefix(prefix, next_token=None):
163
236
logger .critical ('AWS Secret Access Key not set - cannot continue' )
164
237
165
238
logger .debug ('INIT' )
166
- logger .info ('Getting parameters with prefix %s from AWS Parameter Store' % args . param_prefix )
167
- logger .info ('Parameter values will be compared against file contents in "%s " and updated if necessary' % args . cred_path )
239
+ logger .info (f 'Getting parameters with prefix { args . param_prefix } from AWS Parameter Store' )
240
+ logger .info (f 'Parameter values will be compared against file contents in "{ args . cred_path } " and updated if necessary' )
168
241
process_parameters_with_prefix (args .param_prefix , args .cred_path , args .aws_region ,
169
242
args .aws_access_key , args .aws_secret_key , args .dryrun )
243
+
244
+ if args .save_aws_creds :
245
+ if args .aws_access_key and args .aws_secret_key :
246
+ aws_access_key = args .aws_access_key
247
+ aws_secret_key = args .aws_secret_key
248
+ else :
249
+ aws_access_key = os .environ .get ('AWS_ACCESS_KEY_ID' )
250
+ aws_secret_key = os .environ .get ('AWS_SECRET_ACCESS_KEY' )
251
+
252
+ if len (args .save_aws_creds ) % 3 != 0 :
253
+ logging .critical ('Must provide filename, profile_name and region for aws creds' )
254
+ sys .exit (1 )
255
+
256
+ result = write_aws_cli_creds (aws_access_key , aws_secret_key , args .cred_path , args .save_aws_creds )
257
+
170
258
logger .info ('COMPLETE' )
0 commit comments