-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow specifying precise timeframes that should be downloaded from S3 (…
…#11)
- Loading branch information
Showing
12 changed files
with
172 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
boto3>=1.4.7 | ||
click>=6.7 | ||
toolz>=0.8.2 | ||
toolz>=0.8.2 | ||
dateparser>=0.6.0 | ||
pytz>=2017.3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import datetime | ||
|
||
from backports import tempfile | ||
from click.testing import CliRunner | ||
from moto import mock_s3 | ||
|
||
from tests.test_utils_s3 import file_content, given_a_bucket, given_an_object, given_a_file | ||
from tests.test_utils_testdata import cloudtrail_data_dir | ||
from trailscraper import cli | ||
from trailscraper.s3_download import download_cloudtrail_logs | ||
|
||
TEST_LOG_KEY = "some-prefix/AWSLogs/000/CloudTrail/some-region-1/2017/01/01/file_name.json.gz" | ||
TEST_LOG_KEY_EXISTING = "some-prefix/AWSLogs/000/CloudTrail/some-region-1/2017/01/01/file_name_that_exists.json.gz" | ||
|
||
|
||
@mock_s3 | ||
def test_download_log_files_and_skip_existing_files(): | ||
with tempfile.TemporaryDirectory() as dirpath: | ||
given_a_bucket("some-bucket") | ||
given_an_object("some-bucket", TEST_LOG_KEY, "some-file-content") | ||
given_an_object("some-bucket", TEST_LOG_KEY_EXISTING, "some-file-content") | ||
|
||
given_a_file(dirpath, TEST_LOG_KEY_EXISTING, "some-content-already-existing") | ||
|
||
download_cloudtrail_logs( | ||
target_dir=dirpath, | ||
bucket="some-bucket", | ||
cloudtrail_prefix="some-prefix/", | ||
from_date=datetime.datetime(2017, 1, 1), | ||
to_date=datetime.datetime(2017, 1, 1), | ||
account_ids=["000"], | ||
regions=["some-region-1"]) | ||
|
||
runner = CliRunner() | ||
result = runner.invoke(cli.root_group, args=[ | ||
"download", | ||
"--bucket", "some-bucket", | ||
"--region", "some-region-1", | ||
"--account-id", "000", | ||
"--prefix", "some-prefix/", | ||
"--from", "2017-01-01", | ||
"--to", "2017-01-01" | ||
]) | ||
assert result.exit_code == 0 | ||
|
||
assert file_content(dirpath, TEST_LOG_KEY) == "some-file-content" | ||
assert file_content(dirpath, TEST_LOG_KEY_EXISTING) == "some-content-already-existing" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
from click.testing import CliRunner | ||
|
||
from trailscraper import cli | ||
|
||
|
||
def test_should_output_help_message_by_default(): | ||
runner = CliRunner() | ||
result = runner.invoke(cli.root_group) | ||
assert result.exit_code == 0 | ||
assert 'Usage:' in result.output |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,43 +1,51 @@ | ||
from freezegun import freeze_time | ||
import datetime | ||
|
||
from trailscraper.s3_download import _s3_key_prefixes | ||
|
||
|
||
@freeze_time("2017-01-01") | ||
def test_should_generate_a_single_prefix_for_today(): | ||
def test_should_generate_prefixes_for_one_day(): | ||
assert _s3_key_prefixes(prefix="some-prefix/", | ||
past_days=0, | ||
account_ids=["111"], | ||
regions=["some-region-1"]) == \ | ||
["some-prefix/AWSLogs/111/CloudTrail/some-region-1/2017/01/01"] | ||
account_ids=["000"], | ||
regions=["some-region-1"], | ||
from_date=datetime.datetime(2017, 1, 1), | ||
to_date=datetime.datetime(2017, 1, 1)) == \ | ||
["some-prefix/AWSLogs/000/CloudTrail/some-region-1/2017/01/01"] | ||
|
||
|
||
@freeze_time("2017-01-01") | ||
def test_should_generate_prefixes_for_multiple_accounts_today(): | ||
def test_should_generate_prefixes_for_multiple_accounts_on_one_day(): | ||
assert _s3_key_prefixes(prefix="some-prefix/", | ||
past_days=0, | ||
from_date=datetime.datetime(2017, 1, 1), | ||
to_date=datetime.datetime(2017, 1, 1), | ||
account_ids=["000", "111"], | ||
regions=["some-region-1"]) == \ | ||
["some-prefix/AWSLogs/000/CloudTrail/some-region-1/2017/01/01", | ||
"some-prefix/AWSLogs/111/CloudTrail/some-region-1/2017/01/01"] | ||
|
||
|
||
@freeze_time("2017-01-01") | ||
def test_should_generate_prefixes_for_regions(): | ||
def test_should_generate_prefixes_for_one_day_when_datetime_contains_time(): | ||
assert _s3_key_prefixes(prefix="some-prefix/", | ||
past_days=0, | ||
account_ids=["000"], | ||
regions=["some-region-1","some-region-2"]) == \ | ||
["some-prefix/AWSLogs/000/CloudTrail/some-region-1/2017/01/01", | ||
"some-prefix/AWSLogs/000/CloudTrail/some-region-2/2017/01/01"] | ||
regions=["some-region-1"], | ||
from_date=datetime.datetime(2017, 1, 1, 10, 0, 0), | ||
to_date=datetime.datetime(2017, 1, 1, 11, 0, 0)) == \ | ||
["some-prefix/AWSLogs/000/CloudTrail/some-region-1/2017/01/01"] | ||
|
||
|
||
@freeze_time("2017-01-01") | ||
def test_should_generate_prefixes_for_multiple_days_in_the_past(): | ||
def test_should_generate_prefixes_for_multiple_days(): | ||
assert _s3_key_prefixes(prefix="some-prefix/", | ||
past_days=2, | ||
account_ids=["000"], | ||
regions=["some-region-1"]) == \ | ||
regions=["some-region-1"], | ||
from_date=datetime.datetime(2017, 1, 1), | ||
to_date=datetime.datetime(2017, 1, 2)) == \ | ||
["some-prefix/AWSLogs/000/CloudTrail/some-region-1/2017/01/02", | ||
"some-prefix/AWSLogs/000/CloudTrail/some-region-1/2017/01/01", ] | ||
|
||
|
||
def test_should_generate_prefixes_for_regions(): | ||
assert _s3_key_prefixes(prefix="some-prefix/", | ||
from_date=datetime.datetime(2017, 1, 1), | ||
to_date=datetime.datetime(2017, 1, 1), | ||
account_ids=["000"], | ||
regions=["some-region-1", "some-region-2"]) == \ | ||
["some-prefix/AWSLogs/000/CloudTrail/some-region-1/2017/01/01", | ||
"some-prefix/AWSLogs/000/CloudTrail/some-region-1/2016/12/31", | ||
"some-prefix/AWSLogs/000/CloudTrail/some-region-1/2016/12/30", ] | ||
"some-prefix/AWSLogs/000/CloudTrail/some-region-2/2017/01/01"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import datetime | ||
|
||
import pytz | ||
|
||
from freezegun import freeze_time | ||
|
||
from trailscraper.time_utils import parse_human_readable_time | ||
|
||
|
||
def test_should_parse_full_dates(): | ||
assert parse_human_readable_time("2017-12-22") == \ | ||
datetime.datetime(2017, 12, 22, 0, 0, 0) | ||
|
||
|
||
def test_should_parse_full_datetimes(): | ||
assert parse_human_readable_time("2017-12-22 10:11:12") == \ | ||
datetime.datetime(2017, 12, 22, 10, 11, 12) | ||
|
||
@freeze_time("2010-11-12 13:14:15") | ||
def test_should_parse_human_readable_current_time(): | ||
assert parse_human_readable_time("now").astimezone(pytz.utc) == \ | ||
datetime.datetime(2010,11,12,13,14,15,tzinfo=pytz.utc) | ||
|
||
@freeze_time("2010-11-12 13:14:15") | ||
def test_should_parse_human_readable_relative_times(): | ||
assert parse_human_readable_time("one hour ago").astimezone(pytz.utc) == \ | ||
datetime.datetime(2010,11,12,12,14,15,tzinfo=pytz.utc) | ||
assert parse_human_readable_time("in 10 minutes").astimezone(pytz.utc) == \ | ||
datetime.datetime(2010,11,12,13,24,15,tzinfo=pytz.utc) | ||
|
||
assert parse_human_readable_time("-1 hour").astimezone(pytz.utc) == \ | ||
datetime.datetime(2010,11,12,12,14,15,tzinfo=pytz.utc) | ||
assert parse_human_readable_time("-1 day").astimezone(pytz.utc) == \ | ||
datetime.datetime(2010,11,11,13,14,15,tzinfo=pytz.utc) | ||
assert parse_human_readable_time("-10 minutes").astimezone(pytz.utc) == \ | ||
datetime.datetime(2010,11,12,13,4,15,tzinfo=pytz.utc) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
"""Functions to help parse strings into datetime objects""" | ||
import dateparser | ||
|
||
|
||
def parse_human_readable_time(time_string): | ||
"""Parse human readable strings (e.g. "now", "2017-01-01" and "one hour ago") into datetime""" | ||
return dateparser.parse(time_string) |