aws-iam-policy-tool
Version:
AWS IAM role/policy management cli tool
142 lines (141 loc) • 5.59 kB
JavaScript
;
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);
}