UNPKG

aws-iam-policy-tool

Version:
142 lines (141 loc) 5.59 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); const iam_1 = require("../aws/iam"); const result_1 = require("../utils/result"); const attach_1 = require("../aws/attach"); const operation_1 = require("../aws/operation"); class RoleRegisterer { constructor(opts = {}) { this._overwrite = opts['overwrite'] || false; } async register(roleEntry) { try { const results = []; await this._createRoleOrWithInstanceProfile(roleEntry, results); const rolePolicies = await this._getRolePolicies(roleEntry); const attachPromises = []; const attachResults = await Promise.all(attachPromises.concat(rolePolicies.attaching.map((entry) => this._attachRolePolicy(entry)), rolePolicies.detaching.map((entry) => this._detachRolePolicy(entry)), rolePolicies.unchanged.map((entry) => { const policyName = onlyPolicyName(entry.PolicyArn); return Promise.resolve(result_1.Skip('Policy: %1 is already attached on Role: %2', [ policyName, entry.RoleName, ])); }))); return results.concat(attachResults); } catch (err) { console.error(err); return result_1.NG('Failed to create Role: %1 invalid JSON where %2', [ roleEntry.name, err.message, ]); } } async _createRoleOrWithInstanceProfile(roleEntry, results) { const roleName = roleEntry.Role.RoleName; const createdRole = await this._createRole(roleEntry.Role, results); if (createdRole && roleEntry.Role.isEc2Role) { const result = await this._createInstanceProfile(roleName, results); if (result !== null) { await this._addRoleToInstanceProfile(roleName, roleName, results); } } return createdRole; } async _createRole(roleNode, results) { const roleName = roleNode.RoleName; if (roleNode.Path.startsWith('/aws-service-role/')) { results.push(result_1.Skip('Role: %1 is AWS Service linked.', roleName)); return null; } try { const role = await operation_1.createRole(roleNode.toCreateRoleParams()); results.push(result_1.OK('Created Role: %1', roleName)); return roleNode; } catch (err) { if (err.code === 'EntityAlreadyExists') { results.push(result_1.Skip('Role: %1 already exists.', roleName)); return null; } else if (err.code === 'MalformedPolicyDocument') { return result_1.NG('Failed to create Role: %1 invalid JSON where %2', [ roleName, err.message, ]); } results.push(result_1.NG('Failed to create Role: %1', roleName)); throw err; } } async _createInstanceProfile(roleName, results) { const params = { InstanceProfileName: roleName, }; try { const data = await iam_1.iam.createInstanceProfile(params).promise(); results.push(result_1.OK('Created InstanceProfile: %1', roleName)); return data.InstanceProfile; } catch (err) { if (err.code === 'EntityAlreadyExists') { results.push(result_1.Skip('InstanceProfile: %1 already exists.', roleName)); return null; } results.push(result_1.NG('Failed to create InstanceProfile: %1', roleName)); throw err; } } async _addRoleToInstanceProfile(profileName, roleName, results) { const params = { InstanceProfileName: profileName, RoleName: roleName, }; try { iam_1.iam.addRoleToInstanceProfile(params).promise(); results.push(result_1.OK('Added InstanceProfile: %1 to Role: %2', [profileName, roleName])); } catch (err) { /*if (err.code === 'LimitExceeded') { console.log(Status.Skip, err.message) return }*/ throw err; } } async _getRolePolicies(role) { const roleName = role.Role.RoleName; const policyList = role.AttachedPolicies.map((item) => { return { RoleName: roleName, PolicyArn: item.PolicyArn, }; }); return attach_1.diffAttachedPolicies(roleName, policyList); } async _attachRolePolicy(params) { const policyName = onlyPolicyName(params.PolicyArn); try { await iam_1.iam.attachRolePolicy(params).promise(); return result_1.OK('Attached %1 on %2', [policyName, params.RoleName]); } catch (err) { if (err.code === 'NoSuchEntity') { return result_1.NG('Could not attach Policy: %1 that does not exist on %2.', [ policyName, params.RoleName, ]); } throw err; } } async _detachRolePolicy(params) { const policyName = onlyPolicyName(params.PolicyArn); await iam_1.iam.detachRolePolicy(params).promise(); return result_1.OK('Detached %1 on %2', [policyName, params.RoleName]); } } exports.RoleRegisterer = RoleRegisterer; function onlyPolicyName(policyArn) { return policyArn.substr(policyArn.indexOf('/') + 1); }