aws-cdk
Version:
AWS CDK CLI, the command line tool for CDK apps
263 lines • 33 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.AwsCliCompatible = void 0;
const credential_providers_1 = require("@aws-sdk/credential-providers");
const ec2_metadata_service_1 = require("@aws-sdk/ec2-metadata-service");
const shared_ini_file_loader_1 = require("@smithy/shared-ini-file-loader");
const promptly = require("promptly");
const proxy_agent_1 = require("proxy-agent");
const provider_caching_1 = require("./provider-caching");
const util_1 = require("./util");
const api_1 = require("../../../../@aws-cdk/tmp-toolkit-helpers/src/api");
const logging_1 = require("../../logging");
const DEFAULT_CONNECTION_TIMEOUT = 10000;
const DEFAULT_TIMEOUT = 300000;
/**
* Behaviors to match AWS CLI
*
* See these links:
*
* https://docs.aws.amazon.com/cli/latest/topic/config-vars.html
* https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html
*/
class AwsCliCompatible {
/**
* Build an AWS CLI-compatible credential chain provider
*
* The credential chain returned by this function is always caching.
*/
static async credentialChainBuilder(options = {}) {
const clientConfig = {
requestHandler: AwsCliCompatible.requestHandlerBuilder(options.httpOptions),
customUserAgent: 'aws-cdk',
logger: options.logger,
};
// Super hacky solution to https://github.com/aws/aws-cdk/issues/32510, proposed by the SDK team.
//
// Summary of the problem: we were reading the region from the config file and passing it to
// the credential providers. However, in the case of SSO, this makes the credential provider
// use that region to do the SSO flow, which is incorrect. The region that should be used for
// that is the one set in the sso_session section of the config file.
//
// The idea here: the "clientConfig" is for configuring the inner auth client directly,
// and has the highest priority, whereas "parentClientConfig" is the upper data client
// and has lower priority than the sso_region but still higher priority than STS global region.
const parentClientConfig = {
region: await this.region(options.profile),
};
/**
* The previous implementation matched AWS CLI behavior:
*
* If a profile is explicitly set using `--profile`,
* we use that to the exclusion of everything else.
*
* Note: this does not apply to AWS_PROFILE,
* environment credentials still take precedence over AWS_PROFILE
*/
if (options.profile) {
return (0, provider_caching_1.makeCachingProvider)((0, credential_providers_1.fromIni)({
profile: options.profile,
ignoreCache: true,
mfaCodeProvider: tokenCodeFn,
clientConfig,
parentClientConfig,
logger: options.logger,
}));
}
const envProfile = process.env.AWS_PROFILE || process.env.AWS_DEFAULT_PROFILE;
/**
* Env AWS - EnvironmentCredentials with string AWS
* Env Amazon - EnvironmentCredentials with string AMAZON
* Profile Credentials - PatchedSharedIniFileCredentials with implicit profile, credentials file, http options, and token fn
* SSO with implicit profile only
* SharedIniFileCredentials with implicit profile and preferStaticCredentials true (profile with source_profile)
* Shared Credential file that points to Environment Credentials with AWS prefix
* Shared Credential file that points to EC2 Metadata
* Shared Credential file that points to ECS Credentials
* SSO Credentials - SsoCredentials with implicit profile and http options
* ProcessCredentials with implicit profile
* ECS Credentials - ECSCredentials with no input OR Web Identity - TokenFileWebIdentityCredentials with no input OR EC2 Metadata - EC2MetadataCredentials with no input
*
* These translate to:
* fromEnv()
* fromSSO()/fromIni()
* fromProcess()
* fromContainerMetadata()
* fromTokenFile()
* fromInstanceMetadata()
*
* The NodeProviderChain is already cached.
*/
const nodeProviderChain = (0, credential_providers_1.fromNodeProviderChain)({
profile: envProfile,
clientConfig,
parentClientConfig,
logger: options.logger,
mfaCodeProvider: tokenCodeFn,
ignoreCache: true,
});
return shouldPrioritizeEnv()
? (0, credential_providers_1.createCredentialChain)((0, credential_providers_1.fromEnv)(), nodeProviderChain).expireAfter(60 * 60000)
: nodeProviderChain;
}
static requestHandlerBuilder(options = {}) {
const agent = this.proxyAgent(options);
return {
connectionTimeout: DEFAULT_CONNECTION_TIMEOUT,
requestTimeout: DEFAULT_TIMEOUT,
httpsAgent: agent,
httpAgent: agent,
};
}
static proxyAgent(options) {
// Force it to use the proxy provided through the command line.
// Otherwise, let the ProxyAgent auto-detect the proxy using environment variables.
const getProxyForUrl = options.proxyAddress != null
? () => Promise.resolve(options.proxyAddress)
: undefined;
return new proxy_agent_1.ProxyAgent({
ca: tryGetCACert(options.caBundlePath),
getProxyForUrl,
});
}
/**
* Attempts to get the region from a number of sources and falls back to us-east-1 if no region can be found,
* as is done in the AWS CLI.
*
* The order of priority is the following:
*
* 1. Environment variables specifying region, with both an AWS prefix and AMAZON prefix
* to maintain backwards compatibility, and without `DEFAULT` in the name because
* Lambda and CodeBuild set the $AWS_REGION variable.
* 2. Regions listed in the Shared Ini Files - First checking for the profile provided
* and then checking for the default profile.
* 3. IMDS instance identity region from the Metadata Service.
* 4. us-east-1
*/
static async region(maybeProfile) {
const defaultRegion = 'us-east-1';
const profile = maybeProfile || process.env.AWS_PROFILE || process.env.AWS_DEFAULT_PROFILE || 'default';
const region = process.env.AWS_REGION ||
process.env.AMAZON_REGION ||
process.env.AWS_DEFAULT_REGION ||
process.env.AMAZON_DEFAULT_REGION ||
(await getRegionFromIni(profile)) ||
(await regionFromMetadataService());
if (!region) {
const usedProfile = !profile ? '' : ` (profile: "${profile}")`;
(0, logging_1.debug)(`Unable to determine AWS region from environment or AWS configuration${usedProfile}, defaulting to '${defaultRegion}'`);
return defaultRegion;
}
return region;
}
}
exports.AwsCliCompatible = AwsCliCompatible;
/**
* Looks up the region of the provided profile. If no region is present,
* it will attempt to lookup the default region.
* @param profile The profile to use to lookup the region
* @returns The region for the profile or default profile, if present. Otherwise returns undefined.
*/
async function getRegionFromIni(profile) {
const sharedFiles = await (0, shared_ini_file_loader_1.loadSharedConfigFiles)({ ignoreCache: true });
// Priority:
//
// credentials come before config because aws-cli v1 behaves like that.
//
// 1. profile-region-in-credentials
// 2. profile-region-in-config
// 3. default-region-in-credentials
// 4. default-region-in-config
return getRegionFromIniFile(profile, sharedFiles.credentialsFile)
?? getRegionFromIniFile(profile, sharedFiles.configFile)
?? getRegionFromIniFile('default', sharedFiles.credentialsFile)
?? getRegionFromIniFile('default', sharedFiles.configFile);
}
function getRegionFromIniFile(profile, data) {
return data?.[profile]?.region;
}
function tryGetCACert(bundlePath) {
const path = bundlePath || caBundlePathFromEnvironment();
if (path) {
(0, logging_1.debug)('Using CA bundle path: %s', path);
return (0, util_1.readIfPossible)(path);
}
return undefined;
}
/**
* Find and return a CA certificate bundle path to be passed into the SDK.
*/
function caBundlePathFromEnvironment() {
if (process.env.aws_ca_bundle) {
return process.env.aws_ca_bundle;
}
if (process.env.AWS_CA_BUNDLE) {
return process.env.AWS_CA_BUNDLE;
}
return undefined;
}
/**
* We used to support both AWS and AMAZON prefixes for these environment variables.
*
* Adding this for backward compatibility.
*/
function shouldPrioritizeEnv() {
const id = process.env.AWS_ACCESS_KEY_ID || process.env.AMAZON_ACCESS_KEY_ID;
const key = process.env.AWS_SECRET_ACCESS_KEY || process.env.AMAZON_SECRET_ACCESS_KEY;
if (!!id && !!key) {
process.env.AWS_ACCESS_KEY_ID = id;
process.env.AWS_SECRET_ACCESS_KEY = key;
const sessionToken = process.env.AWS_SESSION_TOKEN ?? process.env.AMAZON_SESSION_TOKEN;
if (sessionToken) {
process.env.AWS_SESSION_TOKEN = sessionToken;
}
return true;
}
return false;
}
/**
* The MetadataService class will attempt to fetch the instance identity document from
* IMDSv2 first, and then will attempt v1 as a fallback.
*
* If this fails, we will use us-east-1 as the region so no error should be thrown.
* @returns The region for the instance identity
*/
async function regionFromMetadataService() {
(0, logging_1.debug)('Looking up AWS region in the EC2 Instance Metadata Service (IMDS).');
try {
const metadataService = new ec2_metadata_service_1.MetadataService({
httpOptions: {
timeout: 1000,
},
});
await metadataService.fetchMetadataToken();
const document = await metadataService.request('/latest/dynamic/instance-identity/document', {});
return JSON.parse(document).region;
}
catch (e) {
(0, logging_1.debug)(`Unable to retrieve AWS region from IMDS: ${e}`);
}
}
/**
* Ask user for MFA token for given serial
*
* Result is send to callback function for SDK to authorize the request
*/
async function tokenCodeFn(serialArn) {
(0, logging_1.debug)('Require MFA token for serial ARN', serialArn);
try {
const token = await promptly.prompt(`MFA token for ${serialArn}: `, {
trim: true,
default: '',
});
(0, logging_1.debug)('Successfully got MFA token from user');
return token;
}
catch (err) {
(0, logging_1.debug)('Failed to get MFA token', err);
const e = new api_1.AuthenticationError(`Error fetching MFA token: ${err.message ?? err}`);
e.name = 'SharedIniFileCredentialsProviderFailure';
throw e;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXdzY2xpLWNvbXBhdGlibGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJhd3NjbGktY29tcGF0aWJsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSx3RUFBK0c7QUFDL0csd0VBQWdFO0FBRWhFLDJFQUF1RTtBQUV2RSxxQ0FBcUM7QUFDckMsNkNBQXlDO0FBQ3pDLHlEQUF5RDtBQUV6RCxpQ0FBd0M7QUFDeEMsMEVBQXVGO0FBQ3ZGLDJDQUFzQztBQUV0QyxNQUFNLDBCQUEwQixHQUFHLEtBQUssQ0FBQztBQUN6QyxNQUFNLGVBQWUsR0FBRyxNQUFNLENBQUM7QUFFL0I7Ozs7Ozs7R0FPRztBQUNILE1BQWEsZ0JBQWdCO0lBQzNCOzs7O09BSUc7SUFDSSxNQUFNLENBQUMsS0FBSyxDQUFDLHNCQUFzQixDQUN4QyxVQUFrQyxFQUFFO1FBRXBDLE1BQU0sWUFBWSxHQUFHO1lBQ25CLGNBQWMsRUFBRSxnQkFBZ0IsQ0FBQyxxQkFBcUIsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDO1lBQzNFLGVBQWUsRUFBRSxTQUFTO1lBQzFCLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTTtTQUN2QixDQUFDO1FBRUYsaUdBQWlHO1FBQ2pHLEVBQUU7UUFDRiw0RkFBNEY7UUFDNUYsNEZBQTRGO1FBQzVGLDZGQUE2RjtRQUM3RixxRUFBcUU7UUFDckUsRUFBRTtRQUNGLHVGQUF1RjtRQUN2RixzRkFBc0Y7UUFDdEYsK0ZBQStGO1FBQy9GLE1BQU0sa0JBQWtCLEdBQUc7WUFDekIsTUFBTSxFQUFFLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDO1NBQzNDLENBQUM7UUFDRjs7Ozs7Ozs7V0FRRztRQUNILElBQUksT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3BCLE9BQU8sSUFBQSxzQ0FBbUIsRUFBQyxJQUFBLDhCQUFPLEVBQUM7Z0JBQ2pDLE9BQU8sRUFBRSxPQUFPLENBQUMsT0FBTztnQkFDeEIsV0FBVyxF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USxHQUFHLE1BQU0sZUFBZSxDQUFDLE9BQU8sQ0FBQyw0Q0FBNEMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNqRyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDO0lBQ3JDLENBQUM7SUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQ1gsSUFBQSxlQUFLLEVBQUMsNENBQTRDLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDekQsQ0FBQztBQUNILENBQUM7QUFRRDs7OztHQUlHO0FBQ0gsS0FBSyxVQUFVLFdBQVcsQ0FBQyxTQUFpQjtJQUMxQyxJQUFBLGVBQUssRUFBQyxrQ0FBa0MsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUNyRCxJQUFJLENBQUM7UUFDSCxNQUFNLEtBQUssR0FBVyxNQUFNLFFBQVEsQ0FBQyxNQUFNLENBQUMsaUJBQWlCLFNBQVMsSUFBSSxFQUFFO1lBQzFFLElBQUksRUFBRSxJQUFJO1lBQ1YsT0FBTyxFQUFFLEVBQUU7U0FDWixDQUFDLENBQUM7UUFDSCxJQUFBLGVBQUssRUFBQyxzQ0FBc0MsQ0FBQyxDQUFDO1FBQzlDLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUFDLE9BQU8sR0FBUSxFQUFFLENBQUM7UUFDbEIsSUFBQSxlQUFLLEVBQUMseUJBQXlCLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDdEMsTUFBTSxDQUFDLEdBQUcsSUFBSSx5QkFBbUIsQ0FBQyw2QkFBNkIsR0FBRyxDQUFDLE9BQU8sSUFBSSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQ3JGLENBQUMsQ0FBQyxJQUFJLEdBQUcseUNBQXlDLENBQUM7UUFDbkQsTUFBTSxDQUFDLENBQUM7SUFDVixDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNyZWF0ZUNyZWRlbnRpYWxDaGFpbiwgZnJvbUVudiwgZnJvbUluaSwgZnJvbU5vZGVQcm92aWRlckNoYWluIH0gZnJvbSAnQGF3cy1zZGsvY3JlZGVudGlhbC1wcm92aWRlcnMnO1xuaW1wb3J0IHsgTWV0YWRhdGFTZXJ2aWNlIH0gZnJvbSAnQGF3cy1zZGsvZWMyLW1ldGFkYXRhLXNlcnZpY2UnO1xuaW1wb3J0IHR5cGUgeyBOb2RlSHR0cEhhbmRsZXJPcHRpb25zIH0gZnJvbSAnQHNtaXRoeS9ub2RlLWh0dHAtaGFuZGxlcic7XG5pbXBvcnQgeyBsb2FkU2hhcmVkQ29uZmlnRmlsZXMgfSBmcm9tICdAc21pdGh5L3NoYXJlZC1pbmktZmlsZS1sb2FkZXInO1xuaW1wb3J0IHR5cGUgeyBBd3NDcmVkZW50aWFsSWRlbnRpdHlQcm92aWRlciwgTG9nZ2VyIH0gZnJvbSAnQHNtaXRoeS90eXBlcyc7XG5pbXBvcnQgKiBhcyBwcm9tcHRseSBmcm9tICdwcm9tcHRseSc7XG5pbXBvcnQgeyBQcm94eUFnZW50IH0gZnJvbSAncHJveHktYWdlbnQnO1xuaW1wb3J0IHsgbWFrZUNhY2hpbmdQcm92aWRlciB9IGZyb20gJy4vcHJvdmlkZXItY2FjaGluZyc7XG5pbXBvcnQgdHlwZSB7IFNka0h0dHBPcHRpb25zIH0gZnJvbSAnLi9zZGstcHJvdmlkZXInO1xuaW1wb3J0IHsgcmVhZElmUG9zc2libGUgfSBmcm9tICcuL3V0aWwnO1xuaW1wb3J0IHsgQXV0aGVudGljYXRpb25FcnJvciB9IGZyb20gJy4uLy4uLy4uLy4uL0Bhd3MtY2RrL3RtcC10b29sa2l0LWhlbHBlcnMvc3JjL2FwaSc7XG5pbXBvcnQgeyBkZWJ1ZyB9IGZyb20gJy4uLy4uL2xvZ2dpbmcnO1xuXG5jb25zdCBERUZBVUxUX0NPTk5FQ1RJT05fVElNRU9VVCA9IDEwMDAwO1xuY29uc3QgREVGQVVMVF9USU1FT1VUID0gMzAwMDAwO1xuXG4vKipcbiAqIEJlaGF2aW9ycyB0byBtYXRjaCBBV1MgQ0xJXG4gKlxuICogU2VlIHRoZXNlIGxpbmtzOlxuICpcbiAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbGkvbGF0ZXN0L3RvcGljL2NvbmZpZy12YXJzLmh0bWxcbiAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jbGkvbGF0ZXN0L3VzZXJndWlkZS9jbGktY29uZmlndXJlLWVudnZhcnMuaHRtbFxuICovXG5leHBvcnQgY2xhc3MgQXdzQ2xpQ29tcGF0aWJsZSB7XG4gIC8qKlxuICAgKiBCdWlsZCBhbiBBV1MgQ0xJLWNvbXBhdGlibGUgY3JlZGVudGlhbCBjaGFpbiBwcm92aWRlclxuICAgKlxuICAgKiBUaGUgY3JlZGVudGlhbCBjaGFpbiByZXR1cm5lZCBieSB0aGlzIGZ1bmN0aW9uIGlzIGFsd2F5cyBjYWNoaW5nLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBhc3luYyBjcmVkZW50aWFsQ2hhaW5CdWlsZGVyKFxuICAgIG9wdGlvbnM6IENyZWRlbnRpYWxDaGFpbk9wdGlvbnMgPSB7fSxcbiAgKTogUHJvbWlzZTxBd3NDcmVkZW50aWFsSWRlbnRpdHlQcm92aWRlcj4ge1xuICAgIGNvbnN0IGNsaWVudENvbmZpZyA9IHtcbiAgICAgIHJlcXVlc3RIYW5kbGVyOiBBd3NDbGlDb21wYXRpYmxlLnJlcXVlc3RIYW5kbGVyQnVpbGRlcihvcHRpb25zLmh0dHBPcHRpb25zKSxcbiAgICAgIGN1c3RvbVVzZXJBZ2VudDogJ2F3cy1jZGsnLFxuICAgICAgbG9nZ2VyOiBvcHRpb25zLmxvZ2dlcixcbiAgICB9O1xuXG4gICAgLy8gU3VwZXIgaGFja3kgc29sdXRpb24gdG8gaHR0cHM6Ly9naXRodWIuY29tL2F3cy9hd3MtY2RrL2lzc3Vlcy8zMjUxMCwgcHJvcG9zZWQgYnkgdGhlIFNESyB0ZWFtLlxuICAgIC8vXG4gICAgLy8gU3VtbWFyeSBvZiB0aGUgcHJvYmxlbTogd2Ugd2VyZSByZWFkaW5nIHRoZSByZWdpb24gZnJvbSB0aGUgY29uZmlnIGZpbGUgYW5kIHBhc3NpbmcgaXQgdG9cbiAgICAvLyB0aGUgY3JlZGVudGlhbCBwcm92aWRlcnMuIEhvd2V2ZXIsIGluIHRoZSBjYXNlIG9mIFNTTywgdGhpcyBtYWtlcyB0aGUgY3JlZGVudGlhbCBwcm92aWRlclxuICAgIC8vIHVzZSB0aGF0IHJlZ2lvbiB0byBkbyB0aGUgU1NPIGZsb3csIHdoaWNoIGlzIGluY29ycmVjdC4gVGhlIHJlZ2lvbiB0aGF0IHNob3VsZCBiZSB1c2VkIGZvclxuICAgIC8vIHRoYXQgaXMgdGhlIG9uZSBzZXQgaW4gdGhlIHNzb19zZXNzaW9uIHNlY3Rpb24gb2YgdGhlIGNvbmZpZyBmaWxlLlxuICAgIC8vXG4gICAgLy8gVGhlIGlkZWEgaGVyZTogdGhlIFwiY2xpZW50Q29uZmlnXCIgaXMgZm9yIGNvbmZpZ3VyaW5nIHRoZSBpbm5lciBhdXRoIGNsaWVudCBkaXJlY3RseSxcbiAgICAvLyBhbmQgaGFzIHRoZSBoaWdoZXN0IHByaW9yaXR5LCB3aGVyZWFzIFwicGFyZW50Q2xpZW50Q29uZmlnXCIgaXMgdGhlIHVwcGVyIGRhdGEgY2xpZW50XG4gICAgLy8gYW5kIGhhcyBsb3dlciBwcmlvcml0eSB0aGFuIHRoZSBzc29fcmVnaW9uIGJ1dCBzdGlsbCBoaWdoZXIgcHJpb3JpdHkgdGhhbiBTVFMgZ2xvYmFsIHJlZ2lvbi5cbiAgICBjb25zdCBwYXJlbnRDbGllbnRDb25maWcgPSB7XG4gICAgICByZWdpb246IGF3YWl0IHRoaXMucmVnaW9uKG9wdGlvbnMucHJvZmlsZSksXG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBUaGUgcHJldmlvdXMgaW1wbGVtZW50YXRpb24gbWF0Y2hlZCBBV1MgQ0xJIGJlaGF2aW9yOlxuICAgICAqXG4gICAgICogSWYgYSBwcm9maWxlIGlzIGV4cGxpY2l0bHkgc2V0IHVzaW5nIGAtLXByb2ZpbGVgLFxuICAgICAqIHdlIHVzZSB0aGF0IHRvIHRoZSBleGNsdXNpb24gb2YgZXZlcnl0aGluZyBlbHNlLlxuICAgICAqXG4gICAgICogTm90ZTogdGhpcyBkb2VzIG5vdCBhcHBseSB0byBBV1NfUFJPRklMRSxcbiAgICAgKiBlbnZpcm9ubWVudCBjcmVkZW50aWFscyBzdGlsbCB0YWtlIHByZWNlZGVuY2Ugb3ZlciBBV1NfUFJPRklMRVxuICAgICAqL1xuICAgIGlmIChvcHRpb25zLnByb2ZpbGUpIHtcbiAgICAgIHJldHVybiBtYWtlQ2FjaGluZ1Byb3ZpZGVyKGZyb21Jbmkoe1xuICAgICAgICBwcm9maWxlOiBvcHRpb25zLnByb2ZpbGUsXG4gICAgICAgIGlnbm9yZUNhY2hlOiB0cnVlLFxuICAgICAgICBtZmFDb2RlUHJvdmlkZXI6IHRva2VuQ29kZUZuLFxuICAgICAgICBjbGllbnRDb25maWcsXG4gICAgICAgIHBhcmVudENsaWVudENvbmZpZyxcbiAgICAgICAgbG9nZ2VyOiBvcHRpb25zLmxvZ2dlcixcbiAgICAgIH0pKTtcbiAgICB9XG5cbiAgICBjb25zdCBlbnZQcm9maWxlID0gcHJvY2Vzcy5lbnYuQVdTX1BST0ZJTEUgfHwgcHJvY2Vzcy5lbnYuQVdTX0RFRkFVTFRfUFJPRklMRTtcblxuICAgIC8qKlxuICAgICAqIEVudiBBV1MgLSBFbnZpcm9ubWVudENyZWRlbnRpYWxzIHdpdGggc3RyaW5nIEFXU1xuICAgICAqIEVudiBBbWF6b24gLSBFbnZpcm9ubWVudENyZWRlbnRpYWxzIHdpdGggc3RyaW5nIEFNQVpPTlxuICAgICAqIFByb2ZpbGUgQ3JlZGVudGlhbHMgLSBQYXRjaGVkU2hhcmVkSW5pRmlsZUNyZWRlbnRpYWxzIHdpdGggaW1wbGljaXQgcHJvZmlsZSwgY3JlZGVudGlhbHMgZmlsZSwgaHR0cCBvcHRpb25zLCBhbmQgdG9rZW4gZm5cbiAgICAgKiAgICBTU08gd2l0aCBpbXBsaWNpdCBwcm9maWxlIG9ubHlcbiAgICAgKiAgICBTaGFyZWRJbmlGaWxlQ3JlZGVudGlhbHMgd2l0aCBpbXBsaWNpdCBwcm9maWxlIGFuZCBwcmVmZXJTdGF0aWNDcmVkZW50aWFscyB0cnVlIChwcm9maWxlIHdpdGggc291cmNlX3Byb2ZpbGUpXG4gICAgICogICAgU2hhcmVkIENyZWRlbnRpYWwgZmlsZSB0aGF0IHBvaW50cyB0byBFbnZpcm9ubWVudCBDcmVkZW50aWFscyB3aXRoIEFXUyBwcmVmaXhcbiAgICAgKiAgICBTaGFyZWQgQ3JlZGVudGlhbCBmaWxlIHRoYXQgcG9pbnRzIHRvIEVDMiBNZXRhZGF0YVxuICAgICAqICAgIFNoYXJlZCBDcmVkZW50aWFsIGZpbGUgdGhhdCBwb2ludHMgdG8gRUNTIENyZWRlbnRpYWxzXG4gICAgICogU1NPIENyZWRlbnRpYWxzIC0gU3NvQ3JlZGVudGlhbHMgd2l0aCBpbXBsaWNpdCBwcm9maWxlIGFuZCBodHRwIG9wdGlvbnNcbiAgICAgKiBQcm9jZXNzQ3JlZGVudGlhbHMgd2l0aCBpbXBsaWNpdCBwcm9maWxlXG4gICAgICogRUNTIENyZWRlbnRpYWxzIC0gRUNTQ3JlZGVudGlhbHMgd2l0aCBubyBpbnB1dCBPUiBXZWIgSWRlbnRpdHkgLSBUb2tlbkZpbGVXZWJJZGVudGl0eUNyZWRlbnRpYWxzIHdpdGggbm8gaW5wdXQgT1IgRUMyIE1ldGFkYXRhIC0gRUMyTWV0YWRhdGFDcmVkZW50aWFscyB3aXRoIG5vIGlucHV0XG4gICAgICpcbiAgICAgKiBUaGVzZSB0cmFuc2xhdGUgdG86XG4gICAgICogZnJvbUVudigpXG4gICAgICogZnJvbVNTTygpL2Zyb21JbmkoKVxuICAgICAqIGZyb21Qcm9jZXNzKClcbiAgICAgKiBmcm9tQ29udGFpbmVyTWV0YWRhdGEoKVxuICAgICAqIGZyb21Ub2tlbkZpbGUoKVxuICAgICAqIGZyb21JbnN0YW5jZU1ldGFkYXRhKClcbiAgICAgKlxuICAgICAqIFRoZSBOb2RlUHJvdmlkZXJDaGFpbiBpcyBhbHJlYWR5IGNhY2hlZC5cbiAgICAgKi9cbiAgICBjb25zdCBub2RlUHJvdmlkZXJDaGFpbiA9IGZyb21Ob2RlUHJvdmlkZXJDaGFpbih7XG4gICAgICBwcm9maWxlOiBlbnZQcm9maWxlLFxuICAgICAgY2xpZW50Q29uZmlnLFxuICAgICAgcGFyZW50Q2xpZW50Q29uZmlnLFxuICAgICAgbG9nZ2VyOiBvcHRpb25zLmxvZ2dlcixcbiAgICAgIG1mYUNvZGVQcm92aWRlcjogdG9rZW5Db2RlRm4sXG4gICAgICBpZ25vcmVDYWNoZTogdHJ1ZSxcbiAgICB9KTtcblxuICAgIHJldHVybiBzaG91bGRQcmlvcml0aXplRW52KClcbiAgICAgID8gY3JlYXRlQ3JlZGVudGlhbENoYWluKGZyb21FbnYoKSwgbm9kZVByb3ZpZGVyQ2hhaW4pLmV4cGlyZUFmdGVyKDYwICogNjBfMDAwKVxuICAgICAgOiBub2RlUHJvdmlkZXJDaGFpbjtcbiAgfVxuXG4gIHB1YmxpYyBzdGF0aWMgcmVxdWVzdEhhbmRsZXJCdWlsZGVyKG9wdGlvbnM6IFNka0h0dHBPcHRpb25zID0ge30pOiBOb2RlSHR0cEhhbmRsZXJPcHRpb25zIHtcbiAgICBjb25zdCBhZ2VudCA9IHRoaXMucHJveHlBZ2VudChvcHRpb25zKTtcblxuICAgIHJldHVybiB7XG4gICAgICBjb25uZWN0aW9uVGltZW91dDogREVGQVVMVF9DT05ORUNUSU9OX1RJTUVPVVQsXG4gICAgICByZXF1ZXN0VGltZW91dDogREVGQVVMVF9USU1FT1VULFxuICAgICAgaHR0cHNBZ2VudDogYWdlbnQsXG4gICAgICBodHRwQWdlbnQ6IGFnZW50LFxuICAgIH07XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIHByb3h5QWdlbnQob3B0aW9uczogU2RrSHR0cE9wdGlvbnMpIHtcbiAgICAvLyBGb3JjZSBpdCB0byB1c2UgdGhlIHByb3h5IHByb3ZpZGVkIHRocm91Z2ggdGhlIGNvbW1hbmQgbGluZS5cbiAgICAvLyBPdGhlcndpc2UsIGxldCB0aGUgUHJveHlBZ2VudCBhdXRvLWRldGVjdCB0aGUgcHJveHkgdXNpbmcgZW52aXJvbm1lbnQgdmFyaWFibGVzLlxuICAgIGNvbnN0IGdldFByb3h5Rm9yVXJsID0gb3B0aW9ucy5wcm94eUFkZHJlc3MgIT0gbnVsbFxuICAgICAgPyAoKSA9PiBQcm9taXNlLnJlc29sdmUob3B0aW9ucy5wcm94eUFkZHJlc3MhKVxuICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICByZXR1cm4gbmV3IFByb3h5QWdlbnQoe1xuICAgICAgY2E6IHRyeUdldENBQ2VydChvcHRpb25zLmNhQnVuZGxlUGF0aCksXG4gICAgICBnZXRQcm94eUZvclVybCxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBdHRlbXB0cyB0byBnZXQgdGhlIHJlZ2lvbiBmcm9tIGEgbnVtYmVyIG9mIHNvdXJjZXMgYW5kIGZhbGxzIGJhY2sgdG8gdXMtZWFzdC0xIGlmIG5vIHJlZ2lvbiBjYW4gYmUgZm91bmQsXG4gICAqIGFzIGlzIGRvbmUgaW4gdGhlIEFXUyBDTEkuXG4gICAqXG4gICAqIFRoZSBvcmRlciBvZiBwcmlvcml0eSBpcyB0aGUgZm9sbG93aW5nOlxuICAgKlxuICAgKiAxLiBFbnZpcm9ubWVudCB2YXJpYWJsZXMgc3BlY2lmeWluZyByZWdpb24sIHdpdGggYm90aCBhbiBBV1MgcHJlZml4IGFuZCBBTUFaT04gcHJlZml4XG4gICAqICAgIHRvIG1haW50YWluIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LCBhbmQgd2l0aG91dCBgREVGQVVMVGAgaW4gdGhlIG5hbWUgYmVjYXVzZVxuICAgKiAgICBMYW1iZGEgYW5kIENvZGVCdWlsZCBzZXQgdGhlICRBV1NfUkVHSU9OIHZhcmlhYmxlLlxuICAgKiAyLiBSZWdpb25zIGxpc3RlZCBpbiB0aGUgU2hhcmVkIEluaSBGaWxlcyAtIEZpcnN0IGNoZWNraW5nIGZvciB0aGUgcHJvZmlsZSBwcm92aWRlZFxuICAgKiAgICBhbmQgdGhlbiBjaGVja2luZyBmb3IgdGhlIGRlZmF1bHQgcHJvZmlsZS5cbiAgICogMy4gSU1EUyBpbnN0YW5jZSBpZGVudGl0eSByZWdpb24gZnJvbSB0aGUgTWV0YWRhdGEgU2VydmljZS5cbiAgICogNC4gdXMtZWFzdC0xXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGFzeW5jIHJlZ2lvbihtYXliZVByb2ZpbGU/OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IGRlZmF1bHRSZWdpb24gPSAndXMtZWFzdC0xJztcbiAgICBjb25zdCBwcm9maWxlID0gbWF5YmVQcm9maWxlIHx8IHByb2Nlc3MuZW52LkFXU19QUk9GSUxFIHx8IHByb2Nlc3MuZW52LkFXU19ERUZBVUxUX1BST0ZJTEUgfHwgJ2RlZmF1bHQnO1xuXG4gICAgY29uc3QgcmVnaW9uID1cbiAgICAgIHByb2Nlc3MuZW52LkFXU19SRUdJT04gfHxcbiAgICAgIHByb2Nlc3MuZW52LkFNQVpPTl9SRUdJT04gfHxcbiAgICAgIHByb2Nlc3MuZW52LkFXU19ERUZBVUxUX1JFR0lPTiB8fFxuICAgICAgcHJvY2Vzcy5lbnYuQU1BWk9OX0RFRkFVTFRfUkVHSU9OIHx8XG4gICAgICAoYXdhaXQgZ2V0UmVnaW9uRnJvbUluaShwcm9maWxlKSkgfHxcbiAgICAgIChhd2FpdCByZWdpb25Gcm9tTWV0YWRhdGFTZXJ2aWNlKCkpO1xuXG4gICAgaWYgKCFyZWdpb24pIHtcbiAgICAgIGNvbnN0IHVzZWRQcm9maWxlID0gIXByb2ZpbGUgPyAnJyA6IGAgKHByb2ZpbGU6IFwiJHtwcm9maWxlfVwiKWA7XG4gICAgICBkZWJ1ZyhcbiAgICAgICAgYFVuYWJsZSB0byBkZXRlcm1pbmUgQVdTIHJlZ2lvbiBmcm9tIGVudmlyb25tZW50IG9yIEFXUyBjb25maWd1cmF0aW9uJHt1c2VkUHJvZmlsZX0sIGRlZmF1bHRpbmcgdG8gJyR7ZGVmYXVsdFJlZ2lvbn0nYCxcbiAgICAgICk7XG4gICAgICByZXR1cm4gZGVmYXVsdFJlZ2lvbjtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVnaW9uO1xuICB9XG59XG5cbi8qKlxuICogTG9va3MgdXAgdGhlIHJlZ2lvbiBvZiB0aGUgcHJvdmlkZWQgcHJvZmlsZS4gSWYgbm8gcmVnaW9uIGlzIHByZXNlbnQsXG4gKiBpdCB3aWxsIGF0dGVtcHQgdG8gbG9va3VwIHRoZSBkZWZhdWx0IHJlZ2lvbi5cbiAqIEBwYXJhbSBwcm9maWxlIFRoZSBwcm9maWxlIHRvIHVzZSB0byBsb29rdXAgdGhlIHJlZ2lvblxuICogQHJldHVybnMgVGhlIHJlZ2lvbiBmb3IgdGhlIHByb2ZpbGUgb3IgZGVmYXVsdCBwcm9maWxlLCBpZiBwcmVzZW50LiBPdGhlcndpc2UgcmV0dXJucyB1bmRlZmluZWQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGdldFJlZ2lvbkZyb21JbmkocHJvZmlsZTogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgY29uc3Qgc2hhcmVkRmlsZXMgPSBhd2FpdCBsb2FkU2hhcmVkQ29uZmlnRmlsZXMoeyBpZ25vcmVDYWNoZTogdHJ1ZSB9KTtcblxuICAvLyBQcmlvcml0eTpcbiAgLy9cbiAgLy8gY3JlZGVudGlhbHMgY29tZSBiZWZvcmUgY29uZmlnIGJlY2F1c2UgYXdzLWNsaSB2MSBiZWhhdmVzIGxpa2UgdGhhdC5cbiAgLy9cbiAgLy8gMS4gcHJvZmlsZS1yZWdpb24taW4tY3JlZGVudGlhbHNcbiAgLy8gMi4gcHJvZmlsZS1yZWdpb24taW4tY29uZmlnXG4gIC8vIDMuIGRlZmF1bHQtcmVnaW9uLWluLWNyZWRlbnRpYWxzXG4gIC8vIDQuIGRlZmF1bHQtcmVnaW9uLWluLWNvbmZpZ1xuXG4gIHJldHVybiBnZXRSZWdpb25Gcm9tSW5pRmlsZShwcm9maWxlLCBzaGFyZWRGaWxlcy5jcmVkZW50aWFsc0ZpbGUpXG4gICAgPz8gZ2V0UmVnaW9uRnJvbUluaUZpbGUocHJvZmlsZSwgc2hhcmVkRmlsZXMuY29uZmlnRmlsZSlcbiAgICA/PyBnZXRSZWdpb25Gcm9tSW5pRmlsZSgnZGVmYXVsdCcsIHNoYXJlZEZpbGVzLmNyZWRlbnRpYWxzRmlsZSlcbiAgICA/PyBnZXRSZWdpb25Gcm9tSW5pRmlsZSgnZGVmYXVsdCcsIHNoYXJlZEZpbGVzLmNvbmZpZ0ZpbGUpO1xufVxuXG5mdW5jdGlvbiBnZXRSZWdpb25Gcm9tSW5pRmlsZShwcm9maWxlOiBzdHJpbmcsIGRhdGE/OiBhbnkpIHtcbiAgcmV0dXJuIGRhdGE/Lltwcm9maWxlXT8ucmVnaW9uO1xufVxuXG5mdW5jdGlvbiB0cnlHZXRDQUNlcnQoYnVuZGxlUGF0aD86IHN0cmluZykge1xuICBjb25zdCBwYXRoID0gYnVuZGxlUGF0aCB8fCBjYUJ1bmRsZVBhdGhGcm9tRW52aXJvbm1lbnQoKTtcbiAgaWYgKHBhdGgpIHtcbiAgICBkZWJ1ZygnVXNpbmcgQ0EgYnVuZGxlIHBhdGg6ICVzJywgcGF0aCk7XG4gICAgcmV0dXJuIHJlYWRJZlBvc3NpYmxlKHBhdGgpO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogRmluZCBhbmQgcmV0dXJuIGEgQ0EgY2VydGlmaWNhdGUgYnVuZGxlIHBhdGggdG8gYmUgcGFzc2VkIGludG8gdGhlIFNESy5cbiAqL1xuZnVuY3Rpb24gY2FCdW5kbGVQYXRoRnJvbUVudmlyb25tZW50KCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmIChwcm9jZXNzLmVudi5hd3NfY2FfYnVuZGxlKSB7XG4gICAgcmV0dXJuIHByb2Nlc3MuZW52LmF3c19jYV9idW5kbGU7XG4gIH1cbiAgaWYgKHByb2Nlc3MuZW52LkFXU19DQV9CVU5ETEUpIHtcbiAgICByZXR1cm4gcHJvY2Vzcy5lbnYuQVdTX0NBX0JVTkRMRTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFdlIHVzZWQgdG8gc3VwcG9ydCBib3RoIEFXUyBhbmQgQU1BWk9OIHByZWZpeGVzIGZvciB0aGVzZSBlbnZpcm9ubWVudCB2YXJpYWJsZXMuXG4gKlxuICogQWRkaW5nIHRoaXMgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkuXG4gKi9cbmZ1bmN0aW9uIHNob3VsZFByaW9yaXRpemVFbnYoKSB7XG4gIGNvbnN0IGlkID0gcHJvY2Vzcy5lbnYuQVdTX0FDQ0VTU19LRVlfSUQgfHwgcHJvY2Vzcy5lbnYuQU1BWk9OX0FDQ0VTU19LRVlfSUQ7XG4gIGNvbnN0IGtleSA9IHByb2Nlc3MuZW52LkFXU19TRUNSRVRfQUNDRVNTX0tFWSB8fCBwcm9jZXNzLmVudi5BTUFaT05fU0VDUkVUX0FDQ0VTU19LRVk7XG5cbiAgaWYgKCEhaWQgJiYgISFrZXkpIHtcbiAgICBwcm9jZXNzLmVudi5BV1NfQUNDRVNTX0tFWV9JRCA9IGlkO1xuICAgIHByb2Nlc3MuZW52LkFXU19TRUNSRVRfQUNDRVNTX0tFWSA9IGtleTtcblxuICAgIGNvbnN0IHNlc3Npb25Ub2tlbiA9IHByb2Nlc3MuZW52LkFXU19TRVNTSU9OX1RPS0VOID8/IHByb2Nlc3MuZW52LkFNQVpPTl9TRVNTSU9OX1RPS0VOO1xuICAgIGlmIChzZXNzaW9uVG9rZW4pIHtcbiAgICAgIHByb2Nlc3MuZW52LkFXU19TRVNTSU9OX1RPS0VOID0gc2Vzc2lvblRva2VuO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKipcbiAqIFRoZSBNZXRhZGF0YVNlcnZpY2UgY2xhc3Mgd2lsbCBhdHRlbXB0IHRvIGZldGNoIHRoZSBpbnN0YW5jZSBpZGVudGl0eSBkb2N1bWVudCBmcm9tXG4gKiBJTURTdjIgZmlyc3QsIGFuZCB0aGVuIHdpbGwgYXR0ZW1wdCB2MSBhcyBhIGZhbGxiYWNrLlxuICpcbiAqIElmIHRoaXMgZmFpbHMsIHdlIHdpbGwgdXNlIHVzLWVhc3QtMSBhcyB0aGUgcmVnaW9uIHNvIG5vIGVycm9yIHNob3VsZCBiZSB0aHJvd24uXG4gKiBAcmV0dXJucyBUaGUgcmVnaW9uIGZvciB0aGUgaW5zdGFuY2UgaWRlbnRpdHlcbiAqL1xuYXN5bmMgZnVuY3Rpb24gcmVnaW9uRnJvbU1ldGFkYXRhU2VydmljZSgpIHtcbiAgZGVidWcoJ0xvb2tpbmcgdXAgQVdTIHJlZ2lvbiBpbiB0aGUgRUMyIEluc3RhbmNlIE1ldGFkYXRhIFNlcnZpY2UgKElNRFMpLicpO1xuICB0cnkge1xuICAgIGNvbnN0IG1ldGFkYXRhU2VydmljZSA9IG5ldyBNZXRhZGF0YVNlcnZpY2Uoe1xuICAgICAgaHR0cE9wdGlvbnM6IHtcbiAgICAgICAgdGltZW91dDogMTAwMCxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBhd2FpdCBtZXRhZGF0YVNlcnZpY2UuZmV0Y2hNZXRhZGF0YVRva2VuKCk7XG4gICAgY29uc3QgZG9jdW1lbnQgPSBhd2FpdCBtZXRhZGF0YVNlcnZpY2UucmVxdWVzdCgnL2xhdGVzdC9keW5hbWljL2luc3RhbmNlLWlkZW50aXR5L2RvY3VtZW50Jywge30pO1xuICAgIHJldHVybiBKU09OLnBhcnNlKGRvY3VtZW50KS5yZWdpb247XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBkZWJ1ZyhgVW5hYmxlIHRvIHJldHJpZXZlIEFXUyByZWdpb24gZnJvbSBJTURTOiAke2V9YCk7XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBDcmVkZW50aWFsQ2hhaW5PcHRpb25zIHtcbiAgcmVhZG9ubHkgcHJvZmlsZT86IHN0cmluZztcbiAgcmVhZG9ubHkgaHR0cE9wdGlvbnM/OiBTZGtIdHRwT3B0aW9ucztcbiAgcmVhZG9ubHkgbG9nZ2VyPzogTG9nZ2VyO1xufVxuXG4vKipcbiAqIEFzayB1c2VyIGZvciBNRkEgdG9rZW4gZm9yIGdpdmVuIHNlcmlhbFxuICpcbiAqIFJlc3VsdCBpcyBzZW5kIHRvIGNhbGxiYWNrIGZ1bmN0aW9uIGZvciBTREsgdG8gYXV0aG9yaXplIHRoZSByZXF1ZXN0XG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHRva2VuQ29kZUZuKHNlcmlhbEFybjogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgZGVidWcoJ1JlcXVpcmUgTUZBIHRva2VuIGZvciBzZXJpYWwgQVJOJywgc2VyaWFsQXJuKTtcbiAgdHJ5IHtcbiAgICBjb25zdCB0b2tlbjogc3RyaW5nID0gYXdhaXQgcHJvbXB0bHkucHJvbXB0KGBNRkEgdG9rZW4gZm9yICR7c2VyaWFsQXJufTogYCwge1xuICAgICAgdHJpbTogdHJ1ZSxcbiAgICAgIGRlZmF1bHQ6ICcnLFxuICAgIH0pO1xuICAgIGRlYnVnKCdTdWNjZXNzZnVsbHkgZ290IE1GQSB0b2tlbiBmcm9tIHVzZXInKTtcbiAgICByZXR1cm4gdG9rZW47XG4gIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgZGVidWcoJ0ZhaWxlZCB0byBnZXQgTUZBIHRva2VuJywgZXJyKTtcbiAgICBjb25zdCBlID0gbmV3IEF1dGhlbnRpY2F0aW9uRXJyb3IoYEVycm9yIGZldGNoaW5nIE1GQSB0b2tlbjogJHtlcnIubWVzc2FnZSA/PyBlcnJ9YCk7XG4gICAgZS5uYW1lID0gJ1NoYXJlZEluaUZpbGVDcmVkZW50aWFsc1Byb3ZpZGVyRmFpbHVyZSc7XG4gICAgdGhyb3cgZTtcbiAgfVxufVxuIl19
;