import ALKS from 'alks.js'; import clc from 'cli-color'; import commander from 'commander'; import { isEmpty, isUndefined } from 'underscore'; import { checkForUpdate } from '../checkForUpdate'; import { errorAndExit } from '../errorAndExit'; import { getAlks } from '../getAlks'; import { promptForAlksAccountAndRole } from '../promptForAlksAccountAndRole'; import { getAuth } from '../getAuth'; import { log } from '../log'; import { tryToExtractRole } from '../tryToExtractRole'; import { unpackTags } from '../unpackTags'; import { getAwsAccountFromString } from '../getAwsAccountFromString'; import { badAccountMessage } from '../badAccountMessage'; export async function handleAlksIamCreateTrustRole( options: commander.OptionValues ) { const roleNameDesc = 'alphanumeric including @+=._-'; const trustArnDesc = 'arn:aws|aws-us-gov:iam::d{12}:role/TestRole'; const ROLE_NAME_REGEX = /^[a-zA-Z0-9!@+=._-]+$/g; const TRUST_ARN_REGEX = /arn:(aws|aws-us-gov):iam::\d{12}:role\/?[a-zA-Z_0-9+=,.@-_/]+/g; const roleName = options.rolename; const roleType = options.roletype; const trustArn = options.trustarn; const enableAlksAccess = options.enableAlksAccess; let alksAccount = options.account as string | undefined; let alksRole = options.role as string | undefined; const tags = options.tags ? unpackTags(options.tags) : undefined; const filterFavorites = options.favorites || false; log('validating role name: ' + roleName); if (isEmpty(roleName) || !ROLE_NAME_REGEX.test(roleName)) { errorAndExit( 'The role name provided contains illegal characters. It must be ' + roleNameDesc ); } log('validating role type: ' + roleType); if ( isEmpty(roleType) || (roleType !== 'Cross Account' && roleType !== 'Inner Account') ) { errorAndExit('The role type is required'); } log('validating trust arn: ' + trustArn); if (isEmpty(trustArn) || !TRUST_ARN_REGEX.test(trustArn)) { errorAndExit( 'The trust arn provided contains illegal characters. It must be ' + trustArnDesc ); } if (!isUndefined(alksAccount) && isUndefined(alksRole)) { log('trying to extract role from account'); alksRole = tryToExtractRole(alksAccount); } try { if (!alksAccount || !alksRole) { log('getting accounts'); ({ alksAccount, alksRole } = await promptForAlksAccountAndRole({ iamOnly: true, filterFavorites, })); } else { log('using provided account/role'); } const auth = await getAuth(); const awsAccount = await getAwsAccountFromString(alksAccount); if (!awsAccount) { throw new Error(badAccountMessage); } log('calling api to create trust role: ' + roleName); const alks = await getAlks({ ...auth, }); let role; try { role = await alks.createNonServiceRole({ account: awsAccount.id, role: alksRole, roleName, roleType, trustArn, enableAlksAccess, includeDefaultPolicy: ALKS.PseudoBoolean.False, tags, }); } catch (err) { errorAndExit(err as Error); } console.log( clc.white(`The role "${roleName}" was created with the ARN: `) + clc.white.underline(role.roleArn) ); if (role.instanceProfileArn) { console.log( clc.white('An instance profile was also created with the ARN: ') + clc.white.underline(role.instanceProfileArn) ); } await checkForUpdate(); } catch (err) { errorAndExit((err as Error).message, err as Error); } }