-
Notifications
You must be signed in to change notification settings - Fork 1.4k
chore: add integration tests around Serverless ASM #20320
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
Merged
RomainMuller
merged 27 commits into
main
from
romain.marcadier/appsec-integ-tests/APPSEC-11221
Nov 7, 2023
Merged
Changes from 20 commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
36be27a
chore: add integration tests around Serverless ASM
RomainMuller 1bb5c16
record new cases in the build scripts
RomainMuller daf14fb
update snapshots + some tuning
RomainMuller 9ac55b1
improve normalization procedure
RomainMuller f3b3406
linter fix
RomainMuller 4118cc7
better isolate integration test suites (improved specificity of pass/…
RomainMuller 1574db9
improved doc in run.sh
RomainMuller 6b31944
print out selected test suite when one has been selected...
RomainMuller 5a35b8e
wait for 2 reports to have been emitted
RomainMuller 74d2418
output raw logs on test failure
RomainMuller f4aac42
update default node layer version to latest
RomainMuller dd95ef5
add necessary node configuration, duh
RomainMuller e6f87e3
scope down except block
RomainMuller 49464fc
reduce breaking changes
RomainMuller 8a43602
Merge remote-tracking branch 'origin/main' into romain.marcadier/apps…
RomainMuller e453f72
improve prefix check
RomainMuller fbd5da4
re-normalize existing snapshots
RomainMuller 46a9d1f
remove editor-inserted semicolons
RomainMuller d8a41c7
sort imports in python file
RomainMuller e8a2acc
Merge remote-tracking branch 'origin/main' into romain.marcadier/apps…
RomainMuller 1a0df31
flat_map --> flatmap
RomainMuller 273e07d
no raw log output, just print location
RomainMuller b2b7a5b
pin + update snapshots
RomainMuller f8d754c
update snapshots
RomainMuller 293034e
remove tracer hostname from traces normalization
RomainMuller 1339f0e
Merge remote-tracking branch 'origin/main' into romain.marcadier/apps…
RomainMuller 151758e
Merge remote-tracking branch 'origin/main' into romain.marcadier/apps…
RomainMuller File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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,70 @@ | ||
| { | ||
| "version": "1.0", | ||
| "resource": "/my/path", | ||
| "path": "/my/path", | ||
| "httpMethod": "GET", | ||
| "headers": { | ||
| "User-Agent": "Arachni/v1" | ||
| }, | ||
| "multiValueHeaders": { | ||
| "User-Agent": [ | ||
| "Arachni/v1" | ||
| ] | ||
| }, | ||
| "queryStringParameters": { | ||
| "sql": "UNION SELECT password FROM users" | ||
| }, | ||
| "multiValueQueryStringParameters": { | ||
| "sql": [ | ||
| "UNION SELECT password FROM users" | ||
| ] | ||
| }, | ||
| "requestContext": { | ||
| "accountId": "123456789012", | ||
| "apiId": "id", | ||
| "authorizer": { | ||
| "claims": null, | ||
| "scopes": null | ||
| }, | ||
| "domainName": "id.execute-api.us-east-1.amazonaws.com", | ||
| "domainPrefix": "id", | ||
| "extendedRequestId": "request-id", | ||
| "httpMethod": "GET", | ||
| "identity": { | ||
| "accessKey": null, | ||
| "accountId": null, | ||
| "caller": null, | ||
| "cognitoAuthenticationProvider": null, | ||
| "cognitoAuthenticationType": null, | ||
| "cognitoIdentityId": null, | ||
| "cognitoIdentityPoolId": null, | ||
| "principalOrgId": null, | ||
| "sourceIp": "192.0.2.1", | ||
| "user": null, | ||
| "userAgent": "user-agent", | ||
| "userArn": null, | ||
| "clientCert": { | ||
| "clientCertPem": "CERT_CONTENT", | ||
| "subjectDN": "www.example.com", | ||
| "issuerDN": "Example issuer", | ||
| "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", | ||
| "validity": { | ||
| "notBefore": "May 28 12:30:02 2019 GMT", | ||
| "notAfter": "Aug 5 09:36:04 2021 GMT" | ||
| } | ||
| } | ||
| }, | ||
| "path": "/my/path", | ||
| "protocol": "HTTP/1.1", | ||
| "requestId": "id=", | ||
| "requestTime": "04/Mar/2020:19:15:17 +0000", | ||
| "requestTimeEpoch": 1583349317135, | ||
| "resourceId": null, | ||
| "resourcePath": "/my/path", | ||
| "stage": "$default" | ||
| }, | ||
| "pathParameters": null, | ||
| "stageVariables": null, | ||
| "body": "Hello from Lambda!", | ||
| "isBase64Encoded": false | ||
| } |
This file contains hidden or 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 hidden or 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 hidden or 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,8 +1,8 @@ | ||
| #!/bin/bash | ||
|
|
||
| echo "Building Java Lambda Functions" | ||
| java_test_dirs=("metric" "trace" "log" "timeout" "error") | ||
| java_test_dirs=("metric" "trace" "log" "timeout" "error" "appsec") | ||
| cd src | ||
| for java_dir in "${java_test_dirs[@]}"; do | ||
| mvn package -q -f java-tests/"${java_dir}"/pom.xml | ||
| done | ||
| done |
This file contains hidden or 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,6 +1,9 @@ | ||
| import argparse | ||
| import json | ||
| import os | ||
| import re | ||
| import traceback | ||
| from typing import Union | ||
|
|
||
|
|
||
| def normalize_metrics(stage): | ||
|
|
@@ -85,6 +88,7 @@ def sort__dd_tags_container(log): | |
| tags = tags.split(',') | ||
| tags.sort() | ||
| log["tags"]["_dd.tags.container"] = ','.join(tags) | ||
| return log | ||
|
|
||
| return [ | ||
| require(r'BEGINTRACE.*ENDTRACE'), | ||
|
|
@@ -111,6 +115,36 @@ def sort__dd_tags_container(log): | |
| ] | ||
|
|
||
|
|
||
| def normalize_appsec(stage): | ||
| def select__dd_appsec_json(log): | ||
| """Selects the content of spans.*.meta.[_dd.appsec.json] which is | ||
| unfortunately an embedded JSON string value, so it's parsed out. | ||
| """ | ||
|
|
||
| entries = [] | ||
|
|
||
| for chunk in log["chunks"]: | ||
| for span in chunk.get("spans") or []: | ||
| meta = span.get("meta") or {} | ||
| data = meta.get("_dd.appsec.json") | ||
| if data is None: | ||
| continue | ||
| parsed = json.loads(data, strict=False) | ||
| # The triggers may appear in any order, so we sort them by rule ID | ||
| parsed["triggers"] = sorted(parsed["triggers"], key=lambda x: x["rule"]["id"]) | ||
| entries.append(parsed) | ||
|
|
||
| return entries | ||
|
|
||
| return [ | ||
| require(r'BEGINTRACE.*ENDTRACE'), | ||
| exclude(r'BEGINTRACE'), | ||
| exclude(r'ENDTRACE'), | ||
| flat_map(select__dd_appsec_json), | ||
| replace(stage, 'XXXXXX'), | ||
| ] | ||
|
|
||
|
|
||
| ##################### | ||
| # BEGIN NORMALIZERS # | ||
| ##################### | ||
|
|
@@ -159,11 +193,28 @@ def _foreach(log): | |
| logs = json.loads(log, strict=False) | ||
| for log_item in logs: | ||
| fn(log_item) | ||
| return json.dumps(logs) | ||
| return json.dumps(logs, sort_keys=True) | ||
|
|
||
| return _foreach | ||
|
|
||
|
|
||
| def flat_map(fn): | ||
| """ | ||
| Execute fn with each element of the list in order, flatten the results. | ||
| """ | ||
|
|
||
| def _flat_map(log): | ||
| logs = json.loads(log, strict=False) | ||
|
|
||
| mapped = [] | ||
| for log_item in logs: | ||
| mapped.extend(fn(log_item)) | ||
|
|
||
| return json.dumps(mapped, sort_keys=True) | ||
|
|
||
| return _flat_map | ||
|
|
||
|
|
||
| def sort_by(key): | ||
| """ | ||
| Sort the json entries using the given key function, requires the log string | ||
|
|
@@ -211,12 +262,17 @@ def get_normalizers(typ, stage): | |
| return normalize_logs(stage) | ||
| elif typ == 'traces': | ||
| return normalize_traces(stage) | ||
| elif typ == 'appsec': | ||
| return normalize_appsec(stage) | ||
| else: | ||
| raise ValueError(f'invalid type "{typ}"') | ||
|
|
||
|
|
||
| def format_json(log): | ||
| return json.dumps(json.loads(log, strict=False), indent=2) | ||
| try: | ||
| return json.dumps(json.loads(log, strict=False), indent=2) | ||
| except json.JSONDecodeError: | ||
| return log | ||
|
|
||
|
|
||
| def parse_args(): | ||
|
|
@@ -230,9 +286,21 @@ def parse_args(): | |
| if __name__ == '__main__': | ||
| try: | ||
| args = parse_args() | ||
|
|
||
| if args.logs.startswith('file:'): | ||
| with open(args.logs[5:], 'r') as f: | ||
| args.logs = f.read() | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great addition! |
||
|
|
||
| print(normalize(args.logs, args.type, args.stage)) | ||
| except Exception: | ||
| err = {"error": "normalization raised exception"} | ||
| except Exception as e: | ||
| err: dict[str, Union[str, list[str]]] = { | ||
| "error": "normalization raised exception", | ||
| } | ||
| # Unless explicitly specified, perform as it did historically | ||
| if os.environ.get("TRACEBACK") == "true": | ||
| err["message"] = str(e) | ||
| err["backtrace"] = traceback.format_exception(type(e), e, e.__traceback__) | ||
|
|
||
| err_json = json.dumps(err, indent=2) | ||
| print(err_json) | ||
| exit(1) | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.