From a5a17a78d88f717f0394f33e594f3e5e093da1e4 Mon Sep 17 00:00:00 2001 From: sapirgali Date: Mon, 12 Apr 2021 14:36:55 +0300 Subject: [PATCH 1/4] find s3 bucket name from uri (and not just from host) --- src/lumigo_tracer/wrappers/http/http_parser.py | 5 ++++- src/test/unit/wrappers/http/test_http_parser.py | 9 +++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/lumigo_tracer/wrappers/http/http_parser.py b/src/lumigo_tracer/wrappers/http/http_parser.py index 77ea3d61..46d9cc60 100644 --- a/src/lumigo_tracer/wrappers/http/http_parser.py +++ b/src/lumigo_tracer/wrappers/http/http_parser.py @@ -247,8 +247,11 @@ def _extract_message_id(response_body: bytes) -> Optional[str]: class S3Parser(Parser): def parse_request(self, parse_params: HttpRequest) -> dict: + resource_name = safe_split_get(parse_params.host, ".", 0) + if not resource_name: + resource_name = safe_split_get(parse_params.uri, "/", 1) return recursive_json_join( - {"info": {"resourceName": safe_split_get(parse_params.host, ".", 0)}}, + {"info": {"resourceName": resource_name}}, super().parse_request(parse_params), ) diff --git a/src/test/unit/wrappers/http/test_http_parser.py b/src/test/unit/wrappers/http/test_http_parser.py index 1f7da202..50d66205 100644 --- a/src/test/unit/wrappers/http/test_http_parser.py +++ b/src/test/unit/wrappers/http/test_http_parser.py @@ -12,6 +12,7 @@ DynamoParser, EventBridgeParser, LambdaParser, + S3Parser, ) @@ -250,6 +251,14 @@ def test_event_bridge_parser_request_sad_flow(): assert response["info"]["resourceNames"] is None +def test_s3_parser_resource_name(): + parser = S3Parser() + uri = "s3.eu-west-1.amazonaws.com/public.sapir.com/attachments/-1/321012/2021/3/31/sapir.pdf" + params = HttpRequest(host="", method="POST", uri=uri, headers={}, body="not a json") + response = parser.parse_request(params) + assert response["info"]["resourceName"] == "public.sapir.com" + + def test_event_bridge_parser_response_happy_flow(): parser = EventBridgeParser() response = parser.parse_response( From 8fb631873bc4bf13b34d8e2ca88f3c41515a7957 Mon Sep 17 00:00:00 2001 From: sapirgali Date: Tue, 13 Apr 2021 14:33:47 +0300 Subject: [PATCH 2/4] find s3 bucket name from uri (and not just from host) add tests to all cases --- .../wrappers/http/http_parser.py | 2 +- .../unit/wrappers/http/test_http_parser.py | 46 +++++++++++++++++-- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/lumigo_tracer/wrappers/http/http_parser.py b/src/lumigo_tracer/wrappers/http/http_parser.py index 46d9cc60..eef0b367 100644 --- a/src/lumigo_tracer/wrappers/http/http_parser.py +++ b/src/lumigo_tracer/wrappers/http/http_parser.py @@ -248,7 +248,7 @@ def _extract_message_id(response_body: bytes) -> Optional[str]: class S3Parser(Parser): def parse_request(self, parse_params: HttpRequest) -> dict: resource_name = safe_split_get(parse_params.host, ".", 0) - if not resource_name: + if resource_name == "s3": resource_name = safe_split_get(parse_params.uri, "/", 1) return recursive_json_join( {"info": {"resourceName": resource_name}}, diff --git a/src/test/unit/wrappers/http/test_http_parser.py b/src/test/unit/wrappers/http/test_http_parser.py index 50d66205..e8fb8392 100644 --- a/src/test/unit/wrappers/http/test_http_parser.py +++ b/src/test/unit/wrappers/http/test_http_parser.py @@ -251,12 +251,50 @@ def test_event_bridge_parser_request_sad_flow(): assert response["info"]["resourceNames"] is None -def test_s3_parser_resource_name(): +def test_s3_parser_resource_name_uri(): parser = S3Parser() - uri = "s3.eu-west-1.amazonaws.com/public.sapir.com/attachments/-1/321012/2021/3/31/sapir.pdf" - params = HttpRequest(host="", method="POST", uri=uri, headers={}, body="not a json") + uri = "s3.eu-west-1.amazonaws.com/my.s3-bucket1.com/documents/2021/3/31/file.pdf" + params = HttpRequest( + host="s3.eu-west-1.amazonaws.com", + method="PUT", + uri=uri, + headers={ + "x-amz-copy-source": "my-s3-bucket1/documents/2021/3/31/file2.pdf", + "user-agent": "Boto3/1.16.31 Python/3.7.10 Linux/4.14.219-169.354.amzn2.x86_64 exec-env/AWS_Lambda_python3.7 Botocore/1.19.31", + "x-amzn-trace-id": "Root=test;Parent=test0;Sampled=0", + "x-amz-date": "20210331T090545Z", + "x-amz-security-token": "test_security-token", + "x-amz-content-sha256": "test_x-amz-content-sha256", + "authorization": "test_authorization", + "content-length": "0", + }, + body="not a json", + ) + response = parser.parse_request(params) + assert response["info"]["resourceName"] == "my.s3-bucket1.com" + + +def test_s3_parser_resource_name_host(): + parser = S3Parser() + uri = "my-s3-bucket.s3.us-west-2.amazonaws.com/documents/2021/3/31/file.pdf" + params = HttpRequest( + host="my-s3-bucket.com.s3.us-west-2.amazonaws.com", + method="HEAD", + uri=uri, + headers={ + "x-amz-copy-source": "my-s3-bucket1/documents//2021/3/31/file2.pdf", + "user-agent": "Boto3/1.16.31 Python/3.7.10 Linux/4.14.219-169.354.amzn2.x86_64 exec-env/AWS_Lambda_python3.7 Botocore/1.19.31", + "x-amzn-trace-id": "Root=test;Parent=test0;Sampled=0", + "x-amz-date": "20210331T090545Z", + "x-amz-security-token": "test_security-token", + "x-amz-content-sha256": "test_x-amz-content-sha256", + "authorization": "test_authorization", + "content-length": "0", + }, + body="not a json", + ) response = parser.parse_request(params) - assert response["info"]["resourceName"] == "public.sapir.com" + assert response["info"]["resourceName"] == "my-s3-bucket" def test_event_bridge_parser_response_happy_flow(): From 64e8c47f9942b8548e63d2131429203d32c95b78 Mon Sep 17 00:00:00 2001 From: sapirgali Date: Tue, 13 Apr 2021 17:47:53 +0300 Subject: [PATCH 3/4] find s3 bucket name from uri (and not just from host) add tests to all cases --- .../wrappers/http/http_parser.py | 2 +- .../unit/wrappers/http/test_http_parser.py | 58 +++++++------------ 2 files changed, 21 insertions(+), 39 deletions(-) diff --git a/src/lumigo_tracer/wrappers/http/http_parser.py b/src/lumigo_tracer/wrappers/http/http_parser.py index eef0b367..819cfea4 100644 --- a/src/lumigo_tracer/wrappers/http/http_parser.py +++ b/src/lumigo_tracer/wrappers/http/http_parser.py @@ -321,7 +321,7 @@ def get_parser(url: str, headers: Optional[dict] = None) -> Type[Parser]: return KinesisParser elif service == "events": return EventBridgeParser - elif safe_split_get(url, ".", 1) == "s3": + elif safe_split_get(url, ".", 1) == "s3" or safe_split_get(url, ".", 0) == "s3": return S3Parser # SQS Legacy Endpoints: https://docs.aws.amazon.com/general/latest/gr/rande.html elif service in ("sqs", "sqs-fips") or "queue.amazonaws.com" in url: diff --git a/src/test/unit/wrappers/http/test_http_parser.py b/src/test/unit/wrappers/http/test_http_parser.py index e8fb8392..8c8c50d9 100644 --- a/src/test/unit/wrappers/http/test_http_parser.py +++ b/src/test/unit/wrappers/http/test_http_parser.py @@ -251,50 +251,32 @@ def test_event_bridge_parser_request_sad_flow(): assert response["info"]["resourceNames"] is None -def test_s3_parser_resource_name_uri(): +@pytest.mark.parametrize( + "uri, resource_name, host", + [ + ( + "s3.eu-west-1.amazonaws.com/my.s3-bucket1.com/documents/2021/3/31/file.pdf", + "my.s3-bucket1.com", + "s3.eu-west-1.amazonaws.com", + ), + ( + "my-s3-bucket.s3.us-west-2.amazonaws.com/documents/2021/3/31/file.pdf", + "my-s3-bucket", + "my-s3-bucket.s3.us-west-2.amazonaws.com", + ), + ], +) +def test_s3_parser_resource_name(uri, resource_name, host): parser = S3Parser() - uri = "s3.eu-west-1.amazonaws.com/my.s3-bucket1.com/documents/2021/3/31/file.pdf" params = HttpRequest( - host="s3.eu-west-1.amazonaws.com", + host=host, method="PUT", uri=uri, - headers={ - "x-amz-copy-source": "my-s3-bucket1/documents/2021/3/31/file2.pdf", - "user-agent": "Boto3/1.16.31 Python/3.7.10 Linux/4.14.219-169.354.amzn2.x86_64 exec-env/AWS_Lambda_python3.7 Botocore/1.19.31", - "x-amzn-trace-id": "Root=test;Parent=test0;Sampled=0", - "x-amz-date": "20210331T090545Z", - "x-amz-security-token": "test_security-token", - "x-amz-content-sha256": "test_x-amz-content-sha256", - "authorization": "test_authorization", - "content-length": "0", - }, - body="not a json", - ) - response = parser.parse_request(params) - assert response["info"]["resourceName"] == "my.s3-bucket1.com" - - -def test_s3_parser_resource_name_host(): - parser = S3Parser() - uri = "my-s3-bucket.s3.us-west-2.amazonaws.com/documents/2021/3/31/file.pdf" - params = HttpRequest( - host="my-s3-bucket.com.s3.us-west-2.amazonaws.com", - method="HEAD", - uri=uri, - headers={ - "x-amz-copy-source": "my-s3-bucket1/documents//2021/3/31/file2.pdf", - "user-agent": "Boto3/1.16.31 Python/3.7.10 Linux/4.14.219-169.354.amzn2.x86_64 exec-env/AWS_Lambda_python3.7 Botocore/1.19.31", - "x-amzn-trace-id": "Root=test;Parent=test0;Sampled=0", - "x-amz-date": "20210331T090545Z", - "x-amz-security-token": "test_security-token", - "x-amz-content-sha256": "test_x-amz-content-sha256", - "authorization": "test_authorization", - "content-length": "0", - }, - body="not a json", + headers={}, + body="", ) response = parser.parse_request(params) - assert response["info"]["resourceName"] == "my-s3-bucket" + assert response["info"]["resourceName"] == resource_name def test_event_bridge_parser_response_happy_flow(): From 8b32299747fd5669d2f98667f202ed27b0166e55 Mon Sep 17 00:00:00 2001 From: sapirgali Date: Tue, 13 Apr 2021 18:06:17 +0300 Subject: [PATCH 4/4] add test --- src/test/unit/wrappers/http/test_http_parser.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/test/unit/wrappers/http/test_http_parser.py b/src/test/unit/wrappers/http/test_http_parser.py index 8c8c50d9..3097df56 100644 --- a/src/test/unit/wrappers/http/test_http_parser.py +++ b/src/test/unit/wrappers/http/test_http_parser.py @@ -32,6 +32,12 @@ def test_get_parser_check_headers(): assert get_parser(url, headers) == ServerlessAWSParser +def test_get_parser_s3(): + url = "s3.eu-west-1.amazonaws.com" + headers = {"key": "value"} + assert get_parser(url, headers) == S3Parser + + def test_get_parser_apigw(): url = "https://ne3kjv28fh.execute-api.us-west-2.amazonaws.com/doriaviram" assert get_parser(url, {}) == ApiGatewayV2Parser