UNPKG

@cloud-copilot/iam-collect

Version:

Collect IAM information from AWS Accounts

193 lines 7.99 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.S3GeneralPurposeBucketSync = void 0; const client_s3_1 = require("@aws-sdk/client-s3"); const client_tools_js_1 = require("../../utils/client-tools.js"); const tags_js_1 = require("../../utils/tags.js"); const sync_js_1 = require("../sync.js"); const typedSync_js_1 = require("../typedSync.js"); const gpBuckets = 'generalPurposeBuckets'; exports.S3GeneralPurposeBucketSync = { awsService: 's3', name: gpBuckets, execute: async (accountId, region, credentials, storage, endpoint, syncOptions) => { const s3Client = syncOptions.clientPool.client(client_s3_1.S3Client, credentials, region, endpoint); const allBuckets = await (0, client_tools_js_1.withDnsRetry)(async () => { return (0, typedSync_js_1.paginateResource)(s3Client, client_s3_1.ListBucketsCommand, 'Buckets', { inputKey: 'ContinuationToken', outputKey: 'ContinuationToken' }, { MaxBuckets: 1000, BucketRegion: region }); }); const augmentedBuckets = await Promise.all(allBuckets.map(async (bucket) => { const arn = `arn:${credentials.partition}:s3:::${bucket.Name}`; const [tagsJob, blockPublicAccessConfigJob, bucketPolicyJob, encryptionJob, abacEnabledJob] = await Promise.all(syncOptions.workerPool.enqueueAll([ { execute: () => { return (0, client_tools_js_1.withDnsRetry)(async () => { return getTagsForBucket(s3Client, bucket, arn); }); }, properties: {} }, { execute: () => { return (0, client_tools_js_1.withDnsRetry)(async () => { return getBucketPublicAccessSettings(s3Client, bucket, arn); }); }, properties: {} }, { execute: () => { return (0, client_tools_js_1.withDnsRetry)(async () => { return getBucketPolicy(s3Client, bucket, credentials.accountId, arn); }); }, properties: {} }, { execute: () => { return (0, client_tools_js_1.withDnsRetry)(async () => { return getBucketEncryptionSettings(s3Client, bucket, arn); }); }, properties: {} }, { execute: () => { return (0, client_tools_js_1.withDnsRetry)(async () => { return getBucketAbacEnabled(s3Client, bucket, arn); }); }, properties: {} } ])); for (const job of [ tagsJob, blockPublicAccessConfigJob, bucketPolicyJob, encryptionJob, abacEnabledJob ]) { if (job.status === 'rejected') { throw job.reason; } } const [tags, blockPublicAccessConfig, bucketPolicy, encryption, abacEnabled] = [ tagsJob.value, blockPublicAccessConfigJob.value, bucketPolicyJob.value, encryptionJob.value, abacEnabledJob.value ]; return { arn, tags: tags, bpa: blockPublicAccessConfig, policy: bucketPolicy, encryption: encryption?.Rules, metadata: { name: bucket.Name, region: region, arn, abacEnabled } }; })); (0, sync_js_1.syncData)(augmentedBuckets, storage, accountId, { service: 's3', account: accountId, metadata: { region } }, syncOptions.writeOnly); } }; /** * Get the tags for a bucket. * * @param client the S3 client to use * @param bucket the bucket to get the tags for * @returns the tags for the bucket, if any */ async function getTagsForBucket(client, bucket, arn) { const tagCommand = new client_s3_1.GetBucketTaggingCommand({ Bucket: bucket.Name }); const tags = await (0, client_tools_js_1.runAndCatchAccessDeniedWithLog)(arn, 's3', gpBuckets, 'tags', async () => { return (0, client_tools_js_1.runAndCatch404)(async () => { const response = await client.send(tagCommand); return (0, tags_js_1.convertTagsToRecord)(response.TagSet); }); }); return tags; } /** * Get the bucket policy for a bucket. * * @param client the S3 client to use * @param bucket the bucket to get the policy for * @param accountId the account ID of the bucket owner * @returns the bucket policy for the bucket, if any */ async function getBucketPolicy(client, bucket, accountId, arn) { const policyCommand = new client_s3_1.GetBucketPolicyCommand({ Bucket: bucket.Name, ExpectedBucketOwner: accountId }); const policy = await (0, client_tools_js_1.runAndCatchAccessDeniedWithLog)(arn, 's3', gpBuckets, 'policy', async () => { return (0, client_tools_js_1.runAndCatch404)(async () => { const response = await client.send(policyCommand); return response.Policy ? JSON.parse(response.Policy) : undefined; }); }); return policy; } /** * Get the public access block configuration for a bucket. * * @param client The S3 client to use. * @param bucket the bucket to get the public access settings for * @returns the public access block configuration for the bucket, if any */ async function getBucketPublicAccessSettings(client, bucket, arn) { const command = new client_s3_1.GetPublicAccessBlockCommand({ Bucket: bucket.Name }); const response = await (0, client_tools_js_1.runAndCatchAccessDeniedWithLog)(arn, 's3', gpBuckets, 'blockPublicAccess', async () => { return (0, client_tools_js_1.runAndCatch404)(async () => { return await client.send(command); }); }); return response?.PublicAccessBlockConfiguration; } /** * Get the bucket encryption settings for a bucket. * * @param client the S3 client to use * @param bucket the bucket to get the encryption settings for * @returns encryption settings for the bucket, if any */ async function getBucketEncryptionSettings(client, bucket, arn) { const command = new client_s3_1.GetBucketEncryptionCommand({ Bucket: bucket.Name }); const response = await (0, client_tools_js_1.runAndCatchAccessDeniedWithLog)(arn, 's3', gpBuckets, 'encryption', async () => { return (0, client_tools_js_1.runAndCatch404)(async () => { return await client.send(command); }); }); return response?.ServerSideEncryptionConfiguration; } /** * Check if ABAC is enabled for the bucket. * * @param client the S3 client to use * @param bucket the bucket to check * @param arn the ARN of the bucket * @returns true if ABAC is enabled, undefined otherwise */ async function getBucketAbacEnabled(client, bucket, arn) { const command = new client_s3_1.GetBucketAbacCommand({ Bucket: bucket.Name }); const response = await (0, client_tools_js_1.runAndCatchAccessDeniedWithLog)(arn, 's3', gpBuckets, 'abacEnabled', async () => { return (0, client_tools_js_1.runAndCatch404)(async () => { return await client.send(command); }); }); return response?.AbacStatus?.Status === 'Enabled' ? true : undefined; } //# sourceMappingURL=buckets.js.map