@@ -160,36 +160,36 @@ def createCWEvent(event):
160160 t = int (t * 1000 + msecond )
161161 #
162162 # Build the message to send to CloudWatch.
163- str = f"Date={ event ['System' ]['TimeCreated' ]['@SystemTime' ]} , "
164- str += f"Event={ event ['System' ]['EventName' ].replace (' ' , '-' )} , " # Replace spaces with dashes.
165- str += f"fs={ event ['System' ]['Computer' ].split ('/' )[0 ]} , "
166- str += f"svm={ event ['System' ]['Computer' ].split ('/' )[1 ]} , "
167- str += f"Result={ event ['System' ]['Result' ].replace (' ' , '-' )} " # Replace spaces with dashes.
163+ cwData = f"Date={ event ['System' ]['TimeCreated' ]['@SystemTime' ]} , "
164+ cwData += f"Event={ event ['System' ]['EventName' ].replace (' ' , '-' )} , " # Replace spaces with dashes.
165+ cwData += f"fs={ event ['System' ]['Computer' ].split ('/' )[0 ]} , "
166+ cwData += f"svm={ event ['System' ]['Computer' ].split ('/' )[1 ]} , "
167+ cwData += f"Result={ event ['System' ]['Result' ].replace (' ' , '-' )} " # Replace spaces with dashes.
168168 #
169169 # Add the data fields to the message. Some fields are ignored. Some required special handling.
170170 for data in event ['EventData' ]['Data' ]:
171171 if data ['@Name' ] not in ignoredDataFields :
172172 if data ['@Name' ] == 'SubjectIP' :
173- str += f", IP={ data ['#text' ]} "
173+ cwData += f", IP={ data ['#text' ]} "
174174 elif data ['@Name' ] == 'SubjectUnix' :
175- str += f", UnixID={ data ['@Uid' ]} , GroupID={ data ['@Gid' ]} "
175+ cwData += f", UnixID={ data ['@Uid' ]} , GroupID={ data ['@Gid' ]} "
176176 elif data ['@Name' ] == 'SubjectUserSid' :
177- str += f", UserSid={ data ['#text' ]} "
177+ cwData += f", UserSid={ data ['#text' ]} "
178178 elif data ['@Name' ] == 'SubjectUserName' :
179- str += f", UserName={ data ['#text' ]} "
179+ cwData += f", UserName={ data ['#text' ]} "
180180 elif data ['@Name' ] == 'SubjectDomainName' :
181- str += f", Domain={ data ['#text' ]} "
181+ cwData += f", Domain={ data ['#text' ]} "
182182 elif data ['@Name' ] == 'ObjectName' or data ['@Name' ] == 'FileName' :
183- str += f", volume={ data ['#text' ].split (';' )[0 ].replace ('(' , '' ).replace (')' , '' )} , name={ data ['#text' ].split (';' )[1 ]} "
183+ cwData += f", volume={ data ['#text' ].split (';' )[0 ].replace ('(' , '' ).replace (')' , '' )} , name={ data ['#text' ].split (';' )[1 ]} "
184184 elif data ['@Name' ] == 'InformationSet' :
185185 if data .get ('#text' ) == None :
186- str += ", InformationSet=Null"
186+ cwData += ", InformationSet=Null"
187187 else :
188- str += f", InformationSet={ data ['#text' ]} "
188+ cwData += f", InformationSet={ data ['#text' ]} "
189189 else : # Assume the rest of the fields don't need special handling.
190- str += f", { data ['@Name' ]} ={ data ['#text' ]} "
190+ cwData += f", { data ['@Name' ]} ={ data ['#text' ]} "
191191
192- return {'timestamp' : t , 'message' : str }
192+ return {'timestamp' : t , 'message' : cwData }
193193
194194################################################################################
195195# This function uploads the audit log events stored in XML format to a
@@ -201,9 +201,9 @@ def ingestAuditFile(auditLogPath, auditLogName):
201201 # Convert the XML audit log file into a dictionary.
202202 f = open (auditLogPath , 'r' )
203203 data = f .read ()
204- dict = xmltodict .parse (data )
204+ dictData = xmltodict .parse (data )
205205
206- if dict .get ('Events' ) == None or dict ['Events' ].get ('Event' ) == None :
206+ if dictData .get ('Events' ) == None or dictData ['Events' ].get ('Event' ) == None :
207207 print (f"No events found in { auditLogName } " )
208208 return
209209 #
@@ -218,20 +218,30 @@ def ingestAuditFile(auditLogPath, auditLogName):
218218 #
219219 # If there is only one event, then the dict['Events']['Event'] will be a
220220 # dictionary, otherwise it will be a list of dictionaries.
221- if type ( dict ['Events' ]['Event' ]) == list :
221+ if isinstance ( dictData ['Events' ]['Event' ], list ) :
222222 cwEvents = []
223- for event in dict ['Events' ]['Event' ]:
223+ for event in dictData ['Events' ]['Event' ]:
224224 cwEvents .append (createCWEvent (event ))
225225 if len (cwEvents ) == 5000 : # The real maximum is 10000 events, but there is also a size limit, so we will use 5000.
226- print (f"Putting 5000 events" )
227- reponse = cwLogsClient .put_log_events (logGroupName = config ['logGroupName' ], logStreamName = auditLogName , logEvents = cwEvents )
226+ print ("Putting 5000 events" )
227+ response = cwLogsClient .put_log_events (logGroupName = config ['logGroupName' ], logStreamName = auditLogName , logEvents = cwEvents )
228+ if response .get ('rejectedLogEventsInfo' ) != None :
229+ if response ['rejectedLogEventsInfo' ].get ('tooNewLogEventStartIndex' ) > 0 :
230+ print (f"Warning: Too new log event start index: { response ['rejectedLogEventsInfo' ]['tooNewLogEventStartIndex' ]} " )
231+ if response ['rejectedLogEventsInfo' ].get ('tooOldLogEventStartIndex' ) > 0 :
232+ print (f"Warning: Too old log event start index: { response ['rejectedLogEventsInfo' ]['tooOldLogEventStartIndex' ]} " )
228233 cwEvents = []
229234 else :
230- cwEvents = [createCWEvent (dict ['Events' ]['Event' ])]
235+ cwEvents = [createCWEvent (dictData ['Events' ]['Event' ])]
231236
232237 if len (cwEvents ) > 0 :
233238 print (f"Putting { len (cwEvents )} events" )
234239 response = cwLogsClient .put_log_events (logGroupName = config ['logGroupName' ], logStreamName = auditLogName , logEvents = cwEvents )
240+ if response .get ('rejectedLogEventsInfo' ) != None :
241+ if response ['rejectedLogEventsInfo' ].get ('tooNewLogEventStartIndex' ) > 0 :
242+ print (f"Warning: Too new log event start index: { response ['rejectedLogEventsInfo' ]['tooNewLogEventStartIndex' ]} " )
243+ if response ['rejectedLogEventsInfo' ].get ('tooOldLogEventStartIndex' ) > 0 :
244+ print (f"Warning: Too old log event start index: { response ['rejectedLogEventsInfo' ]['tooOldLogEventStartIndex' ]} " )
235245
236246################################################################################
237247# This function checks that all the required configuration variables are set.
@@ -240,15 +250,15 @@ def checkConfig():
240250 global config
241251
242252 config = {
243- 'volumeName' : volumeName if 'volumeName' in globals () else None ,
244- 'logGroupName' : logGroupName if 'logGroupName' in globals () else None ,
245- 'fsxRegion' : fsxRegion if 'fsxRegion' in globals () else None ,
246- 'secretRegion' : secretRegion if 'secretRegion' in globals () else None ,
247- 'secretArn' : secretArn if 'secretArn' in globals () else None ,
248- 's3BucketRegion' : s3BucketRegion if 's3BucketRegion' in globals () else None ,
249- 's3BucketName' : s3BucketName if 's3BucketName' in globals () else None ,
250- 'statsName' : statsName if 'statsName' in globals () else None ,
251- 'vserverName' : vserverName if 'vserverName' in globals () else None
253+ 'volumeName' : volumeName if 'volumeName' in globals () else None , # pylint: disable=E0602
254+ 'logGroupName' : logGroupName if 'logGroupName' in globals () else None , # pylint: disable=E0602
255+ 'fsxRegion' : fsxRegion if 'fsxRegion' in globals () else None , # pylint: disable=E0602
256+ 'secretRegion' : secretRegion if 'secretRegion' in globals () else None , # pylint: disable=E0602
257+ 'secretArn' : secretArn if 'secretArn' in globals () else None , # pylint: disable=E0602
258+ 's3BucketRegion' : s3BucketRegion if 's3BucketRegion' in globals () else None , # pylint: disable=E0602
259+ 's3BucketName' : s3BucketName if 's3BucketName' in globals () else None , # pylint: disable=E0602
260+ 'statsName' : statsName if 'statsName' in globals () else None , # pylint: disable=E0602
261+ 'vserverName' : vserverName if 'vserverName' in globals () else None # pylint: disable=E0602
252262 }
253263
254264 for item in config :
@@ -261,7 +271,7 @@ def checkConfig():
261271# This is the main function that checks that everything is configured correctly
262272# and then processes all the FSxNs.
263273################################################################################
264- def lambda_handler (event , context ):
274+ def lambda_handler (event , context ): # pylint: disable=W0613
265275 global http , cwLogsClient , config
266276 #
267277 # Check that we have all the configuration variables we need.
0 commit comments