@csermet/multiprovider
Version:
cloud-graph provider plugin for AWS used to fetch AWS cloud data.
185 lines (184 loc) • 7.37 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.listIamRoles = exports.getAccountAuthorizationDetails = void 0;
const sdk_1 = __importDefault(require("@cloudgraph/sdk"));
const groupBy_1 = __importDefault(require("lodash/groupBy"));
const isEmpty_1 = __importDefault(require("lodash/isEmpty"));
const iam_1 = __importDefault(require("aws-sdk/clients/iam"));
const logger_1 = __importDefault(require("../../properties/logger"));
const utils_1 = require("../../utils");
const errorLog_1 = __importDefault(require("../../utils/errorLog"));
const regions_1 = require("../../enums/regions");
const format_1 = require("../../utils/format");
const constants_1 = require("../../config/constants");
const lt = { ...logger_1.default };
const { logger } = sdk_1.default;
const serviceName = 'IAM Role';
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.IAM_CUSTOM_DELAY,
});
const roleByRoleName = async (iam, { RoleName }) => new Promise(resolve => {
iam.getRole({ RoleName }, (err, data) => {
if (err) {
errorLog.generateAwsErrorLog({
err,
functionName: 'iam:getRole',
});
}
if (!isEmpty_1.default(data)) {
const { Role } = data;
resolve({
RoleName,
Role,
});
}
resolve(null);
});
});
const tagsByRoleName = async (iam, { RoleName }) => new Promise(resolve => {
iam.listRoleTags({ RoleName }, (err, data) => {
if (err) {
errorLog.generateAwsErrorLog({
functionName: 'iam:listRoleTags',
err,
});
}
if (!isEmpty_1.default(data)) {
const { Tags: tags = [] } = data;
resolve({
RoleName,
Tags: format_1.convertAwsTagsToTagMap(tags),
});
}
resolve(null);
});
});
const managedPoliciesByRoleName = async (iam, { RoleName }) => new Promise(resolve => {
iam.listAttachedRolePolicies({ RoleName }, (err, data) => {
if (err) {
errorLog.generateAwsErrorLog({
functionName: 'iam:listAttachedRolePolicies',
err,
});
}
if (!isEmpty_1.default(data)) {
const { AttachedPolicies = [] } = data;
resolve({
RoleName,
ManagedPolicies: AttachedPolicies,
});
}
resolve(null);
});
});
const getAccountAuthorizationDetails = async (iam, marker) => new Promise(resolve => {
const result = [];
iam.getAccountAuthorizationDetails({ Filter: ['Role'], Marker: marker }, async (err, data) => {
if (err) {
errorLog.generateAwsErrorLog({
functionName: 'iam:getAccountAuthorizationDetails',
err,
});
}
if (!isEmpty_1.default(data) && !isEmpty_1.default(data.RoleDetailList)) {
const { Marker, IsTruncated, RoleDetailList } = data;
result.push(...RoleDetailList);
if (IsTruncated) {
result.push(...(await exports.getAccountAuthorizationDetails(iam, Marker)));
}
resolve(result);
}
resolve([]);
});
});
exports.getAccountAuthorizationDetails = getAccountAuthorizationDetails;
const listIamRoles = async ({ iam, marker, roleInlinePolicyMap, }) => new Promise(resolve => {
const result = [];
const tagsByRoleNamePromises = [];
const managedPoliciesByRoleNamePromises = [];
const roleByRoleNamePromises = [];
iam.listRoles({ Marker: marker }, async (err, data) => {
if (err) {
errorLog.generateAwsErrorLog({
functionName: 'iam:listRoles',
err,
});
}
if (!isEmpty_1.default(data)) {
const { Roles: roles = [], IsTruncated, Marker } = data;
roles.map(role => {
tagsByRoleNamePromises.push(tagsByRoleName(iam, role));
managedPoliciesByRoleNamePromises.push(managedPoliciesByRoleName(iam, role));
roleByRoleNamePromises.push(roleByRoleName(iam, role));
});
const tags = await Promise.all(tagsByRoleNamePromises);
const managedPolicies = await Promise.all(managedPoliciesByRoleNamePromises);
const detailedRoles = await Promise.all(roleByRoleNamePromises);
result.push(...roles.map(({ RoleName, AssumeRolePolicyDocument, PermissionsBoundary, Tags, ...role }) => {
return {
RoleName,
AssumeRolePolicyDocument: decodeURIComponent(AssumeRolePolicyDocument),
...role,
region: regions_1.globalRegionName,
RoleLastUsed: detailedRoles?.find(r => r?.RoleName === RoleName)?.Role.RoleLastUsed,
ManagedPolicies: managedPolicies
?.filter(p => p?.RoleName === RoleName)
.map(p => p.ManagedPolicies)
.reduce((current, acc) => [...acc, ...current], []) || [],
Tags: tags.find(t => t?.RoleName === RoleName)?.Tags || {},
...(PermissionsBoundary?.PermissionsBoundaryArn
? {
PermissionsBoundaryArn: PermissionsBoundary?.PermissionsBoundaryArn,
}
: {}),
InlinePolicies: roleInlinePolicyMap[RoleName] ?? [],
};
}));
if (IsTruncated) {
result.push(...(await exports.listIamRoles({
iam,
marker: Marker,
roleInlinePolicyMap,
})));
}
resolve(result);
}
resolve([]);
});
});
exports.listIamRoles = listIamRoles;
/**
* IAM Role
*/
exports.default = async ({ config, }) => new Promise(async (resolve) => {
let rolesData = [];
const client = new iam_1.default({
...config,
region: regions_1.globalRegionName,
endpoint,
...customRetrySettings,
});
logger.debug(lt.lookingForIamRoles);
// Fetch role authorization details first
const roleAuthorizationDetails = await exports.getAccountAuthorizationDetails(client);
// Create inlinePolicies map
const roleInlinePolicyMap = {};
roleAuthorizationDetails.map(roleDetail => {
roleInlinePolicyMap[roleDetail.RoleName] = roleDetail.RolePolicyList.map(({ PolicyName, PolicyDocument }) => ({
name: PolicyName,
// PolicyDocument is URI encoded
document: decodeURIComponent(PolicyDocument),
}));
});
// Fetch IAM Roles
rolesData = await exports.listIamRoles({ iam: client, roleInlinePolicyMap });
errorLog.reset();
logger.debug(lt.foundRoles(rolesData.length));
resolve(groupBy_1.default(rolesData, 'region'));
});