Skip to content

Commit 146226a

Browse files
committed
Merge remote-tracking branch 'origin/feature/CLDSRV-812/list-objects-v2-optional-permissions' into w/9.2/feature/CLDSRV-812/list-objects-v2-optional-permissions
2 parents 1af3942 + ccaf400 commit 146226a

File tree

9 files changed

+389
-109
lines changed

9 files changed

+389
-109
lines changed

docs/RELEASE.md

Lines changed: 24 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -26,42 +26,33 @@ docker pull ghcr.io/scality/cloudserver:<tag>
2626

2727
To release a production image:
2828

29-
* Create a PR to bump the package version
30-
Update Cloudserver's `package.json` by bumping it to the relevant next
31-
version in a new PR. Per example if the last released version was
32-
`8.4.7`, the next version would be `8.4.8`.
33-
34-
```js
35-
{
36-
"name": "cloudserver",
37-
"version": "8.4.8", <--- Here
38-
[...]
39-
}
40-
```
29+
* Create a PR to bump the package version :
30+
update Cloudserver's `package.json` by bumping it to the relevant next
31+
version in a new PR. Per example if the last released version was `8.4.7`,
32+
the next version would be `8.4.8`.
33+
34+
```js
35+
{
36+
"name": "cloudserver",
37+
"version": "8.4.8", <--- Here
38+
[...]
39+
}
40+
```
4141

4242
* Review & merge the PR
4343

44-
* Create the release on GitHub
45-
46-
* Go the Release tab (https://github.com/scality/cloudserver/releases);
47-
* Click on the `Draft new release button`;
48-
* In the `tag` field, type the name of the release (`8.4.8`), and confirm
49-
to create the tag on publish;
50-
* Click on `Generate release notes` button to fill the fields;
51-
* Rename the release to `Release x.y.z` (e.g. `Release 8.4.8` in this case);
52-
* Click to `Publish the release` to create the GitHub release and git tag
53-
54-
Notes:
55-
* the Git tag will be created automatically.
56-
* this should be done as soon as the PR is merged, so that the tag
57-
is put on the "version bump" commit.
58-
59-
* With the following parameters, [force a build here](https://eve.devsca.com/github/scality/cloudserver/#/builders/3/force/force)
60-
61-
* Branch Name: The one used for the tag earlier. In this example `development/8.4`
62-
* Override Stage: 'release'
63-
* Extra properties:
64-
* name: `'tag'`, value: `[release version]`, in this example`'8.4.8'`
44+
* Trigger the release workflow on GitHub
45+
46+
* Go to the [**Actions** tab on GitHub](https://github.com/scality/cloudserver/actions)
47+
* Select the `release` workflow from the list
48+
* Click on **Run workflow** (manual dispatch)
49+
* Enter the new tag (e.g., `8.4.8`) in the input field
50+
* Start the workflow
51+
52+
This workflow will create the tag and push the Docker images.
53+
54+
This should be done as soon as the PR is merged,
55+
so that the tag is put on the "version bump" commit.
6556

6657
* Release the release version on Jira
6758

lib/api/apiUtils/authorization/prepareRequestContexts.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,15 @@ function prepareRequestContexts(apiMethod, request, sourceBucket,
252252
generateRequestContext('bypassGovernanceRetention');
253253
requestContexts.push(checkUserGovernanceBypassRequestContext);
254254
}
255+
} else if (apiMethodAfterVersionCheck === 'bucketGet') {
256+
requestContexts.push(generateRequestContext(apiMethodAfterVersionCheck));
257+
258+
const optionalAttributesHeader = request.headers['x-amz-optional-object-attributes'];
259+
const requestedAttributes = optionalAttributesHeader ? optionalAttributesHeader.split(',') : [];
260+
261+
if (requestedAttributes.filter(attr => attr != 'RestoreStatus').length > 0) {
262+
requestContexts.push(generateRequestContext('listObjectsV2OptionalAttributes'));
263+
}
255264
} else {
256265
const requestContext =
257266
generateRequestContext(apiMethodAfterVersionCheck);

lib/api/bucketGet.js

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,15 @@ function bucketGet(authInfo, request, log, callback) {
284284
const params = request.query;
285285
const bucketName = request.bucketName;
286286
const v2 = params['list-type'];
287+
288+
const optionalAttributes =
289+
request.headers['x-amz-optional-object-attributes']?.split(',').map(attr => attr.trim()) ?? [];
290+
if (optionalAttributes.some(attr => !attr.startsWith('x-amz-meta-') && attr != 'RestoreStatus')) {
291+
return callback(
292+
errorInstances.InvalidArgument.customizeDescription('Invalid attribute name specified')
293+
);
294+
}
295+
287296
if (v2 !== undefined && Number.parseInt(v2, 10) !== 2) {
288297
return callback(errorInstances.InvalidArgument.customizeDescription('Invalid ' +
289298
'List Type specified in Request'));
@@ -352,21 +361,22 @@ function bucketGet(authInfo, request, log, callback) {
352361
}
353362

354363
standardMetadataValidateBucket(metadataValParams, request.actionImplicitDenies, log, (err, bucket) => {
355-
const corsHeaders = collectCorsHeaders(request.headers.origin,
356-
request.method, bucket);
364+
const corsHeaders = collectCorsHeaders(request.headers.origin, request.method, bucket);
365+
357366
if (err) {
358367
log.debug('error processing request', { error: err });
359-
monitoring.promMetrics(
360-
'GET', bucketName, err.code, 'listBucket');
368+
monitoring.promMetrics('GET', bucketName, err.code, 'listBucket');
361369
return callback(err, null, corsHeaders);
362370
}
371+
363372
if (params.versions !== undefined) {
364373
listParams.listingType = 'DelimiterVersions';
365374
delete listParams.marker;
366375
listParams.keyMarker = params['key-marker'];
367376
listParams.versionIdMarker = params['version-id-marker'] ?
368377
versionIdUtils.decode(params['version-id-marker']) : undefined;
369378
}
379+
370380
if (!requestMaxKeys) {
371381
const emptyList = {
372382
CommonPrefixes: [],
@@ -377,14 +387,14 @@ function bucketGet(authInfo, request, log, callback) {
377387
return handleResult(listParams, requestMaxKeys, encoding, authInfo,
378388
bucketName, emptyList, corsHeaders, log, callback);
379389
}
380-
return services.getObjectListing(bucketName, listParams, log,
381-
(err, list) => {
390+
391+
return services.getObjectListing(bucketName, listParams, log, (err, list) => {
382392
if (err) {
383393
log.debug('error processing request', { error: err });
384-
monitoring.promMetrics(
385-
'GET', bucketName, err.code, 'listBucket');
394+
monitoring.promMetrics('GET', bucketName, err.code, 'listBucket');
386395
return callback(err, null, corsHeaders);
387396
}
397+
388398
return handleResult(listParams, requestMaxKeys, encoding, authInfo,
389399
bucketName, list, corsHeaders, log, callback);
390400
});

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"dependencies": {
2222
"@azure/storage-blob": "^12.28.0",
2323
"@hapi/joi": "^17.1.1",
24-
"arsenal": "git+https://github.com/scality/Arsenal#8.2.43",
24+
"arsenal": "git+https://github.com/scality/arsenal#8.2.44",
2525
"async": "2.6.4",
2626
"aws-sdk": "^2.1692.0",
2727
"bucketclient": "scality/bucketclient#8.2.7",
@@ -69,6 +69,7 @@
6969
"node-mocks-http": "^1.16.1",
7070
"nodemon": "^3.1.10",
7171
"nyc": "^15.1.0",
72+
"pino-pretty": "^13.1.3",
7273
"sinon": "^13.0.1",
7374
"tv4": "^1.3.0"
7475
},
@@ -82,7 +83,7 @@
8283
},
8384
"scripts": {
8485
"cloudserver": "S3METADATA=mongodb npm-run-all --parallel start_dataserver start_s3server",
85-
"dev": "nodemon --exec \"yarn run start\"",
86+
"dev": "nodemon --exec \"yarn run start\" | pino-pretty -c -S -m message -i \"pid,hostname,name,authn,authz,address,clientPort,clientIP,elapsed_ms\"",
8687
"ft_awssdk": "cd tests/functional/aws-node-sdk && mocha --reporter mocha-multi-reporters --reporter-options configFile=$INIT_CWD/tests/reporter-config.json test/ --exit",
8788
"ft_awssdk_aws": "cd tests/functional/aws-node-sdk && AWS_ON_AIR=true mocha --reporter mocha-multi-reporters --reporter-options configFile=$INIT_CWD/tests/reporter-config.json test/ --exit",
8889
"ft_awssdk_buckets": "cd tests/functional/aws-node-sdk && mocha --reporter mocha-multi-reporters --reporter-options configFile=$INIT_CWD/tests/reporter-config.json test/bucket --exit",

tests/functional/aws-node-sdk/test/object/mpuVersion.js

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -101,14 +101,15 @@ function checkObjMdAndUpdate(objMDBefore, objMDAfter, props) {
101101
});
102102
}
103103

104-
function clearUploadIdFromVersions(versions) {
104+
function clearUploadIdAndRestoreStatusFromVersions(versions) {
105105
if (!versions || versions.length === 0) {
106106
return versions;
107107
}
108108

109109
for (const version of versions) {
110110
if (version.value) {
111111
version.value.uploadId = undefined;
112+
version.value.restoreStatus = undefined;
112113
}
113114
}
114115

@@ -263,7 +264,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
263264
return next(err);
264265
}),
265266
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
266-
versionsBefore = clearUploadIdFromVersions(res.Versions);
267+
versionsBefore = clearUploadIdAndRestoreStatusFromVersions(res.Versions);
267268
return next(err);
268269
}),
269270
next => putMPUVersion(s3, bucketName, objectName, '', next),
@@ -272,7 +273,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
272273
return next(err);
273274
}),
274275
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
275-
versionsAfter = clearUploadIdFromVersions(res.Versions);
276+
versionsAfter = clearUploadIdAndRestoreStatusFromVersions(res.Versions);
276277
return next(err);
277278
}),
278279
], err => {
@@ -304,7 +305,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
304305
return next(err);
305306
}),
306307
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
307-
versionsBefore = clearUploadIdFromVersions(res.Versions);
308+
versionsBefore = clearUploadIdAndRestoreStatusFromVersions(res.Versions);
308309
return next(err);
309310
}),
310311
next => putMPUVersion(s3, bucketName, objectName, '', next),
@@ -313,7 +314,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
313314
return next(err);
314315
}),
315316
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
316-
versionsAfter = clearUploadIdFromVersions(res.Versions);
317+
versionsAfter = clearUploadIdAndRestoreStatusFromVersions(res.Versions);
317318
return next(err);
318319
}),
319320
], err => {
@@ -353,7 +354,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
353354
}),
354355
next => fakeMetadataArchive(bucketName, objectName, vId, archive, next),
355356
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
356-
versionsBefore = clearUploadIdFromVersions(res.Versions);
357+
versionsBefore = clearUploadIdAndRestoreStatusFromVersions(res.Versions);
357358
return next(err);
358359
}),
359360
next => getMetadata(bucketName, objectName, vId, (err, objMD) => {
@@ -366,7 +367,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
366367
return next(err);
367368
}),
368369
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
369-
versionsAfter = clearUploadIdFromVersions(res.Versions);
370+
versionsAfter = clearUploadIdAndRestoreStatusFromVersions(res.Versions);
370371
return next(err);
371372
}),
372373
], err => {
@@ -405,7 +406,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
405406
}),
406407
next => fakeMetadataArchive(bucketName, objectName, vId, archive, next),
407408
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
408-
versionsBefore = clearUploadIdFromVersions(res.Versions);
409+
versionsBefore = clearUploadIdAndRestoreStatusFromVersions(res.Versions);
409410
return next(err);
410411
}),
411412
next => getMetadata(bucketName, objectName, vId, (err, objMD) => {
@@ -418,7 +419,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
418419
return next(err);
419420
}),
420421
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
421-
versionsAfter = clearUploadIdFromVersions(res.Versions);
422+
versionsAfter = clearUploadIdAndRestoreStatusFromVersions(res.Versions);
422423
return next(err);
423424
}),
424425
], err => {
@@ -458,7 +459,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
458459
return next(err);
459460
}),
460461
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
461-
versionsBefore = clearUploadIdFromVersions(res.Versions);
462+
versionsBefore = clearUploadIdAndRestoreStatusFromVersions(res.Versions);
462463
return next(err);
463464
}),
464465
next => putMPUVersion(s3, bucketName, objectName, 'null', next),
@@ -467,7 +468,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
467468
return next(err);
468469
}),
469470
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
470-
versionsAfter = clearUploadIdFromVersions(res.Versions);
471+
versionsAfter = clearUploadIdAndRestoreStatusFromVersions(res.Versions);
471472
return next(err);
472473
}),
473474
], err => {
@@ -511,7 +512,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
511512
return next(err);
512513
}),
513514
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
514-
versionsBefore = clearUploadIdFromVersions(res.Versions);
515+
versionsBefore = clearUploadIdAndRestoreStatusFromVersions(res.Versions);
515516
next(err);
516517
}),
517518
next => putMPUVersion(s3, bucketName, objectName, vId, next),
@@ -520,7 +521,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
520521
return next(err);
521522
}),
522523
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
523-
versionsAfter = clearUploadIdFromVersions(res.Versions);
524+
versionsAfter = clearUploadIdAndRestoreStatusFromVersions(res.Versions);
524525
return next(err);
525526
}),
526527
], err => {
@@ -567,7 +568,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
567568
return next(err);
568569
}),
569570
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
570-
versionsBefore = clearUploadIdFromVersions(res.Versions);
571+
versionsBefore = clearUploadIdAndRestoreStatusFromVersions(res.Versions);
571572
next(err);
572573
}),
573574
next => putMPUVersion(s3, bucketName, objectName, '', next),
@@ -576,7 +577,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
576577
return next(err);
577578
}),
578579
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
579-
versionsAfter = clearUploadIdFromVersions(res.Versions);
580+
versionsAfter = clearUploadIdAndRestoreStatusFromVersions(res.Versions);
580581
return next(err);
581582
}),
582583
], err => {
@@ -621,7 +622,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
621622
return next(err);
622623
}),
623624
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
624-
versionsBefore = clearUploadIdFromVersions(res.Versions);
625+
versionsBefore = clearUploadIdAndRestoreStatusFromVersions(res.Versions);
625626
return next(err);
626627
}),
627628
next => putMPUVersion(s3, bucketName, objectName, vId, next),
@@ -630,7 +631,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
630631
return next(err);
631632
}),
632633
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
633-
versionsAfter = clearUploadIdFromVersions(res.Versions);
634+
versionsAfter = clearUploadIdAndRestoreStatusFromVersions(res.Versions);
634635
return next(err);
635636
}),
636637
], err => {
@@ -670,7 +671,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
670671
}),
671672
next => fakeMetadataArchive(bucketName, objectName, vId, archive, next),
672673
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
673-
versionsBefore = clearUploadIdFromVersions(res.Versions);
674+
versionsBefore = clearUploadIdAndRestoreStatusFromVersions(res.Versions);
674675
return next(err);
675676
}),
676677
next => getMetadata(bucketName, objectName, vId, (err, objMD) => {
@@ -683,7 +684,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
683684
return next(err);
684685
}),
685686
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
686-
versionsAfter = clearUploadIdFromVersions(res.Versions);
687+
versionsAfter = clearUploadIdAndRestoreStatusFromVersions(res.Versions);
687688
return next(err);
688689
}),
689690
], err => {
@@ -729,7 +730,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
729730
}),
730731
next => fakeMetadataArchive(bucketName, objectName, vId, archive, next),
731732
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
732-
versionsBefore = clearUploadIdFromVersions(res.Versions);
733+
versionsBefore = clearUploadIdAndRestoreStatusFromVersions(res.Versions);
733734
return next(err);
734735
}),
735736
next => getMetadata(bucketName, objectName, vId, (err, objMD) => {
@@ -743,7 +744,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
743744
return next(err);
744745
}),
745746
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
746-
versionsAfter = clearUploadIdFromVersions(res.Versions);
747+
versionsAfter = clearUploadIdAndRestoreStatusFromVersions(res.Versions);
747748
return next(err);
748749
}),
749750
], err => {
@@ -777,7 +778,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
777778
next => s3.putObject(params, next),
778779
next => fakeMetadataArchive(bucketName, objectName, undefined, archive, next),
779780
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
780-
versionsBefore = clearUploadIdFromVersions(res.Versions);
781+
versionsBefore = clearUploadIdAndRestoreStatusFromVersions(res.Versions);
781782
return next(err);
782783
}),
783784
next => getMetadata(bucketName, objectName, undefined, (err, objMD) => {
@@ -791,7 +792,7 @@ describe('MPU with x-scal-s3-version-id header', () => {
791792
return next(err);
792793
}),
793794
next => metadata.listObject(bucketName, mdListingParams, log, (err, res) => {
794-
versionsAfter = clearUploadIdFromVersions(res.Versions);
795+
versionsAfter = clearUploadIdAndRestoreStatusFromVersions(res.Versions);
795796
return next(err);
796797
}),
797798
], err => {

0 commit comments

Comments
 (0)