diff --git a/.changes/next-release/feature-S3Control-8b5d37ea.json b/.changes/next-release/feature-S3Control-8b5d37ea.json new file mode 100644 index 0000000000..145d29682a --- /dev/null +++ b/.changes/next-release/feature-S3Control-8b5d37ea.json @@ -0,0 +1,5 @@ +{ + "type": "feature", + "category": "S3Control", + "description": "Support FIPS for S3 Outposts" +} \ No newline at end of file diff --git a/lib/services/s3control.js b/lib/services/s3control.js index ff54ec3125..c78b2c2dbc 100644 --- a/lib/services/s3control.js +++ b/lib/services/s3control.js @@ -27,7 +27,7 @@ AWS.util.update(AWS.S3Control.prototype, { } if (isArnInBucket || isArnInName) { - request.addListener('validate', s3util.validateArnRegion); + request.addListener('validate', this.validateArnRegion); request.addListener('validate', this.validateArnAccountWithParams, true); request.addListener('validate', s3util.validateArnAccount); request.addListener('validate', s3util.validateArnService); @@ -98,9 +98,10 @@ AWS.util.update(AWS.S3Control.prototype, { var endpoint = req.httpRequest.endpoint; var useArnRegion = req.service.config.s3UseArnRegion; + var useFipsEndpoint = req.service.config.useFipsEndpoint; endpoint.hostname = [ - 's3-outposts', + 's3-outposts' + (useFipsEndpoint ? '-fips': ''), useArnRegion ? parsedArn.region : req.service.config.region, 'amazonaws.com' ].join('.'); @@ -112,8 +113,9 @@ AWS.util.update(AWS.S3Control.prototype, { */ populateEndpointForOutpostId: function populateEndpointForOutpostId(req) { var endpoint = req.httpRequest.endpoint; + var useFipsEndpoint = req.service.config.useFipsEndpoint; endpoint.hostname = [ - 's3-outposts', + 's3-outposts' + (useFipsEndpoint ? '-fips': ''), req.service.config.region, 'amazonaws.com' ].join('.'); @@ -131,6 +133,13 @@ AWS.util.update(AWS.S3Control.prototype, { } }, + /** + * @api private + */ + validateArnRegion: function validateArnRegion(req) { + s3util.validateArnRegion(req, { allowFipsEndpoint: true }); + }, + /** * @api private */ diff --git a/test/services/s3control.spec.js b/test/services/s3control.spec.js index 31b9ee8a29..bbd95f741d 100644 --- a/test/services/s3control.spec.js +++ b/test/services/s3control.spec.js @@ -205,7 +205,7 @@ describe('AWS.S3Control', function() { }); }); - it('should correctly generate access point endpoint for pseudo regions', function() { + it('should correctly generate access point endpoint for s3-external-1', function() { var client = new AWS.S3Control({region: 'us-east-1'}); helpers.mockHttpResponse(200, {}, ''); var request = client.getBucket({ @@ -215,22 +215,32 @@ describe('AWS.S3Control', function() { expect( built.httpRequest.endpoint.hostname ).to.equal('s3-outposts.s3-external-1.amazonaws.com'); + }); - var testFipsError = (client) => { - helpers.mockHttpResponse(200, {}, ''); - request = client.getBucket({ - Bucket: 'arn:aws:s3-outposts:s3-external-1:123456789012:outpost/op-01234567890123456/bucket/mybucket' - }); - var error; - request.build(function(err) { - error = err; - }); - expect(error.name).to.equal('InvalidConfiguration'); - expect(error.message).to.equal('ARN endpoint is not compatible with FIPS region'); - }; - testFipsError(new AWS.S3Control({region: 'fips-us-east-1'})); - testFipsError(new AWS.S3Control({region: 'us-east-1-fips'})); - testFipsError(new AWS.S3Control({region: 'us-east-1', useFipsEndpoint: true})); + it('should correctly generate access point endpoint when useFipsEndpoint=true', function() { + var client = new AWS.S3Control({region: 'us-gov-west-1', useFipsEndpoint: true}); + helpers.mockHttpResponse(200, {}, ''); + var request = client.getBucket({ + Bucket: 'arn:aws:s3-outposts:us-gov-west-1:123456789012:outpost/op-01234567890123456/bucket/mybucket' + }); + var built = request.build(function() {}); + expect( + built.httpRequest.endpoint.hostname + ).to.equal('s3-outposts-fips.us-gov-west-1.amazonaws.com'); + }); + + it('should throw when fips region is passed in ARN', function() { + var client = new AWS.S3Control({region: 'us-gov-west-1', useFipsEndpoint: true}); + helpers.mockHttpResponse(200, {}, ''); + var request = client.getBucket({ + Bucket: 'arn:aws:s3-outposts:fips-us-gov-west-1:123456789012:outpost/op-01234567890123456/bucket/mybucket' + }); + var error; + request.build(function(err) { + error = err; + }); + expect(error.name).to.equal('InvalidConfiguration'); + expect(error.message).to.equal('FIPS region not allowed in ARN'); }); it('should use regions from ARN if s3UseArnRegion config is set to false', function(done) {