@cloud-copilot/iam-collect
Version:
Collect IAM information from AWS Accounts
193 lines • 7.99 kB
JavaScript
"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