Skip to content

Commit 00a9ec1

Browse files
Merge remote-tracking branch 'origin/develop' into codex/pr-8429-fix
# Conflicts: # tests/functional/feature_flags/_boto3/test_feature_flags.py
2 parents 95094f9 + 3fff06f commit 00a9ec1

57 files changed

Lines changed: 1565 additions & 502 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
POLICY_FILE=${1:?Policy file is required}
6+
7+
if jq -e '
8+
(.Policy | if type == "string" then fromjson else . end)
9+
| any(.Statement[]?;
10+
.Effect == "Allow"
11+
and ((.Action // [] | if type == "array" then . else [.] end) | any(. == "*" or . == "lambda:*" or . == "lambda:GetLayerVersion"))
12+
and (((.Principal | if type == "object" then .AWS // "" else . end) | if type == "array" then . else [.] end) | index("*") != null)
13+
and ((.Condition // {}) | length == 0)
14+
)
15+
' "$POLICY_FILE" > /dev/null; then
16+
echo public
17+
else
18+
RESULT=$?
19+
if (( RESULT > 1 )); then
20+
echo "Unable to evaluate layer policy ${POLICY_FILE} (jq exit ${RESULT})" >&2
21+
exit "$RESULT"
22+
fi
23+
echo private
24+
fi

.github/workflows/bootstrap_region.yml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,10 @@ jobs:
5252
with:
5353
node-version: "22"
5454
- name: Setup dependencies
55-
uses: aws-powertools/actions/.github/actions/cached-node-modules@4bf64a4072489399fbf39b78f558eeeed6767189
55+
uses: aws-powertools/actions/.github/actions/cached-node-modules@7898dbd71be8083748aa52f07ce5201bb36078ac
5656
- id: credentials
5757
name: AWS Credentials
58-
uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c
58+
uses: aws-actions/configure-aws-credentials@cbe3b392738ccf3f987d68400dafcf4b0624a56c
5959
with:
6060
aws-region: ${{ inputs.region }}
6161
role-to-assume: ${{ secrets.REGION_IAM_ROLE }}
@@ -80,13 +80,11 @@ jobs:
8080
strategy:
8181
matrix:
8282
layer:
83-
- AWSLambdaPowertoolsPythonV3-python39-arm64
8483
- AWSLambdaPowertoolsPythonV3-python310-arm64
8584
- AWSLambdaPowertoolsPythonV3-python311-arm64
8685
- AWSLambdaPowertoolsPythonV3-python312-arm64
8786
- AWSLambdaPowertoolsPythonV3-python313-arm64
8887
- AWSLambdaPowertoolsPythonV3-python314-arm64
89-
- AWSLambdaPowertoolsPythonV3-python39-x86_64
9088
- AWSLambdaPowertoolsPythonV3-python310-x86_64
9189
- AWSLambdaPowertoolsPythonV3-python311-x86_64
9290
- AWSLambdaPowertoolsPythonV3-python312-x86_64
@@ -96,7 +94,7 @@ jobs:
9694
steps:
9795
- id: credentials
9896
name: AWS Credentials
99-
uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3
97+
uses: aws-actions/configure-aws-credentials@cbe3b392738ccf3f987d68400dafcf4b0624a56c # v6.2.4
10098
with:
10199
aws-region: us-east-1
102100
role-to-assume: ${{ secrets.REGION_IAM_ROLE }}

.github/workflows/layer_govcloud.yml

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ jobs:
5252
strategy:
5353
matrix:
5454
layer:
55-
- AWSLambdaPowertoolsPythonV3-python39
5655
- AWSLambdaPowertoolsPythonV3-python310
5756
- AWSLambdaPowertoolsPythonV3-python311
5857
- AWSLambdaPowertoolsPythonV3-python312
@@ -64,7 +63,7 @@ jobs:
6463
environment: Prod (Readonly)
6564
steps:
6665
- name: Configure AWS Credentials
67-
uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3
66+
uses: aws-actions/configure-aws-credentials@cbe3b392738ccf3f987d68400dafcf4b0624a56c # v6.2.4
6867
with:
6968
role-to-assume: ${{ secrets.AWS_IAM_ROLE }}
7069
aws-region: us-east-1
@@ -98,7 +97,6 @@ jobs:
9897
strategy:
9998
matrix:
10099
layer:
101-
- AWSLambdaPowertoolsPythonV3-python39
102100
- AWSLambdaPowertoolsPythonV3-python310
103101
- AWSLambdaPowertoolsPythonV3-python311
104102
- AWSLambdaPowertoolsPythonV3-python312
@@ -122,7 +120,7 @@ jobs:
122120
SHA=$(jq -r '.Content.CodeSha256' '${{ matrix.layer }}_${{ matrix.arch }}.json')
123121
test "$(openssl dgst -sha256 -binary ${{ matrix.layer }}_${{ matrix.arch }}.zip | openssl enc -base64)" == "$SHA" && echo "SHA OK: ${SHA}" || exit 1
124122
- name: Configure AWS Credentials
125-
uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3
123+
uses: aws-actions/configure-aws-credentials@cbe3b392738ccf3f987d68400dafcf4b0624a56c # v6.2.4
126124
with:
127125
role-to-assume: ${{ secrets.AWS_IAM_ROLE }}
128126
aws-region: us-gov-east-1
@@ -167,7 +165,6 @@ jobs:
167165
strategy:
168166
matrix:
169167
layer:
170-
- AWSLambdaPowertoolsPythonV3-python39
171168
- AWSLambdaPowertoolsPythonV3-python310
172169
- AWSLambdaPowertoolsPythonV3-python311
173170
- AWSLambdaPowertoolsPythonV3-python312
@@ -192,7 +189,7 @@ jobs:
192189
SHA=$(jq -r '.Content.CodeSha256' '${{ matrix.layer }}_${{ matrix.arch }}.json')
193190
test "$(openssl dgst -sha256 -binary ${{ matrix.layer }}_${{ matrix.arch }}.zip | openssl enc -base64)" == "$SHA" && echo "SHA OK: ${SHA}" || exit 1
194191
- name: Configure AWS Credentials
195-
uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3
192+
uses: aws-actions/configure-aws-credentials@cbe3b392738ccf3f987d68400dafcf4b0624a56c # v6.2.4
196193
with:
197194
role-to-assume: ${{ secrets.AWS_IAM_ROLE }}
198195
aws-region: us-gov-west-1

.github/workflows/layer_govcloud_python313.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ jobs:
5959
environment: Prod (Readonly)
6060
steps:
6161
- name: Configure AWS Credentials
62-
uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3
62+
uses: aws-actions/configure-aws-credentials@cbe3b392738ccf3f987d68400dafcf4b0624a56c # v6.2.4
6363
with:
6464
role-to-assume: ${{ secrets.AWS_IAM_ROLE }}
6565
aws-region: us-east-1
@@ -112,7 +112,7 @@ jobs:
112112
SHA=$(jq -r '.Content.CodeSha256' '${{ matrix.layer }}_${{ matrix.arch }}.json')
113113
test "$(openssl dgst -sha256 -binary ${{ matrix.layer }}_${{ matrix.arch }}.zip | openssl enc -base64)" == "$SHA" && echo "SHA OK: ${SHA}" || exit 1
114114
- name: Configure AWS Credentials
115-
uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3
115+
uses: aws-actions/configure-aws-credentials@cbe3b392738ccf3f987d68400dafcf4b0624a56c # v6.2.4
116116
with:
117117
role-to-assume: ${{ secrets.AWS_IAM_ROLE }}
118118
aws-region: us-gov-east-1
@@ -177,7 +177,7 @@ jobs:
177177
SHA=$(jq -r '.Content.CodeSha256' '${{ matrix.layer }}_${{ matrix.arch }}.json')
178178
test "$(openssl dgst -sha256 -binary ${{ matrix.layer }}_${{ matrix.arch }}.zip | openssl enc -base64)" == "$SHA" && echo "SHA OK: ${SHA}" || exit 1
179179
- name: Configure AWS Credentials
180-
uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3
180+
uses: aws-actions/configure-aws-credentials@cbe3b392738ccf3f987d68400dafcf4b0624a56c # v6.2.4
181181
with:
182182
role-to-assume: ${{ secrets.AWS_IAM_ROLE }}
183183
aws-region: us-gov-west-1

.github/workflows/layer_govcloud_verify.yml

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ jobs:
2828
strategy:
2929
matrix:
3030
layer:
31-
- AWSLambdaPowertoolsPythonV3-python39
3231
- AWSLambdaPowertoolsPythonV3-python310
3332
- AWSLambdaPowertoolsPythonV3-python311
3433
- AWSLambdaPowertoolsPythonV3-python312
@@ -40,7 +39,7 @@ jobs:
4039
environment: Prod (Readonly)
4140
steps:
4241
- name: Configure AWS Credentials
43-
uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3
42+
uses: aws-actions/configure-aws-credentials@cbe3b392738ccf3f987d68400dafcf4b0624a56c # v6.2.4
4443
with:
4544
role-to-assume: ${{ secrets.AWS_IAM_ROLE }}
4645
aws-region: us-east-1
@@ -59,7 +58,6 @@ jobs:
5958
strategy:
6059
matrix:
6160
layer:
62-
- AWSLambdaPowertoolsPythonV3-python39
6361
- AWSLambdaPowertoolsPythonV3-python310
6462
- AWSLambdaPowertoolsPythonV3-python311
6563
- AWSLambdaPowertoolsPythonV3-python312
@@ -71,7 +69,7 @@ jobs:
7169
environment: GovCloud Prod (East)
7270
steps:
7371
- name: Configure AWS Credentials
74-
uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3
72+
uses: aws-actions/configure-aws-credentials@cbe3b392738ccf3f987d68400dafcf4b0624a56c # v6.2.4
7573
with:
7674
role-to-assume: ${{ secrets.AWS_IAM_ROLE }}
7775
aws-region: us-gov-east-1
@@ -91,7 +89,6 @@ jobs:
9189
strategy:
9290
matrix:
9391
layer:
94-
- AWSLambdaPowertoolsPythonV3-python39
9592
- AWSLambdaPowertoolsPythonV3-python310
9693
- AWSLambdaPowertoolsPythonV3-python311
9794
- AWSLambdaPowertoolsPythonV3-python312
@@ -103,7 +100,7 @@ jobs:
103100
environment: GovCloud Prod (West)
104101
steps:
105102
- name: Configure AWS Credentials
106-
uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3
103+
uses: aws-actions/configure-aws-credentials@cbe3b392738ccf3f987d68400dafcf4b0624a56c # v6.2.4
107104
with:
108105
role-to-assume: ${{ secrets.AWS_IAM_ROLE }}
109106
aws-region: us-gov-east-1

.github/workflows/layers_partition_balance.yml

Lines changed: 65 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ jobs:
137137
architecture: ${{ fromJson(needs.setup.outputs.architectures) }}
138138
steps:
139139
- name: Configure AWS Credentials
140-
uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3
140+
uses: aws-actions/configure-aws-credentials@cbe3b392738ccf3f987d68400dafcf4b0624a56c # v6.2.4
141141
with:
142142
role-to-assume: ${{ secrets.AWS_IAM_ROLE }}
143143
aws-region: us-east-1
@@ -154,6 +154,7 @@ jobs:
154154
for (( VERSION=START_VERSION; VERSION<=END_VERSION; VERSION++ )); do
155155
NAME="${LAYER}-${ARCHITECTURE}"
156156
METADATA="source/${VERSION}.json"
157+
POLICY="source/${VERSION}.policy.json"
157158
ZIP="source/${VERSION}.zip"
158159
159160
aws --region us-east-1 lambda get-layer-version-by-arn \
@@ -162,6 +163,17 @@ jobs:
162163
LOCATION=$(jq -r '.Content.Location' "$METADATA")
163164
curl --fail --location --retry 3 --retry-delay 2 --output "$ZIP" "$LOCATION"
164165
166+
if ! aws --region us-east-1 lambda get-layer-version-policy \
167+
--layer-name "arn:aws:lambda:us-east-1:017000801446:layer:${NAME}" \
168+
--version-number "$VERSION" > "$POLICY" 2> policy-error.txt; then
169+
if grep -q ResourceNotFoundException policy-error.txt; then
170+
echo '{"Policy":null}' > "$POLICY"
171+
else
172+
cat policy-error.txt
173+
exit 1
174+
fi
175+
fi
176+
165177
EXPECTED_SHA=$(jq -r '.Content.CodeSha256' "$METADATA")
166178
ACTUAL_SHA=$(openssl dgst -sha256 -binary "$ZIP" | openssl enc -base64)
167179
if [[ "$ACTUAL_SHA" != "$EXPECTED_SHA" ]]; then
@@ -197,6 +209,8 @@ jobs:
197209
region: ${{ fromJson(needs.setup.outputs.regions) }}
198210
architecture: ${{ fromJson(needs.setup.outputs.architectures) }}
199211
steps:
212+
- name: Checkout repository
213+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
200214
- name: Download commercial layer versions
201215
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
202216
with:
@@ -210,7 +224,7 @@ jobs:
210224
NORMALIZED_REGION=${REGION^^}
211225
echo "value=${NORMALIZED_REGION//-/_}" >> "$GITHUB_OUTPUT"
212226
- name: Configure AWS Credentials
213-
uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3
227+
uses: aws-actions/configure-aws-credentials@cbe3b392738ccf3f987d68400dafcf4b0624a56c # v6.2.4
214228
with:
215229
role-to-assume: ${{ secrets[format('IAM_ROLE_{0}', steps.region.outputs.value)] }}
216230
aws-region: ${{ matrix.region }}
@@ -227,8 +241,8 @@ jobs:
227241
exit 1
228242
fi
229243
230-
CALLER_ACCOUNT=$(aws --region "$REGION" sts get-caller-identity --query Account --output text)
231-
CALLER_ARN=$(aws --region "$REGION" sts get-caller-identity --query Arn --output text)
244+
IDENTITY=$(aws --region "$REGION" sts get-caller-identity --query '[Account, Arn]' --output text)
245+
read -r CALLER_ACCOUNT CALLER_ARN <<< "$IDENTITY"
232246
233247
if [[ "$CALLER_ACCOUNT" != "$AWS_ACCOUNT" ]] || [[ "$CALLER_ARN" != "arn:${PARTITION}:"* ]]; then
234248
echo "Assumed role does not match the expected account and partition for ${REGION}"
@@ -249,18 +263,6 @@ jobs:
249263
mkdir -p scratch
250264
mkdir -p target
251265
252-
has_public_permission() {
253-
jq -e '
254-
(.Policy | if type == "string" then fromjson else . end)
255-
| any(.Statement[]?;
256-
.Sid == "PublicLayer"
257-
and .Effect == "Allow"
258-
and ((.Action | if type == "array" then . else [.] end) | index("lambda:GetLayerVersion") != null)
259-
and (((.Principal | if type == "object" then .AWS // "" else . end) | if type == "array" then . else [.] end) | index("*") != null)
260-
)
261-
' "$1" > /dev/null
262-
}
263-
264266
if ! aws --region "$REGION" lambda list-layer-versions \
265267
--layer-name "$NAME" \
266268
--output json > scratch/versions.json 2> scratch/list-error.txt; then
@@ -276,6 +278,7 @@ jobs:
276278
277279
for (( VERSION=START_VERSION; VERSION<=END_VERSION; VERSION++ )); do
278280
METADATA="source/${VERSION}.json"
281+
SOURCE_POLICY="source/${VERSION}.policy.json"
279282
ZIP="source/${VERSION}.zip"
280283
TARGET_METADATA="target/${VERSION}.json"
281284
TARGET_ARN="arn:${PARTITION}:lambda:${REGION}:${AWS_ACCOUNT}:layer:${NAME}:${VERSION}"
@@ -302,17 +305,29 @@ jobs:
302305
fi
303306
304307
HAS_PUBLIC_PERMISSION=false
305-
if aws --region "$REGION" lambda get-layer-version-policy \
308+
if ! aws --region "$REGION" lambda get-layer-version-policy \
306309
--layer-name "$NAME" \
307310
--version-number "$VERSION" > scratch/policy.json 2> scratch/policy-error.txt; then
308-
if has_public_permission scratch/policy.json; then
309-
HAS_PUBLIC_PERMISSION=true
311+
if grep -q ResourceNotFoundException scratch/policy-error.txt; then
312+
echo '{"Policy":null}' > scratch/policy.json
313+
else
314+
cat scratch/policy-error.txt
315+
exit 1
310316
fi
311-
elif ! grep -q ResourceNotFoundException scratch/policy-error.txt; then
312-
cat scratch/policy-error.txt
313-
exit 1
314317
fi
315318
319+
TARGET_VISIBILITY=$(bash .github/scripts/layer_policy_visibility.sh scratch/policy.json)
320+
if [[ "$TARGET_VISIBILITY" == "public" ]]; then
321+
HAS_PUBLIC_PERMISSION=true
322+
fi
323+
324+
SOURCE_IS_PUBLIC=false
325+
SOURCE_VISIBILITY=$(bash .github/scripts/layer_policy_visibility.sh "$SOURCE_POLICY")
326+
if [[ "$SOURCE_VISIBILITY" == "public" ]]; then
327+
SOURCE_IS_PUBLIC=true
328+
fi
329+
echo "Commercial source ${NAME}:${VERSION} public: ${SOURCE_IS_PUBLIC}"
330+
316331
if [[ "$VERSION_EXISTS" == "true" ]]; then
317332
echo "${NAME}:${VERSION} already exists in ${REGION} with the expected SHA"
318333
else
@@ -323,13 +338,21 @@ jobs:
323338
fi
324339
fi
325340
341+
if [[ "$SOURCE_IS_PUBLIC" == "false" ]] && [[ "$HAS_PUBLIC_PERMISSION" == "true" ]]; then
342+
echo "${NAME}:${VERSION} in ${REGION} is public but its commercial source is private"
343+
exit 1
344+
fi
345+
326346
if [[ "$DRY_RUN" != "false" ]]; then
327347
if [[ "$VERSION_EXISTS" == "false" ]]; then
328348
echo "Would publish ${NAME}:${VERSION} to ${REGION}"
329349
CURRENT_POSITION=$VERSION
330-
elif [[ "$HAS_PUBLIC_PERMISSION" == "false" ]]; then
350+
elif [[ "$SOURCE_IS_PUBLIC" == "true" ]] && [[ "$HAS_PUBLIC_PERMISSION" == "false" ]]; then
331351
echo "Would add public permission to ${NAME}:${VERSION} in ${REGION}"
332352
fi
353+
if [[ "$SOURCE_IS_PUBLIC" == "false" ]]; then
354+
echo "Would keep ${NAME}:${VERSION} private in ${REGION}"
355+
fi
333356
continue
334357
fi
335358
@@ -352,7 +375,7 @@ jobs:
352375
CURRENT_POSITION=$PUBLISHED_VERSION
353376
fi
354377
355-
if [[ "$HAS_PUBLIC_PERMISSION" == "false" ]]; then
378+
if [[ "$SOURCE_IS_PUBLIC" == "true" ]] && [[ "$HAS_PUBLIC_PERMISSION" == "false" ]]; then
356379
if ! aws --region "$REGION" lambda add-layer-version-permission \
357380
--layer-name "$NAME" \
358381
--statement-id PublicLayer \
@@ -375,11 +398,25 @@ jobs:
375398
exit 1
376399
fi
377400
378-
aws --region "$REGION" lambda get-layer-version-policy \
401+
if ! aws --region "$REGION" lambda get-layer-version-policy \
379402
--layer-name "$NAME" \
380-
--version-number "$VERSION" > scratch/policy.json
381-
if ! has_public_permission scratch/policy.json; then
382-
echo "${NAME}:${VERSION} in ${REGION} is missing the expected public permission"
403+
--version-number "$VERSION" > scratch/policy.json 2> scratch/policy-error.txt; then
404+
if grep -q ResourceNotFoundException scratch/policy-error.txt; then
405+
echo '{"Policy":null}' > scratch/policy.json
406+
else
407+
cat scratch/policy-error.txt
408+
exit 1
409+
fi
410+
fi
411+
412+
TARGET_IS_PUBLIC=false
413+
TARGET_VISIBILITY=$(bash .github/scripts/layer_policy_visibility.sh scratch/policy.json)
414+
if [[ "$TARGET_VISIBILITY" == "public" ]]; then
415+
TARGET_IS_PUBLIC=true
416+
fi
417+
418+
if [[ "$TARGET_IS_PUBLIC" != "$SOURCE_IS_PUBLIC" ]]; then
419+
echo "${NAME}:${VERSION} in ${REGION} does not match its commercial source visibility"
383420
exit 1
384421
fi
385422
done

0 commit comments

Comments
 (0)