Skip to content

Commit bbf3f97

Browse files
authored
Merge branch 'main' into zarir.hamza/disable-rc-in-lambda
2 parents 6384d35 + 5e8feaa commit bbf3f97

23 files changed

Lines changed: 588 additions & 322 deletions

Dockerfile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,13 @@ RUN pip install --no-cache-dir . -t ./python/lib/$runtime/site-packages
3333
RUN rm -rf ./python/lib/$runtime/site-packages/botocore*
3434
RUN rm -rf ./python/lib/$runtime/site-packages/setuptools
3535
RUN rm -rf ./python/lib/$runtime/site-packages/jsonschema/tests
36-
RUN rm -rf ./python/lib/$runtime/site-packages/ddtrace/appsec/_iast
36+
37+
# Remove unsupported appsec modules
38+
RUN rm -rf \
39+
./python/lib/$runtime/site-packages/ddtrace/appsec/_iast \
40+
./python/lib/$runtime/site-packages/ddtrace/appsec/sca \
41+
./python/lib/$runtime/site-packages/ddtrace/appsec/_shared
42+
3743
# CI Visibility paths/integrations
3844
RUN rm -rf \
3945
./python/lib/$runtime/site-packages/ddtrace/contrib/coverage/ \

ci/get_secrets.sh

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,11 @@ fi
2121

2222
printf "Getting AWS External ID...\n"
2323

24-
EXTERNAL_ID=$(aws ssm get-parameter \
25-
--region us-east-1 \
26-
--name "ci.datadog-lambda-python.$EXTERNAL_ID_NAME" \
27-
--with-decryption \
28-
--query "Parameter.Value" \
29-
--out text)
24+
EXTERNAL_ID=$(vault kv get -field="$EXTERNAL_ID_NAME" kv/k8s/gitlab-runner/datadog-lambda-python/secrets)
3025

3126
printf "Getting DD API KEY...\n"
3227

33-
export DD_API_KEY=$(aws ssm get-parameter \
34-
--region us-east-1 \
35-
--name ci.datadog-lambda-python.dd-api-key \
36-
--with-decryption \
37-
--query "Parameter.Value" \
38-
--out text)
28+
export DD_API_KEY=$(vault kv get -field=dd-api-key kv/k8s/gitlab-runner/datadog-lambda-python/secrets)
3929

4030
printf "Assuming role...\n"
4131

ci/input_files/build.yaml.tpl

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -285,30 +285,5 @@ e2e-test-status:
285285
- if: '$SKIP_E2E_TESTS == "true"'
286286
when: never
287287
- when: on_success
288-
script: |
289-
GITLAB_API_TOKEN=$(aws ssm get-parameter --region us-east-1 --name "ci.${CI_PROJECT_NAME}.serverless-e2e-gitlab-token" --with-decryption --query "Parameter.Value" --out text)
290-
URL="${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/pipelines/${CI_PIPELINE_ID}/bridges"
291-
echo "Fetching E2E job status from: $URL"
292-
while true; do
293-
RESPONSE=$(curl -s --header "PRIVATE-TOKEN: ${GITLAB_API_TOKEN}" "$URL")
294-
E2E_JOB_STATUS=$(echo "$RESPONSE" | jq -r '.[] | select(.name=="e2e-test") | .downstream_pipeline.status')
295-
echo -n "E2E job status: $E2E_JOB_STATUS, "
296-
if [ "$E2E_JOB_STATUS" == "success" ]; then
297-
echo "✅ E2E tests completed successfully"
298-
exit 0
299-
elif [ "$E2E_JOB_STATUS" == "failed" ]; then
300-
echo "❌ E2E tests failed"
301-
exit 1
302-
elif [ "$E2E_JOB_STATUS" == "running" ]; then
303-
echo "⏳ E2E tests are still running, retrying in 1 minute..."
304-
elif [ "$E2E_JOB_STATUS" == "canceled" ]; then
305-
echo "🚫 E2E tests were canceled"
306-
exit 1
307-
elif [ "$E2E_JOB_STATUS" == "skipped" ]; then
308-
echo "⏭️ E2E tests were skipped"
309-
exit 0
310-
else
311-
echo "❓ Unknown E2E test status: $E2E_JOB_STATUS, retrying in 1 minute..."
312-
fi
313-
sleep 60
314-
done
288+
script:
289+
- ci/poll_e2e.sh

ci/poll_e2e.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
curl -OL "binaries.ddbuild.io/dd-source/authanywhere/LATEST/authanywhere-linux-amd64" && mv "authanywhere-linux-amd64" /bin/authanywhere && chmod +x /bin/authanywhere
2+
3+
BTI_CI_API_TOKEN=$(authanywhere --audience rapid-devex-ci)
4+
5+
BTI_RESPONSE=$(curl --silent --request GET \
6+
--header "$BTI_CI_API_TOKEN" \
7+
--header "Content-Type: application/vnd.api+json" \
8+
"https://bti-ci-api.us1.ddbuild.io/internal/ci/gitlab/token?owner=DataDog&repository=datadog-lambda-python")
9+
10+
GITLAB_TOKEN=$(echo "$BTI_RESPONSE" | jq -r '.token // empty')
11+
12+
URL="${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/pipelines/${CI_PIPELINE_ID}/bridges"
13+
14+
echo "Fetching E2E job status from: $URL"
15+
16+
while true; do
17+
RESPONSE=$(curl -s --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" "$URL")
18+
E2E_JOB_STATUS=$(echo "$RESPONSE" | jq -r '.[] | select(.name=="e2e-test") | .downstream_pipeline.status')
19+
echo -n "E2E job status: $E2E_JOB_STATUS, "
20+
if [ "$E2E_JOB_STATUS" == "success" ]; then
21+
echo "✅ E2E tests completed successfully"
22+
exit 0
23+
elif [ "$E2E_JOB_STATUS" == "failed" ]; then
24+
echo "❌ E2E tests failed"
25+
exit 1
26+
elif [ "$E2E_JOB_STATUS" == "running" ]; then
27+
echo "⏳ E2E tests are still running, retrying in 2 minutes..."
28+
elif [ "$E2E_JOB_STATUS" == "canceled" ]; then
29+
echo "🚫 E2E tests were canceled"
30+
exit 1
31+
elif [ "$E2E_JOB_STATUS" == "skipped" ]; then
32+
echo "⏭️ E2E tests were skipped"
33+
exit 0
34+
else
35+
echo "❓ Unknown E2E test status: $E2E_JOB_STATUS, retrying in 2 minutes..."
36+
fi
37+
sleep 120
38+
done

datadog_lambda/durable.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,17 @@ def extract_durable_function_tags(event):
4141
if not parsed:
4242
logger.error("Failed to parse DurableExecutionArn: %s", durable_execution_arn)
4343
return {}
44-
4544
execution_name, execution_id = parsed
45+
# Use the number of operations to determine if it's the first invocation. This is
46+
# what the durable execution SDK does to determine the replay status.
47+
operations = event.get("InitialExecutionState", {}).get("Operations", [])
48+
is_first_invocation = len(operations) == 1
4649
return {
4750
"aws_lambda.durable_function.execution_name": execution_name,
4851
"aws_lambda.durable_function.execution_id": execution_id,
52+
"aws_lambda.durable_function.first_invocation": str(
53+
is_first_invocation
54+
).lower(),
4955
}
5056

5157

datadog_lambda/tracing.py

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -977,16 +977,12 @@ def process_injected_data(event, request_time_epoch_ms, args, tags):
977977
start_time_ns = int(
978978
injected_authorizer_data.get(Headers.Parent_Span_Finish_Time)
979979
)
980-
finish_time_ns = (
981-
request_time_epoch_ms
982-
+ (
983-
int(
984-
event["requestContext"]["authorizer"].get(
985-
"integrationLatency", 0
986-
)
987-
)
988-
)
989-
) * 1e6
980+
integration_latency = int(
981+
event["requestContext"]["authorizer"].get("integrationLatency", 0)
982+
)
983+
finish_time_ns = max(
984+
start_time_ns, (request_time_epoch_ms + integration_latency) * 1e6
985+
)
990986
upstream_authorizer_span = insert_upstream_authorizer_span(
991987
args, tags, start_time_ns, finish_time_ns
992988
)

datadog_lambda/wrapper.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,6 @@ def __call__(self, event, context, **kwargs):
191191
if self.blocking_response:
192192
return self.blocking_response
193193
self.response = self.func(event, context, **kwargs)
194-
return self.response
195194
except BlockingException:
196195
self.blocking_response = get_asm_blocked_response(self.event_source)
197196
except Exception:
@@ -204,8 +203,9 @@ def __call__(self, event, context, **kwargs):
204203
raise
205204
finally:
206205
self._after(event, context)
207-
if self.blocking_response:
208-
return self.blocking_response
206+
if self.blocking_response:
207+
return self.blocking_response
208+
return self.response
209209

210210
def _inject_authorizer_span_headers(self, request_id):
211211
reference_span = self.inferred_span if self.inferred_span else self.span

pyproject.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ ddtrace = [
3333
{version = ">=3.19.1,<4", python = ">=3.8,<3.10"},
3434
{version = ">=4.1.1,<5,!=4.6.*", python = ">=3.10"}
3535
]
36-
ujson = ">=5.9.0"
36+
ujson = [
37+
{version = ">=5.10.0,<5.12.0", python = ">=3.8,<3.10"},
38+
{version = ">=5.12.0", python = ">=3.10"}
39+
]
3740
botocore = { version = "^1.34.0", optional = true }
3841
requests = { version ="^2.22.0", optional = true }
3942
pytest = { version= "^8.0.0", optional = true }

scripts/build_layers.sh

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -91,29 +91,49 @@ trap cleanup EXIT
9191
# Helper: replace the multi-line ddtrace dependency in pyproject.toml.
9292
# Uses perl instead of sed -z for macOS/Linux portability.
9393
replace_ddtrace_dep() {
94+
echo "Replacing dep with $1"
9495
perl -i -0777 -pe "s|ddtrace = \[[^\]]*\]|$1|gs" pyproject.toml
9596
}
9697

9798
function make_path_absolute {
9899
echo "$(cd "$(dirname "$1")"; pwd)/$(basename "$1")"
99100
}
100101

101-
function docker_build_zip {
102-
# Args: [python version] [zip destination]
102+
function search_wheel {
103+
# Args: [wheel base name] [index]
103104

104-
destination=$(make_path_absolute $2)
105-
arch=$3
105+
WHEEL_BASENAME=$1
106+
INDEX=$2
107+
108+
SEARCH_PATTERN="${WHEEL_BASENAME}-[^\"]*${PY_TAG}[^\"]*${PLATFORM}[^\"]*\.whl"
109+
INDEX_URL="${S3_BASE}/index-${INDEX}.html"
110+
echo "Searching for wheel ${SEARCH_PATTERN}"
111+
export WHEEL_FILE=$(curl -sSfL ${INDEX_URL} | grep -o "$SEARCH_PATTERN" | head -n 1)
112+
if [ ! -z "${WHEEL_FILE}" ]; then
113+
curl -sSfL "${S3_BASE}/${WHEEL_FILE}" -o "${WHEEL_FILE}"
114+
echo "Using S3 wheel: ${WHEEL_FILE}"
115+
replace_ddtrace_dep "${WHEEL_BASENAME} = { file = \"${WHEEL_FILE}\" }"
116+
fi
117+
}
118+
119+
function find_and_spec_wheel {
120+
# Args: [python version] [wheel base name] [index]
121+
122+
arch=$2
123+
wheel_basename=$3
124+
index=$4
106125

107126
# Restore pyproject.toml to a clean state for each build iteration
108127
cp pyproject.toml.bak pyproject.toml
109128

110129
# Replace ddtrace source if necessary
111130
if [ -n "$DD_TRACE_COMMIT" ]; then
112-
replace_ddtrace_dep "ddtrace = { git = \"https://github.com/DataDog/dd-trace-py.git\", rev = \"$DD_TRACE_COMMIT\" }"
131+
replace_ddtrace_dep "${wheel_basename} = { git = \"https://github.com/DataDog/dd-trace-py.git\", rev = \"$DD_TRACE_COMMIT\" }"
113132
elif [ -n "$DD_TRACE_COMMIT_BRANCH" ]; then
114-
replace_ddtrace_dep "ddtrace = { git = \"https://github.com/DataDog/dd-trace-py.git\", branch = \"$DD_TRACE_COMMIT_BRANCH\" }"
133+
replace_ddtrace_dep "${wheel_basename} = { git = \"https://github.com/DataDog/dd-trace-py.git\", branch = \"$DD_TRACE_COMMIT_BRANCH\" }"
115134
elif [ -n "$DD_TRACE_WHEEL" ]; then
116-
replace_ddtrace_dep "ddtrace = { file = \"$DD_TRACE_WHEEL\" }"
135+
wheel_basename=$(sed 's/^.*\///' <<< ${DD_TRACE_WHEEL%%-*})
136+
replace_ddtrace_dep "${wheel_basename} = { file = \"$DD_TRACE_WHEEL\" }"
117137
elif [ -n "$UPSTREAM_PIPELINE_ID" ]; then
118138
S3_BASE="https://dd-trace-py-builds.s3.amazonaws.com/${UPSTREAM_PIPELINE_ID}"
119139
if [ "${arch}" = "amd64" ]; then
@@ -122,18 +142,19 @@ function docker_build_zip {
122142
PLATFORM="manylinux2014_aarch64"
123143
fi
124144
PY_TAG="cp$(echo "$1" | tr -d '.')"
125-
WHEEL_FILE=$(curl -sSfL "${S3_BASE}/index-manylinux2014.html" \
126-
| grep -o "ddtrace-[^\"]*${PY_TAG}[^\"]*${PLATFORM}[^\"]*\.whl" \
127-
| head -n 1)
145+
search_wheel ${wheel_basename} ${index}
128146
if [ -z "${WHEEL_FILE}" ]; then
129147
echo "No S3 wheel found for ${PY_TAG} ${PLATFORM}, using default pyproject.toml version"
130-
else
131-
curl -sSfL "${S3_BASE}/${WHEEL_FILE}" -o "${WHEEL_FILE}"
132-
echo "Using S3 wheel: ${WHEEL_FILE}"
133-
replace_ddtrace_dep "ddtrace = { file = \"${WHEEL_FILE}\" }"
148+
return 1
134149
fi
135150
fi
151+
}
152+
153+
function docker_build_zip {
154+
# Args: [python version] [zip destination]
136155

156+
destination=$(make_path_absolute $2)
157+
arch=$3
137158
# Install datadogpy in a docker container to avoid the mess from switching
138159
# between different python runtimes.
139160
temp_dir=$(mktemp -d)
@@ -159,6 +180,14 @@ do
159180
for architecture in "${ARCHS[@]}"
160181
do
161182
echo "Building layer for Python ${python_version} arch=${architecture}"
183+
set +e
184+
find_and_spec_wheel ${python_version} ${architecture} "ddtrace_serverless" "serverless"
185+
FAILURE=$?
186+
if [ $FAILURE != 0 ]; then
187+
echo "Attempting layer build again with package ddtrace"
188+
find_and_spec_wheel ${python_version} ${architecture} "ddtrace" "manylinux2014"
189+
fi
190+
set -e
162191
docker_build_zip ${python_version} $LAYER_DIR/${LAYER_FILES_PREFIX}-${architecture}-${python_version}.zip ${architecture}
163192
done
164193
done

tests/event_samples/authorizer-request-api-gateway-v1.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
"requestContext": {
5656
"resourceId": "0et54l",
5757
"authorizer": {
58-
"_datadog": "eyJ4LWRhdGFkb2ctdHJhY2UtaWQiOiAiMTM0Nzg3MDU5OTU3OTcyMjEyMDkiLCAieC1kYXRhZG9nLXBhcmVudC1pZCI6ICI4NDcxMjg4MjYzMzg0MjE2ODk2IiwgIngtZGF0YWRvZy1zYW1wbGluZy1wcmlvcml0eSI6ICIxIiwgIngtZGF0YWRvZy1wYXJlbnQtc3Bhbi1maW5pc2gtdGltZSI6IDE2NjMyOTUwMjE4MjcuNTIxLCAieC1kYXRhZG9nLWF1dGhvcml6aW5nLXJlcXVlc3RpZCI6ICJhYmMxMjMifQ==",
58+
"_datadog": "eyJ4LWRhdGFkb2ctdHJhY2UtaWQiOiAiMTM0Nzg3MDU5OTU3OTcyMjEyMDkiLCAieC1kYXRhZG9nLXBhcmVudC1pZCI6ICI4NDcxMjg4MjYzMzg0MjE2ODk2IiwgIngtZGF0YWRvZy1zYW1wbGluZy1wcmlvcml0eSI6ICIxIiwgIngtZGF0YWRvZy1wYXJlbnQtc3Bhbi1maW5pc2gtdGltZSI6IDE2NjMyOTUwMjE4Mjc1MjEwMDAsICJ4LWRhdGFkb2ctYXV0aG9yaXppbmctcmVxdWVzdGlkIjogImFiYzEyMyJ9",
5959
"scope": "this is just a string",
6060
"principalId": "foo",
6161
"integrationLatency": 1897

0 commit comments

Comments
 (0)