Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separates CredentialProvider from OutputDispatcher #875

Merged
merged 17 commits into from
Jan 30, 2019

Conversation

Ryxias
Copy link
Contributor

@Ryxias Ryxias commented Jan 14, 2019

to: @ryandeivert
cc: @airbnb/streamalert-maintainers

Background

Implementing a new OutputDispatcher requires a lot of in-depth understanding of how the base class is implemented, and testing it has dependencies on AWS S3, AWS KMS, os, and the filesystem. To write a good test, you will need to know how to mock all three of these out which is lot of boilerplate.

Example: TestPagerDutyOutput.setup/teardown

Changes

I refactored OutputDispatcher and decoupled the credentials logic out of the base class and into a new class, OutputCredentialsProvider. This class now becomes solely responsible for providing _load_creds() functionality to the parent class.

Benefit?

Now, when writing unit tests, instead of having to mock out many different things as boilerplate, we can simply use mock to patch the OutputCredentialsProvider class to always return stub credentials.

Example: Commit showing before/after

This reduces the amount of code slightly, and makes it slightly easier to understand.

Additionally, this PR contains all changes in #878, with the new notion of Drivers. This opens up an easier path in the future to build an integration with SSM (#240).

Other (Unrelated?) Changes

I DRY'd out some code here and there, and removed some private (?) methods from OutputDispatcher that I didn't see being used in production code, in order to simplify the class's interface and its inheritance model.

Testing

I'm not quite done yet but I'm adding new unit tests which are passing. Will paste results here shortly.

tests/scripts/unit_tests.sh

stream_alert/threat_intel_downloader/__init__.py          0      0   100%
stream_alert/threat_intel_downloader/exceptions.py        4      0   100%
stream_alert/threat_intel_downloader/main.py            134      1    99%   348
-----------------------------------------------------------------------------------
TOTAL                                                  4414     94    98%
[success] 1.76% tests.unit.stream_alert_alert_merger.test_main.TestAlertMerger.test_dispatch: 0.3028s
[success] 1.45% tests.unit.streamalert.classifier.clients.test_firehose.TestFirehoseClient.test_send_batch: 0.2494s
[success] 1.42% tests.unit.stream_alert_shared.test_rule.RuleImportTest.test_path_to_module: 0.2436s
[success] 1.05% tests.unit.stream_alert_apps.test_apps.test_aliyun.TestAliyunApp.test_date_formatter: 0.1794s
[success] 0.99% tests.unit.stream_alert_alert_processor.test_outputs.test_pagerduty.TestPagerDutyIncidentOutput.test_dispatch_success_no_context: 0.1701s
[success] 0.99% tests.unit.stream_alert_shared.test_config.TestConfigLoading.test_load_invalid_file: 0.1696s
[success] 0.85% tests.unit.stream_alert_alert_processor.test_outputs.test_github.TestGithubOutput.test_dispatch_failure: 0.1454s
[success] 0.84% tests.unit.stream_alert_shared.test_rule.RuleImportTest.test_import_rules: 0.1447s
[success] 0.81% tests.unit.stream_alert_shared.test_config.TestConfigLoading.test_load_include: 0.1398s
[success] 0.81% tests.unit.stream_alert_shared.test_alert_table.TestAlertTable.test_get_alert_records: 0.1383s
----------------------------------------------------------------------
Ran 882 tests in 17.284s

OK

tests/scripts/rule_test.sh

Summary:

Total Tests: 77
Pass: 77
Fail: 0

[INFO 2019-01-14 15:48:57,377 (stream_alert_cli.runner:85)]: Completed

@Ryxias
Copy link
Contributor Author

Ryxias commented Jan 14, 2019

Per @ryandeivert 's comment worth keeping #240 in mind

@coveralls
Copy link

coveralls commented Jan 15, 2019

Coverage Status

Coverage increased (+0.02%) to 97.131% when pulling cde8b20 on dw--output-credentials-provider into 6334ede on master.

@Ryxias Ryxias force-pushed the dw--output-credentials-provider branch from 9340d27 to 8180c71 Compare January 15, 2019 01:00
Copy link
Contributor

@ryandeivert ryandeivert left a comment

Choose a reason for hiding this comment

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

thank you for the work on this @Ryxias !! looking good so far, a handful of comments :)

"""Get the local tmp directory for caching the encrypted service credentials
OutputDispatcher implementations may require credentials to authenticate with an external
gateway. All credentials for OutputDispatchers are to be stored in a single bucket on AWS S3
and are encrypted with AWS KMS. When the OutputDispatchers are booted, this these encrypted
Copy link
Contributor

Choose a reason for hiding this comment

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

typo: this these

also 'booted' might not be the right verbiage :P

stream_alert/alert_processor/outputs/output_base.py Outdated Show resolved Hide resolved
stream_alert/alert_processor/outputs/output_base.py Outdated Show resolved Hide resolved
stream_alert/alert_processor/outputs/output_base.py Outdated Show resolved Hide resolved
stream_alert/alert_processor/outputs/output_base.py Outdated Show resolved Hide resolved
stream_alert/alert_processor/outputs/output_base.py Outdated Show resolved Hide resolved
stream_alert/alert_processor/outputs/output_base.py Outdated Show resolved Hide resolved
stream_alert/alert_processor/outputs/output_base.py Outdated Show resolved Hide resolved
@Ryxias Ryxias force-pushed the dw--output-credentials-provider branch from 703db22 to f241094 Compare January 19, 2019 00:10
Copy link
Contributor

@ryandeivert ryandeivert left a comment

Choose a reason for hiding this comment

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

great work so far @Ryxias - leaving a handful of comments/questions for you

stream_alert_cli/outputs/handler.py Outdated Show resolved Hide resolved
@Ryxias
Copy link
Contributor Author

Ryxias commented Jan 28, 2019

@ryandeivert I've added a Fixup that addresses your comments, PTAL

(I also added stream_alert.shared.helps.aws_api_client.py)

@Ryxias
Copy link
Contributor Author

Ryxias commented Jan 28, 2019

OH no i Messed up i put it on the wrong branch... hold on..

@Ryxias Ryxias force-pushed the dw--output-credentials-provider branch from 96cdd52 to f104123 Compare January 28, 2019 20:24
Ryxias and others added 15 commits January 28, 2019 12:24
* Working? Draft of new driver-based credentials storage

* Higher quality refactor; needs tests

* Kinks ironed out with good tests this time

* First maybe working try

* Adds lots of tests for the Drivers

* Add more tests. Not final; still need to remove deprecated methods

* Rename method to reduce confusion

* Remove deprecated method load_encrypted_credentials_from_s3

* Removes deprecated method get_local_credentials_temp_dir

* Remove deprecated method get_formatted_output_credentials_name

* Removes deprecated method kms_decrypt

* Removes extraneous imports

* Extract globally injected REGION so the handler can be implemented properly

* Pylint`

* Pylint is my nemesis

* Remove extraneous method

* Use default_config for boto clients

* Code coverage. PR feedback.

* Add missing __init__.py file causing poor code coverage

* Fixes the tests to get past pylint garbage
@Ryxias Ryxias force-pushed the dw--output-credentials-provider branch from f104123 to 92da1c5 Compare January 28, 2019 20:25
@Ryxias
Copy link
Contributor Author

Ryxias commented Jan 28, 2019

There we go @ryandeivert I fixed it, PTAL

from botocore.exceptions import ClientError

from stream_alert.shared.logger import get_logger
from stream_alert.shared.helpers.aws_api_client import AwsS3, AwsKms
Copy link
Contributor

Choose a reason for hiding this comment

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

this import should go before the previous line (h < l)

client.put_object(Body=blob_data, Bucket=bucket, Key=key)

return True
return AwsS3.put_object(blob_data, bucket=bucket, key=key, region=region)
Copy link
Contributor

Choose a reason for hiding this comment

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

nice changes - if this function (send_creds_to_s3) is in fact not being anywhere else, you can freely remove it

@Ryxias
Copy link
Contributor Author

Ryxias commented Jan 30, 2019

Done; I removed the deprecated code and added tests to replace the old ones that are gone

Copy link
Contributor

@ryandeivert ryandeivert left a comment

Choose a reason for hiding this comment

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

🚢 👍 thank you @Ryxias !

@Ryxias Ryxias merged commit 44fe7d0 into master Jan 30, 2019
@Ryxias Ryxias deleted the dw--output-credentials-provider branch January 31, 2019 22:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants