UNPKG

alks

Version:
177 lines (157 loc) 4.81 kB
import { white } from 'cli-color'; import { last, sortBy, where } from 'underscore'; import { getAlks } from './getAlks'; import moment from 'moment'; import ALKS from 'alks.js'; import { log } from './log'; import { badAccountMessage } from './badAccountMessage'; import { Key } from '../model/keys'; import { ensureConfigured } from './ensureConfigured'; import { getAuth } from './getAuth'; import { promptForAlksAccountAndRole } from './promptForAlksAccountAndRole'; import { getKeys } from './getKeys'; import { addKey } from './addKey'; import { getAwsAccountFromString } from './getAwsAccountFromString'; interface NewChangeRequestOptions { ciid: string; activityType: string; description: string; } interface ExistingChangeRequestOptions { changeNumber: string; } export type ChangeRequestOptions = | NewChangeRequestOptions | ExistingChangeRequestOptions; export async function getIamKey( alksAccount: string | undefined, alksRole: string | undefined, forceNewSession: boolean = false, filterFavorites: boolean = false, iamOnly: boolean = true, sessionDuration: number | undefined = undefined, changeRequestOptions: ChangeRequestOptions | object = {} ): Promise<Key> { await ensureConfigured(); log('getting auth'); const auth = await getAuth(); // only lookup alks account if they didnt provide if (!alksAccount || !alksRole) { log('getting accounts'); ({ alksAccount, alksRole } = await promptForAlksAccountAndRole({ iamOnly, filterFavorites, })); } else { log('using provided account/role'); } const awsAccount = await getAwsAccountFromString(alksAccount); if (!awsAccount) { throw new Error(badAccountMessage); } log('getting existing keys'); const existingKeys: Key[] = await getKeys(auth, true); log('got existing keys'); if (existingKeys.length && !forceNewSession) { log( `filtering keys by ${awsAccount.id}(${awsAccount?.alias}) with role ${alksRole}` ); // filter keys for the selected alks account/role const keyCriteria = { alksAccount: awsAccount.id, alksRole }; // filter, sort by expiration, grab last key to expire const selectedKey = last( sortBy(where(existingKeys, keyCriteria), 'expires') ); if (selectedKey) { log('found existing valid key'); console.error( white.underline( `Resuming existing session in "${ awsAccount.label ?? awsAccount.alias }" (id=${awsAccount.id} alias=${awsAccount.alias}) for ${alksRole}` ) ); return selectedKey; } } // generate a new key/session if (forceNewSession) { log('forcing a new session'); } const alks = await getAlks({ ...auth, }); const loginRole = await alks.getLoginRole({ accountId: awsAccount.id, role: alksRole, }); const duration = Math.min(loginRole.maxKeyDuration, sessionDuration ?? 12); console.error( white.underline( `Creating new session in "${awsAccount.label ?? awsAccount.alias}" (id=${ awsAccount.id } alias=${ awsAccount.alias }) for ${alksRole} expiring in ${duration} hour${ duration === 1 ? '' : 's' }` ) ); let alksKey: ALKS.Key; try { if (changeRequestOptions?.hasOwnProperty('changeNumber')) { alksKey = await alks.getIAMKeys({ account: awsAccount.id, role: alksRole, sessionTime: duration, changeRequestNumber: ( changeRequestOptions as ExistingChangeRequestOptions ).changeNumber, }); } else if (changeRequestOptions?.hasOwnProperty('ciid')) { alksKey = await alks.getIAMKeys({ account: awsAccount.id, role: alksRole, sessionTime: duration, primaryCI: (changeRequestOptions as NewChangeRequestOptions).ciid, category: (changeRequestOptions as NewChangeRequestOptions) .activityType, description: (changeRequestOptions as NewChangeRequestOptions) .description, }); } else { alksKey = await alks.getIAMKeys({ account: awsAccount.id, role: alksRole, sessionTime: duration, }); } } catch (e) { throw new Error(badAccountMessage); } const key: Key = { accessKey: alksKey.accessKey, secretKey: alksKey.secretKey, sessionToken: alksKey.sessionToken, changeNumber: alksKey.changeRequestNumber, expires: moment().add(duration, 'hours').toDate(), alksAccount: awsAccount.id, alksRole, isIAM: true, }; log('storing key: ' + JSON.stringify(key), { unsafe: true, alt: 'storing key', }); await addKey( key.accessKey, key.secretKey, key.sessionToken, awsAccount.id, alksRole, key.expires, auth, true ); return key; }