UNPKG

@aws-cdk-testing/cli-integ

Version:

Integration tests for the AWS CDK CLI

119 lines 14.3 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 }); let outcome = 'success'; context.reportWaitTime(Date.now() - start); try { const aws = await aws_1.AwsClients.forIdentity(context.randomString, allocation.environment.region, { accessKeyId: allocation.credentials.accessKeyId, secretAccessKey: allocation.credentials.secretAccessKey, sessionToken: allocation.credentials.sessionToken, accountId: allocation.environment.account, }, context.output); await sanityCheck(aws); try { return await block({ ...context, disableBootstrap, aws }); } catch (e) { outcome = 'failure'; throw e; } finally { await aws.dispose(); } } finally { await atmosphere.release(allocation.id, outcome); } } else { return regionPool().using(async (region) => { const aws = await aws_1.AwsClients.forRegion(context.randomString, region, context.output); try { await sanityCheck(aws); return await block({ ...context, disableBootstrap, aws }); } finally { await aws.dispose(); } }); } }; } 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2l0aC1hd3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ3aXRoLWF3cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQU1BLDhDQUdDO0FBRUQsZ0RBTUM7QUFFRCx3Q0FNQztBQVNELDBCQWdEQztBQUdELGdDQVdDO0FBaEdELDBFQUFrRTtBQUNsRSwrQkFBbUM7QUFFbkMsbURBQStDO0FBRy9DLFNBQWdCLGlCQUFpQjtJQUMvQixNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLDRCQUE0QixDQUFDO0lBQ3pELE9BQU8sT0FBTyxLQUFLLE1BQU0sSUFBSSxPQUFPLEtBQUssR0FBRyxDQUFDO0FBQy9DLENBQUM7QUFFRCxTQUFnQixrQkFBa0I7SUFDaEMsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyw2QkFBNkIsQ0FBQztJQUN4RCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDWCxNQUFNLElBQUksS0FBSyxDQUFDLDhDQUE4QyxDQUFDLENBQUM7SUFDbEUsQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQztBQUVELFNBQWdCLGNBQWM7SUFDNUIsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyx5QkFBeUIsQ0FBQztJQUNwRCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDWCxNQUFNLElBQUksS0FBSyxDQUFDLDBDQUEwQyxDQUFDLENBQUM7SUFDOUQsQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQztBQUlEOzs7O0dBSUc7QUFDSCxTQUFnQixPQUFPLENBQ3JCLEtBQTJFLEVBQzNFLG1CQUE0QixLQUFLO0lBRWpDLE9BQU8sS0FBSyxFQUFFLE9BQVUsRUFBRSxFQUFFO1FBQzFCLElBQUksaUJBQWlCLEVBQUUsRUFBRSxDQUFDO1lBQ3hCLE1BQU0sVUFBVSxHQUFHLElBQUksd0NBQWdCLENBQUMsa0JBQWtCLEVBQUUsRUFBRTtnQkFDNUQsU0FBUyxFQUFFLE9B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Q0FBQyxhQUFhLENBQUMsYUFBYSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ2pFLE9BQU8sV0FBVyxDQUFDO0FBQ3JCLENBQUM7QUFFRDs7Ozs7Ozs7OztHQVVHO0FBQ0gsS0FBSyxVQUFVLFdBQVcsQ0FBQyxHQUFlO0lBQ3hDLElBQUksYUFBYSxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQ2hDLElBQUksQ0FBQztZQUNILE1BQU0sR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3BCLGFBQWEsR0FBRyxJQUFJLENBQUM7UUFDdkIsQ0FBQztRQUFDLE9BQU8sQ0FBTSxFQUFFLENBQUM7WUFDaEIsYUFBYSxHQUFHLEtBQUssQ0FBQztZQUN0QixNQUFNLElBQUksS0FBSyxDQUFDLHVEQUF1RCxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUN0RixDQUFDO0lBQ0gsQ0FBQztJQUNELElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNuQixNQUFNLElBQUksS0FBSyxDQUFDLDZEQUE2RCxDQUFDLENBQUM7SUFDakYsQ0FBQztBQUNILENBQUM7QUFDRCxJQUFJLGFBQWtDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBdG1vc3BoZXJlQ2xpZW50IH0gZnJvbSAnQGNka2xhYnMvY2RrLWF0bW9zcGhlcmUtY2xpZW50JztcbmltcG9ydCB7IEF3c0NsaWVudHMgfSBmcm9tICcuL2F3cyc7XG5pbXBvcnQgdHlwZSB7IFRlc3RDb250ZXh0IH0gZnJvbSAnLi9pbnRlZy10ZXN0JztcbmltcG9ydCB7IFJlc291cmNlUG9vbCB9IGZyb20gJy4vcmVzb3VyY2UtcG9vbCc7XG5pbXBvcnQgdHlwZSB7IERpc2FibGVCb290c3RyYXBDb250ZXh0IH0gZnJvbSAnLi93aXRoLWNkay1hcHAnO1xuXG5leHBvcnQgZnVuY3Rpb24gYXRtb3NwaGVyZUVuYWJsZWQoKTogYm9vbGVhbiB7XG4gIGNvbnN0IGVuYWJsZWQgPSBwcm9jZXNzLmVudi5DREtfSU5URUdfQVRNT1NQSEVSRV9FTkFCTEVEO1xuICByZXR1cm4gZW5hYmxlZCA9PT0gJ3RydWUnIHx8IGVuYWJsZWQgPT09ICcxJztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGF0bW9zcGhlcmVFbmRwb2ludCgpOiBzdHJpbmcge1xuICBjb25zdCB2YWx1ZSA9IHByb2Nlc3MuZW52LkNES19JTlRFR19BVE1PU1BIRVJFX0VORFBPSU5UO1xuICBpZiAoIXZhbHVlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDREtfSU5URUdfQVRNT1NQSEVSRV9FTkRQT0lOVCBpcyBub3QgZGVmaW5lZCcpO1xuICB9XG4gIHJldHVybiB2YWx1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGF0bW9zcGhlcmVQb29sKCkge1xuICBjb25zdCB2YWx1ZSA9IHByb2Nlc3MuZW52LkNES19JTlRFR19BVE1PU1BIRVJFX1BPT0w7XG4gIGlmICghdmFsdWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NES19JTlRFR19BVE1PU1BIRVJFX1BPT0wgaXMgbm90IGRlZmluZWQnKTtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59XG5cbmV4cG9ydCB0eXBlIEF3c0NvbnRleHQgPSB7IHJlYWRvbmx5IGF3czogQXdzQ2xpZW50cyB9O1xuXG4vKipcbiAqIEhpZ2hlciBvcmRlciBmdW5jdGlvbiB0byBleGVjdXRlIGEgYmxvY2sgd2l0aCBhbiBBV1MgY2xpZW50IHNldHVwXG4gKlxuICogQWxsb2NhdGUgdGhlIG5leHQgcmVnaW9uIGZyb20gdGhlIFJFR0lPTiBwb29sIGFuZCBkaXNwb3NlIGl0IGFmdGVyd2FyZHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3aXRoQXdzPEEgZXh0ZW5kcyBUZXN0Q29udGV4dD4oXG4gIGJsb2NrOiAoY29udGV4dDogQSAmIEF3c0NvbnRleHQgJiBEaXNhYmxlQm9vdHN0cmFwQ29udGV4dCkgPT4gUHJvbWlzZTx2b2lkPixcbiAgZGlzYWJsZUJvb3RzdHJhcDogYm9vbGVhbiA9IGZhbHNlLFxuKTogKGNvbnRleHQ6IEEpID0+IFByb21pc2U8dm9pZD4ge1xuICByZXR1cm4gYXN5bmMgKGNvbnRleHQ6IEEpID0+IHtcbiAgICBpZiAoYXRtb3NwaGVyZUVuYWJsZWQoKSkge1xuICAgICAgY29uc3QgYXRtb3NwaGVyZSA9IG5ldyBBdG1vc3BoZXJlQ2xpZW50KGF0bW9zcGhlcmVFbmRwb2ludCgpLCB7XG4gICAgICAgIGxvZ1N0cmVhbTogY29udGV4dC5vdXRwdXQsXG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgc3RhcnQgPSBEYXRlLm5vdygpO1xuICAgICAgY29uc3QgYWxsb2NhdGlvbiA9IGF3YWl0IGF0bW9zcGhlcmUuYWNxdWlyZSh7IHBvb2w6IGF0bW9zcGhlcmVQb29sKCksIHJlcXVlc3RlcjogY29udGV4dC5uYW1lLCB0aW1lb3V0U2Vjb25kczogNjAgKiAzMCB9KTtcbiAgICAgIGxldCBvdXRjb21lID0gJ3N1Y2Nlc3MnO1xuICAgICAgY29udGV4dC5yZXBvcnRXYWl0VGltZShEYXRlLm5vdygpIC0gc3RhcnQpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBhd3MgPSBhd2FpdCBBd3NDbGllbnRzLmZvcklkZW50aXR5KGNvbnRleHQucmFuZG9tU3RyaW5nLCBhbGxvY2F0aW9uLmVudmlyb25tZW50LnJlZ2lvbiwge1xuICAgICAgICAgIGFjY2Vzc0tleUlkOiBhbGxvY2F0aW9uLmNyZWRlbnRpYWxzLmFjY2Vzc0tleUlkLFxuICAgICAgICAgIHNlY3JldEFjY2Vzc0tleTogYWxsb2NhdGlvbi5jcmVkZW50aWFscy5zZWNyZXRBY2Nlc3NLZXksXG4gICAgICAgICAgc2Vzc2lvblRva2VuOiBhbGxvY2F0aW9uLmNyZWRlbnRpYWxzLnNlc3Npb25Ub2tlbixcbiAgICAgICAgICBhY2NvdW50SWQ6IGFsbG9jYXRpb24uZW52aXJvbm1lbnQuYWNjb3VudCxcbiAgICAgICAgfSwgY29udGV4dC5vdXRwdXQpO1xuICAgICAgICBhd2FpdCBzYW5pdHlDaGVjayhhd3MpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IGJsb2NrKHsgLi4uY29udGV4dCwgZGlzYWJsZUJvb3RzdHJhcCwgYXdzIH0pO1xuICAgICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgICBvdXRjb21lID0gJ2ZhaWx1cmUnO1xuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgYXdhaXQgYXdzLmRpc3Bvc2UoKTtcbiAgICAgICAgfVxuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgYXdhaXQgYXRtb3NwaGVyZS5yZWxlYXNlKGFsbG9jYXRpb24uaWQsIG91dGNvbWUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gcmVnaW9uUG9vbCgpLnVzaW5nKGFzeW5jIChyZWdpb24pID0+IHtcbiAgICAgICAgY29uc3QgYXdzID0gYXdhaXQgQXdzQ2xpZW50cy5mb3JSZWdpb24oY29udGV4dC5yYW5kb21TdHJpbmcsIHJlZ2lvbiwgY29udGV4dC5vdXRwdXQpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IHNhbml0eUNoZWNrKGF3cyk7XG5cbiAgICAgICAgICByZXR1cm4gYXdhaXQgYmxvY2soeyAuLi5jb250ZXh0LCBkaXNhYmxlQm9vdHN0cmFwLCBhd3MgfSk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgYXdhaXQgYXdzLmRpc3Bvc2UoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9O1xufVxuXG5sZXQgX3JlZ2lvblBvb2w6IHVuZGVmaW5lZCB8IFJlc291cmNlUG9vbDtcbmV4cG9ydCBmdW5jdGlvbiByZWdpb25Qb29sKCk6IFJlc291cmNlUG9vbCB7XG4gIGlmIChfcmVnaW9uUG9vbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIF9yZWdpb25Qb29sO1xuICB9XG5cbiAgY29uc3QgUkVHSU9OUyA9IHByb2Nlc3MuZW52LkFXU19SRUdJT05TXG4gICAgPyBwcm9jZXNzLmVudi5BV1NfUkVHSU9OUy5zcGxpdCgnLCcpXG4gICAgOiBbcHJvY2Vzcy5lbnYuQVdTX1JFR0lPTiA/PyBwcm9jZXNzLmVudi5BV1NfREVGQVVMVF9SRUdJT04gPz8gJ3VzLWVhc3QtMSddO1xuXG4gIF9yZWdpb25Qb29sID0gUmVzb3VyY2VQb29sLndpdGhSZXNvdXJjZXMoJ2F3c19yZWdpb25zJywgUkVHSU9OUyk7XG4gIHJldHVybiBfcmVnaW9uUG9vbDtcbn1cblxuLyoqXG4gKiBQZXJmb3JtIGEgb25lLXRpbWUgcXVpY2sgc2FuaXR5IGNoZWNrIHRoYXQgdGhlIEFXUyBjbGllbnRzIGhhdmUgcHJvcGVybHkgY29uZmlndXJlZCBjcmVkZW50aWFsc1xuICpcbiAqIElmIHdlIGRvbid0IGRvIHRoaXMsIGNhbGxzIGFyZSBnb2luZyB0byBmYWlsIGFuZCB0aGV5J2xsIGJlIHJldHJpZWQgYW5kIGV2ZXJ5dGhpbmcgd2lsbCB0YWtlXG4gKiBmb3JldmVyIGJlZm9yZSB0aGUgdXNlciBub3RpY2VzIGEgc2ltcGxlIG1pc2NvbmZpZ3VyYXRpb24uXG4gKlxuICogV2UgY2FuJ3QgY2hlY2sgZm9yIHRoZSBwcmVzZW5jZSBvZiBlbnZpcm9ubWVudCB2YXJpYWJsZXMgc2luY2UgY3JlZGVudGlhbHMgY291bGQgY29tZSBmcm9tXG4gKiBhbnl3aGVyZSwgc28gZG8gc2ltcGxlIGFjY291bnQgcmV0cmlldmFsLlxuICpcbiAqIE9ubHkgZG8gaXQgb25jZSBwZXIgcHJvY2Vzcy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gc2FuaXR5Q2hlY2soYXdzOiBBd3NDbGllbnRzKSB7XG4gIGlmIChzYW5pdHlDaGVja2VkID09PSB1bmRlZmluZWQpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgYXdzLmFjY291bnQoKTtcbiAgICAgIHNhbml0eUNoZWNrZWQgPSB0cnVlO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgc2FuaXR5Q2hlY2tlZCA9IGZhbHNlO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBBV1MgY3JlZGVudGlhbHMgcHJvYmFibHkgbm90IGNvbmZpZ3VyZWQsIGdvdCBlcnJvcjogJHtlLm1lc3NhZ2V9YCk7XG4gICAgfVxuICB9XG4gIGlmICghc2FuaXR5Q2hlY2tlZCkge1xuICAgIHRocm93IG5ldyBFcnJvcignQVdTIGNyZWRlbnRpYWxzIHByb2JhYmx5IG5vdCBjb25maWd1cmVkLCBzZWUgcHJldmlvdXMgZXJyb3InKTtcbiAgfVxufVxubGV0IHNhbml0eUNoZWNrZWQ6IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG4iXX0=