UNPKG

@csermet/multiprovider

Version:

cloud-graph provider plugin for AWS used to fetch AWS cloud data.

207 lines (206 loc) 7.71 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const sns_1 = __importDefault(require("aws-sdk/clients/sns")); const sdk_1 = __importDefault(require("@cloudgraph/sdk")); const groupBy_1 = __importDefault(require("lodash/groupBy")); const isEmpty_1 = __importDefault(require("lodash/isEmpty")); const logger_1 = __importDefault(require("../../properties/logger")); const format_1 = require("../../utils/format"); const errorLog_1 = __importDefault(require("../../utils/errorLog")); const utils_1 = require("../../utils"); const constants_1 = require("../../config/constants"); const lt = { ...logger_1.default }; const { logger } = sdk_1.default; const serviceName = 'SNS'; const errorLog = new errorLog_1.default(serviceName); const endpoint = utils_1.initTestEndpoint(serviceName); const customRetrySettings = utils_1.setAwsRetryOptions({ maxRetries: constants_1.MAX_FAILED_AWS_REQUEST_RETRIES, baseDelay: constants_1.SNS_CUSTOM_DELAY, }); const listSnsTopicArnsForRegion = async ({ sns, resolveRegion, }) => new Promise(resolve => { const topicArnList = []; const listTopicArnNameOpts = {}; const listTopicArns = (token) => { if (token) { listTopicArnNameOpts.NextToken = token; } try { sns.listTopics(listTopicArnNameOpts, (err, listTopicArnsOutput) => { if (err) { errorLog.generateAwsErrorLog({ functionName: 'sns:listTopics', err, }); } /** * No SNS data for this region */ if (isEmpty_1.default(listTopicArnsOutput)) { return resolveRegion(); } const { Topics, NextToken: nextToken } = listTopicArnsOutput; /** * No SNS Topics for this region */ if (isEmpty_1.default(Topics)) { return resolveRegion(); } topicArnList.push(...Topics); if (nextToken) { listTopicArns(nextToken); } else { resolve(topicArnList); } }); } catch (error) { resolve([]); } }; listTopicArns(); }); const getTopicAttributes = async (sns, arn) => new Promise(resolve => { sns.getTopicAttributes({ TopicArn: arn }, (err, topicAttributesData) => { if (err || !topicAttributesData) { errorLog.generateAwsErrorLog({ functionName: 'sns:getTopicAttributes', err, }); } const { Attributes = {} } = topicAttributesData || {}; resolve(Attributes); }); }); const getTopicTags = async (sns, arn) => new Promise(resolveTags => { try { sns.listTagsForResource({ ResourceArn: arn }, (err, data) => { if (err) { errorLog.generateAwsErrorLog({ functionName: 'sns:listTagsForResource', err, }); return resolveTags({}); } const { Tags = [] } = data || {}; resolveTags(format_1.convertAwsTagsToTagMap(Tags)); }); } catch (error) { resolveTags({}); } }); const getTopicSubscriptions = async (sns, arn) => new Promise(resolveSubscriptions => { const subscriptions = []; const listSubscriptionsOpts = { TopicArn: arn, }; const listAllSubscriptions = (token) => { if (token) { listSubscriptionsOpts.NextToken = token; } try { sns.listSubscriptionsByTopic(listSubscriptionsOpts, (err, data) => { if (err) { errorLog.generateAwsErrorLog({ functionName: 'sns:listSubscriptionsByTopic', err, }); } if (isEmpty_1.default(data)) { return resolveSubscriptions([]); } const { Subscriptions, NextToken } = data || {}; if (isEmpty_1.default(Subscriptions)) { return resolveSubscriptions([]); } subscriptions.push(...Subscriptions); if (NextToken) { logger.debug(lt.foundAnotherThousand); listAllSubscriptions(NextToken); } else { resolveSubscriptions(subscriptions); } }); } catch (error) { resolveSubscriptions([]); } }; listAllSubscriptions(); }); exports.default = async ({ regions, config, }) => new Promise(async (resolve) => { const snsData = []; const regionPromises = []; const topicPromises = []; const tagsPromises = []; const subscriptionsPromises = []; // First we get all sns topics arn for all regions regions.split(',').map(region => { const sns = new sns_1.default({ ...config, region, endpoint, ...customRetrySettings, }); const regionPromise = new Promise(async (resolveRegion) => { const snsTopicArnList = await listSnsTopicArnsForRegion({ sns, resolveRegion, }); snsData.push(...snsTopicArnList.map((topic) => ({ ...topic, region, }))); resolveRegion(); }); regionPromises.push(regionPromise); }); await Promise.all(regionPromises); logger.debug(lt.fetchedSNSTopics(snsData.length)); // Then we get all attributes for each topic using the arn snsData.map(({ TopicArn: arn, region }, idx) => { const sns = new sns_1.default({ ...config, region, endpoint }); const topicPromise = new Promise(async (resolveTopic) => { const snsAttributes = await getTopicAttributes(sns, arn); snsData[idx] = { ...snsData[idx], ...snsAttributes, }; resolveTopic(); }); topicPromises.push(topicPromise); }); logger.debug(lt.gettingSNSTopicAttributes); await Promise.all(topicPromises); // Afterwards we get all tags for each topic snsData.map(({ TopicArn: arn, region }, idx) => { const sns = new sns_1.default({ ...config, region, endpoint }); const tagsPromise = new Promise(async (resolveTags) => { snsData[idx].Tags = await getTopicTags(sns, arn); resolveTags(); }); tagsPromises.push(tagsPromise); }); logger.debug(lt.gettingSNSTopicTags); await Promise.all(tagsPromises); // Then we get all subscriptions for each topic snsData.map(({ TopicArn: arn, region }, idx) => { const sns = new sns_1.default({ ...config, region, endpoint }); const listSubscriptionsPromise = new Promise(async (resolveSubscriptions) => { const subscriptionList = await getTopicSubscriptions(sns, arn); snsData[idx].subscriptions = subscriptionList; resolveSubscriptions(); }); subscriptionsPromises.push(listSubscriptionsPromise); }); logger.debug(lt.gettingSNSTopicSubscriptions); await Promise.all(subscriptionsPromises); errorLog.reset(); resolve(groupBy_1.default(snsData, 'region')); });