UNPKG

@aws-cdk-testing/cli-integ

Version:

Integration tests for the AWS CDK CLI

109 lines 13.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.atmosphereEnabled = atmosphereEnabled; exports.atmosphereEndpoint = atmosphereEndpoint; exports.atmospherePool = atmospherePool; exports.withAws = withAws; exports.regionPool = regionPool; const cdk_atmosphere_client_1 = require("@cdklabs/cdk-atmosphere-client"); const aws_1 = require("./aws"); const resource_pool_1 = require("./resource-pool"); function atmosphereEnabled() { const enabled = process.env.CDK_INTEG_ATMOSPHERE_ENABLED; return enabled === 'true' || enabled === '1'; } function atmosphereEndpoint() { const value = process.env.CDK_INTEG_ATMOSPHERE_ENDPOINT; if (!value) { throw new Error('CDK_INTEG_ATMOSPHERE_ENDPOINT is not defined'); } return value; } function atmospherePool() { const value = process.env.CDK_INTEG_ATMOSPHERE_POOL; if (!value) { throw new Error('CDK_INTEG_ATMOSPHERE_POOL is not defined'); } return value; } /** * Higher order function to execute a block with an AWS client setup * * Allocate the next region from the REGION pool and dispose it afterwards. */ function withAws(block, disableBootstrap = false) { return async (context) => { if (atmosphereEnabled()) { const atmosphere = new cdk_atmosphere_client_1.AtmosphereClient(atmosphereEndpoint(), { logStream: context.output, }); const start = Date.now(); const allocation = await atmosphere.acquire({ pool: atmospherePool(), requester: context.name, timeoutSeconds: 60 * 30 }); context.reportWaitTime(Date.now() - start); const aws = await aws_1.AwsClients.forIdentity(allocation.environment.region, { accessKeyId: allocation.credentials.accessKeyId, secretAccessKey: allocation.credentials.secretAccessKey, sessionToken: allocation.credentials.sessionToken, accountId: allocation.environment.account, }, context.output); await sanityCheck(aws); let outcome = 'success'; try { return await block({ ...context, disableBootstrap, aws }); } catch (e) { outcome = 'failure'; throw e; } finally { await atmosphere.release(allocation.id, outcome); } } else { return regionPool().using(async (region) => { const aws = await aws_1.AwsClients.forRegion(region, context.output); await sanityCheck(aws); return block({ ...context, disableBootstrap, aws }); }); } }; } let _regionPool; function regionPool() { if (_regionPool !== undefined) { return _regionPool; } const REGIONS = process.env.AWS_REGIONS ? process.env.AWS_REGIONS.split(',') : [process.env.AWS_REGION ?? process.env.AWS_DEFAULT_REGION ?? 'us-east-1']; _regionPool = resource_pool_1.ResourcePool.withResources('aws_regions', REGIONS); return _regionPool; } /** * Perform a one-time quick sanity check that the AWS clients have properly configured credentials * * If we don't do this, calls are going to fail and they'll be retried and everything will take * forever before the user notices a simple misconfiguration. * * We can't check for the presence of environment variables since credentials could come from * anywhere, so do simple account retrieval. * * Only do it once per process. */ async function sanityCheck(aws) { if (sanityChecked === undefined) { try { await aws.account(); sanityChecked = true; } catch (e) { sanityChecked = false; throw new Error(`AWS credentials probably not configured, got error: ${e.message}`); } } if (!sanityChecked) { throw new Error('AWS credentials probably not configured, see previous error'); } } let sanityChecked; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2l0aC1hd3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ3aXRoLWF3cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQU1BLDhDQUdDO0FBRUQsZ0RBTUM7QUFFRCx3Q0FNQztBQVNELDBCQXlDQztBQUdELGdDQVdDO0FBekZELDBFQUFrRTtBQUNsRSwrQkFBbUM7QUFFbkMsbURBQStDO0FBRy9DLFNBQWdCLGlCQUFpQjtJQUMvQixNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLDRCQUE0QixDQUFDO0lBQ3pELE9BQU8sT0FBTyxLQUFLLE1BQU0sSUFBSSxPQUFPLEtBQUssR0FBRyxDQUFDO0FBQy9DLENBQUM7QUFFRCxTQUFnQixrQkFBa0I7SUFDaEMsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyw2QkFBNkIsQ0FBQztJQUN4RCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDWCxNQUFNLElBQUksS0FBSyxDQUFDLDhDQUE4QyxDQUFDLENBQUM7SUFDbEUsQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQztBQUVELFNBQWdCLGNBQWM7SUFDNUIsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyx5QkFBeUIsQ0FBQztJQUNwRCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDWCxNQUFNLElBQUksS0FBSyxDQUFDLDBDQUEwQyxDQUFDLENBQUM7SUFDOUQsQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQztBQUlEOzs7O0dBSUc7QUFDSCxTQUFnQixPQUFPLENBQ3JCLEtBQTJFLEVBQzNFLG1CQUE0QixLQUFLO0lBRWpDLE9BQU8sS0FBSyxFQUFFLE9BQVUsRUFBRSxFQUFFO1FBQzFCLElBQUksaUJBQWlCLEVBQUUsRUFBRSxDQUFDO1lBQ3hCLE1BQU0sVUFBVSxHQUFHLElBQUksd0NBQWdCLENBQUMsa0JBQWtCLEVBQUUsRUFBRTtnQkFDNUQsU0FBUyxFQUFFLE9B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RyxJQUFJLENBQUM7UUFDdkIsQ0FBQztRQUFDLE9BQU8sQ0FBTSxFQUFFLENBQUM7WUFDaEIsYUFBYSxHQUFHLEtBQUssQ0FBQztZQUN0QixNQUFNLElBQUksS0FBSyxDQUFDLHVEQUF1RCxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUN0RixDQUFDO0lBQ0gsQ0FBQztJQUNELElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNuQixNQUFNLElBQUksS0FBSyxDQUFDLDZEQUE2RCxDQUFDLENBQUM7SUFDakYsQ0FBQztBQUNILENBQUM7QUFDRCxJQUFJLGFBQWtDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBdG1vc3BoZXJlQ2xpZW50IH0gZnJvbSAnQGNka2xhYnMvY2RrLWF0bW9zcGhlcmUtY2xpZW50JztcbmltcG9ydCB7IEF3c0NsaWVudHMgfSBmcm9tICcuL2F3cyc7XG5pbXBvcnQgdHlwZSB7IFRlc3RDb250ZXh0IH0gZnJvbSAnLi9pbnRlZy10ZXN0JztcbmltcG9ydCB7IFJlc291cmNlUG9vbCB9IGZyb20gJy4vcmVzb3VyY2UtcG9vbCc7XG5pbXBvcnQgdHlwZSB7IERpc2FibGVCb290c3RyYXBDb250ZXh0IH0gZnJvbSAnLi93aXRoLWNkay1hcHAnO1xuXG5leHBvcnQgZnVuY3Rpb24gYXRtb3NwaGVyZUVuYWJsZWQoKTogYm9vbGVhbiB7XG4gIGNvbnN0IGVuYWJsZWQgPSBwcm9jZXNzLmVudi5DREtfSU5URUdfQVRNT1NQSEVSRV9FTkFCTEVEO1xuICByZXR1cm4gZW5hYmxlZCA9PT0gJ3RydWUnIHx8IGVuYWJsZWQgPT09ICcxJztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGF0bW9zcGhlcmVFbmRwb2ludCgpOiBzdHJpbmcge1xuICBjb25zdCB2YWx1ZSA9IHByb2Nlc3MuZW52LkNES19JTlRFR19BVE1PU1BIRVJFX0VORFBPSU5UO1xuICBpZiAoIXZhbHVlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDREtfSU5URUdfQVRNT1NQSEVSRV9FTkRQT0lOVCBpcyBub3QgZGVmaW5lZCcpO1xuICB9XG4gIHJldHVybiB2YWx1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGF0bW9zcGhlcmVQb29sKCkge1xuICBjb25zdCB2YWx1ZSA9IHByb2Nlc3MuZW52LkNES19JTlRFR19BVE1PU1BIRVJFX1BPT0w7XG4gIGlmICghdmFsdWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NES19JTlRFR19BVE1PU1BIRVJFX1BPT0wgaXMgbm90IGRlZmluZWQnKTtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59XG5cbmV4cG9ydCB0eXBlIEF3c0NvbnRleHQgPSB7IHJlYWRvbmx5IGF3czogQXdzQ2xpZW50cyB9O1xuXG4vKipcbiAqIEhpZ2hlciBvcmRlciBmdW5jdGlvbiB0byBleGVjdXRlIGEgYmxvY2sgd2l0aCBhbiBBV1MgY2xpZW50IHNldHVwXG4gKlxuICogQWxsb2NhdGUgdGhlIG5leHQgcmVnaW9uIGZyb20gdGhlIFJFR0lPTiBwb29sIGFuZCBkaXNwb3NlIGl0IGFmdGVyd2FyZHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3aXRoQXdzPEEgZXh0ZW5kcyBUZXN0Q29udGV4dD4oXG4gIGJsb2NrOiAoY29udGV4dDogQSAmIEF3c0NvbnRleHQgJiBEaXNhYmxlQm9vdHN0cmFwQ29udGV4dCkgPT4gUHJvbWlzZTx2b2lkPixcbiAgZGlzYWJsZUJvb3RzdHJhcDogYm9vbGVhbiA9IGZhbHNlLFxuKTogKGNvbnRleHQ6IEEpID0+IFByb21pc2U8dm9pZD4ge1xuICByZXR1cm4gYXN5bmMgKGNvbnRleHQ6IEEpID0+IHtcbiAgICBpZiAoYXRtb3NwaGVyZUVuYWJsZWQoKSkge1xuICAgICAgY29uc3QgYXRtb3NwaGVyZSA9IG5ldyBBdG1vc3BoZXJlQ2xpZW50KGF0bW9zcGhlcmVFbmRwb2ludCgpLCB7XG4gICAgICAgIGxvZ1N0cmVhbTogY29udGV4dC5vdXRwdXQsXG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgc3RhcnQgPSBEYXRlLm5vdygpO1xuICAgICAgY29uc3QgYWxsb2NhdGlvbiA9IGF3YWl0IGF0bW9zcGhlcmUuYWNxdWlyZSh7IHBvb2w6IGF0bW9zcGhlcmVQb29sKCksIHJlcXVlc3RlcjogY29udGV4dC5uYW1lLCB0aW1lb3V0U2Vjb25kczogNjAgKiAzMCB9KTtcbiAgICAgIGNvbnRleHQucmVwb3J0V2FpdFRpbWUoRGF0ZS5ub3coKSAtIHN0YXJ0KTtcblxuICAgICAgY29uc3QgYXdzID0gYXdhaXQgQXdzQ2xpZW50cy5mb3JJZGVudGl0eShhbGxvY2F0aW9uLmVudmlyb25tZW50LnJlZ2lvbiwge1xuICAgICAgICBhY2Nlc3NLZXlJZDogYWxsb2NhdGlvbi5jcmVkZW50aWFscy5hY2Nlc3NLZXlJZCxcbiAgICAgICAgc2VjcmV0QWNjZXNzS2V5OiBhbGxvY2F0aW9uLmNyZWRlbnRpYWxzLnNlY3JldEFjY2Vzc0tleSxcbiAgICAgICAgc2Vzc2lvblRva2VuOiBhbGxvY2F0aW9uLmNyZWRlbnRpYWxzLnNlc3Npb25Ub2tlbixcbiAgICAgICAgYWNjb3VudElkOiBhbGxvY2F0aW9uLmVudmlyb25tZW50LmFjY291bnQsXG4gICAgICB9LCBjb250ZXh0Lm91dHB1dCk7XG5cbiAgICAgIGF3YWl0IHNhbml0eUNoZWNrKGF3cyk7XG5cbiAgICAgIGxldCBvdXRjb21lID0gJ3N1Y2Nlc3MnO1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IGJsb2NrKHsgLi4uY29udGV4dCwgZGlzYWJsZUJvb3RzdHJhcCwgYXdzIH0pO1xuICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgIG91dGNvbWUgPSAnZmFpbHVyZSc7XG4gICAgICAgIHRocm93IGU7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCBhdG1vc3BoZXJlLnJlbGVhc2UoYWxsb2NhdGlvbi5pZCwgb3V0Y29tZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiByZWdpb25Qb29sKCkudXNpbmcoYXN5bmMgKHJlZ2lvbikgPT4ge1xuICAgICAgICBjb25zdCBhd3MgPSBhd2FpdCBBd3NDbGllbnRzLmZvclJlZ2lvbihyZWdpb24sIGNvbnRleHQub3V0cHV0KTtcbiAgICAgICAgYXdhaXQgc2FuaXR5Q2hlY2soYXdzKTtcblxuICAgICAgICByZXR1cm4gYmxvY2soeyAuLi5jb250ZXh0LCBkaXNhYmxlQm9vdHN0cmFwLCBhd3MgfSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH07XG59XG5cbmxldCBfcmVnaW9uUG9vbDogdW5kZWZpbmVkIHwgUmVzb3VyY2VQb29sO1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lvblBvb2woKTogUmVzb3VyY2VQb29sIHtcbiAgaWYgKF9yZWdpb25Qb29sICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gX3JlZ2lvblBvb2w7XG4gIH1cblxuICBjb25zdCBSRUdJT05TID0gcHJvY2Vzcy5lbnYuQVdTX1JFR0lPTlNcbiAgICA/IHByb2Nlc3MuZW52LkFXU19SRUdJT05TLnNwbGl0KCcsJylcbiAgICA6IFtwcm9jZXNzLmVudi5BV1NfUkVHSU9OID8/IHByb2Nlc3MuZW52LkFXU19ERUZBVUxUX1JFR0lPTiA/PyAndXMtZWFzdC0xJ107XG5cbiAgX3JlZ2lvblBvb2wgPSBSZXNvdXJjZVBvb2wud2l0aFJlc291cmNlcygnYXdzX3JlZ2lvbnMnLCBSRUdJT05TKTtcbiAgcmV0dXJuIF9yZWdpb25Qb29sO1xufVxuXG4vKipcbiAqIFBlcmZvcm0gYSBvbmUtdGltZSBxdWljayBzYW5pdHkgY2hlY2sgdGhhdCB0aGUgQVdTIGNsaWVudHMgaGF2ZSBwcm9wZXJseSBjb25maWd1cmVkIGNyZWRlbnRpYWxzXG4gKlxuICogSWYgd2UgZG9uJ3QgZG8gdGhpcywgY2FsbHMgYXJlIGdvaW5nIHRvIGZhaWwgYW5kIHRoZXknbGwgYmUgcmV0cmllZCBhbmQgZXZlcnl0aGluZyB3aWxsIHRha2VcbiAqIGZvcmV2ZXIgYmVmb3JlIHRoZSB1c2VyIG5vdGljZXMgYSBzaW1wbGUgbWlzY29uZmlndXJhdGlvbi5cbiAqXG4gKiBXZSBjYW4ndCBjaGVjayBmb3IgdGhlIHByZXNlbmNlIG9mIGVudmlyb25tZW50IHZhcmlhYmxlcyBzaW5jZSBjcmVkZW50aWFscyBjb3VsZCBjb21lIGZyb21cbiAqIGFueXdoZXJlLCBzbyBkbyBzaW1wbGUgYWNjb3VudCByZXRyaWV2YWwuXG4gKlxuICogT25seSBkbyBpdCBvbmNlIHBlciBwcm9jZXNzLlxuICovXG5hc3luYyBmdW5jdGlvbiBzYW5pdHlDaGVjayhhd3M6IEF3c0NsaWVudHMpIHtcbiAgaWYgKHNhbml0eUNoZWNrZWQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBhd3MuYWNjb3VudCgpO1xuICAgICAgc2FuaXR5Q2hlY2tlZCA9IHRydWU7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICBzYW5pdHlDaGVja2VkID0gZmFsc2U7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEFXUyBjcmVkZW50aWFscyBwcm9iYWJseSBub3QgY29uZmlndXJlZCwgZ290IGVycm9yOiAke2UubWVzc2FnZX1gKTtcbiAgICB9XG4gIH1cbiAgaWYgKCFzYW5pdHlDaGVja2VkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBV1MgY3JlZGVudGlhbHMgcHJvYmFibHkgbm90IGNvbmZpZ3VyZWQsIHNlZSBwcmV2aW91cyBlcnJvcicpO1xuICB9XG59XG5sZXQgc2FuaXR5Q2hlY2tlZDogYm9vbGVhbiB8IHVuZGVmaW5lZDtcbiJdfQ==