Skip to content
This repository has been archived by the owner on Jun 5, 2023. It is now read-only.

Allow user to specify the violation payload format (csv / json) #1301

Merged
merged 22 commits into from
Mar 27, 2018

Conversation

arbeit
Copy link
Contributor

@arbeit arbeit commented Mar 26, 2018

Fully tested; switching between CSV and JSON works by specifying a data_format configuration setting for the notifier in question (with CSV being the default).

Fixes issue #1287.

@arbeit arbeit changed the base branch from dev to 2.0-dev March 26, 2018 15:01
@arbeit arbeit requested a review from blueandgold March 26, 2018 15:02
@codecov
Copy link

codecov bot commented Mar 26, 2018

Codecov Report

Merging #1301 into 2.0-dev will increase coverage by 0.26%.
The diff coverage is 98.14%.

@@             Coverage Diff             @@
##           2.0-dev    #1301      +/-   ##
===========================================
+ Coverage     86.7%   86.97%   +0.26%     
===========================================
  Files          148      148              
  Lines        10270    10304      +34     
===========================================
+ Hits          8905     8962      +57     
+ Misses        1365     1342      -23
Impacted Files Coverage Δ
...ud/forseti/notifier/notifiers/base_notification.py 96.15% <100%> (+2.82%) ⬆️
...oud/forseti/notifier/notifiers/email_violations.py 96.92% <100%> (+40.31%) ⬆️
...cloud/forseti/notifier/notifiers/gcs_violations.py 96.87% <95.23%> (-3.13%) ⬇️
google/cloud/forseti/common/util/date_time.py 61.53% <0%> (+11.53%) ⬆️

@arbeit arbeit changed the title [WIP] allow user to specify violation payload format Allow user to specify the violation payload format (csv / json) Mar 26, 2018
Copy link
Contributor

@blueandgold blueandgold left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great overall. First pass with some comments, and then I'll look at the tests on next pass.

str: The output filename for the violations CSV file.
"""
now_utc = date_time.get_utc_now_datetime()
output_timestamp = now_utc.strftime(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: you should just call this variable, utc_now_datetime since that is what you got back from above, and also shows why strftime can be called here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


Returns:
attachment: SendGrid attachment object.
"""
output_file_name = self._get_output_filename()
output_file_name = self._get_output_filename(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: be consistent whether you want to use file_name or filename

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

LOGGER.info('JSON filename: %s', tmp_violations.name)
attachment = self.mail_util.create_attachment(
file_location=tmp_violations.name,
content_type='text/csv', filename=output_file_name,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix the content_type

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

LOGGER.info('JSON filename: %s', tmp_violations.name)
attachment = self.mail_util.create_attachment(
file_location=tmp_violations.name,
content_type='text/csv', filename=output_file_name,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can you put filename=output_file_name, on a new line? Just to be consistent with the indentings here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

email_map['content'] = content
email_map['attachment'] = attachment
data_format = self.notification_config.get('data_format', 'csv')
if data_format not in ['json', 'csv']:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to suggest breaking out ['json', 'csv'] into a separate variable like supported_data_format, then it's easy to maintain and read.

supported_data_format = ['json', 'csv']
if data_format not in supported_data_format:
    blah blah blah

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

email_map['attachment'] = attachment
data_format = self.notification_config.get('data_format', 'csv')
if data_format not in ['json', 'csv']:
LOGGER.error(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nicer to raise a custom exception here. Perhaps something like UnsupportedNotificationDataFormat, and make the caller handle this via try/except.

Then, you can remove the else here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

"""Generate the temporary (CSV xor JSON) file and upload to GCS."""
if self.notification_config['gcs_path'].startswith('gs://'):
data_format = self.notification_config.get('data_format', 'csv')
if data_format not in ['json', 'csv']:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the second time this is checked, see my comment above in _make_content(). I think it's better to check and raise here early on.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

data_format = self.notification_config.get('data_format', 'csv')
if data_format not in ['json', 'csv']:
LOGGER.error('GCS upload: invalid data format: %s', data_format)
elif data_format == 'csv':
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like to break up the nested if-if-elif-else here.

if not self.notification_config['gcs_path'].startswith('gs://'):
    log.error()
    return

if data_format not in supported_data_format:
    log.error()
    raise

if data_format == 'json':
    send json
else:
    send csv

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@blueandgold blueandgold merged commit ca9c013 into forseti-security:2.0-dev Mar 27, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants