@aws-cdk/core
Version:
AWS Cloud Development Kit Core Library
129 lines • 18.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CustomResourceProvider = exports.CustomResourceProviderRuntime = void 0;
const fs = require("fs");
const path = require("path");
const asset_staging_1 = require("../asset-staging");
const assets_1 = require("../assets");
const cfn_resource_1 = require("../cfn-resource");
const duration_1 = require("../duration");
const size_1 = require("../size");
const stack_1 = require("../stack");
const token_1 = require("../token");
const ENTRYPOINT_FILENAME = '__entrypoint__';
const ENTRYPOINT_NODEJS_SOURCE = path.join(__dirname, 'nodejs-entrypoint.js');
// v2 - keep this import as a separate section to reduce merge conflict when forward merging with the v2 branch.
// eslint-disable-next-line
const construct_compat_1 = require("../construct-compat");
/**
* The lambda runtime to use for the resource provider. This also indicates
* which language is used for the handler.
* @experimental
*/
var CustomResourceProviderRuntime;
(function (CustomResourceProviderRuntime) {
CustomResourceProviderRuntime["NODEJS_12"] = "nodejs12";
})(CustomResourceProviderRuntime = exports.CustomResourceProviderRuntime || (exports.CustomResourceProviderRuntime = {}));
/**
* (experimental) An AWS-Lambda backed custom resource provider.
*
* @experimental
*/
class CustomResourceProvider extends construct_compat_1.Construct {
/**
* @experimental
*/
constructor(scope, id, props) {
var _a, _b;
super(scope, id);
const stack = stack_1.Stack.of(scope);
// copy the entry point to the code directory
fs.copyFileSync(ENTRYPOINT_NODEJS_SOURCE, path.join(props.codeDirectory, `${ENTRYPOINT_FILENAME}.js`));
// verify we have an index file there
if (!fs.existsSync(path.join(props.codeDirectory, 'index.js'))) {
throw new Error(`cannot find ${props.codeDirectory}/index.js`);
}
const staging = new asset_staging_1.AssetStaging(this, 'Staging', {
sourcePath: props.codeDirectory,
});
const asset = stack.addFileAsset({
fileName: staging.stagedPath,
sourceHash: staging.sourceHash,
packaging: assets_1.FileAssetPackaging.ZIP_DIRECTORY,
});
const policies = !props.policyStatements ? undefined : [
{
PolicyName: 'Inline',
PolicyDocument: {
Version: '2012-10-17',
Statement: props.policyStatements,
},
},
];
const role = new cfn_resource_1.CfnResource(this, 'Role', {
type: 'AWS::IAM::Role',
properties: {
AssumeRolePolicyDocument: {
Version: '2012-10-17',
Statement: [{ Action: 'sts:AssumeRole', Effect: 'Allow', Principal: { Service: 'lambda.amazonaws.com' } }],
},
ManagedPolicyArns: [
{ 'Fn::Sub': 'arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole' },
],
Policies: policies,
},
});
const timeout = (_a = props.timeout) !== null && _a !== void 0 ? _a : duration_1.Duration.minutes(15);
const memory = (_b = props.memorySize) !== null && _b !== void 0 ? _b : size_1.Size.mebibytes(128);
const handler = new cfn_resource_1.CfnResource(this, 'Handler', {
type: 'AWS::Lambda::Function',
properties: {
Code: {
S3Bucket: asset.bucketName,
S3Key: asset.objectKey,
},
Timeout: timeout.toSeconds(),
MemorySize: memory.toMebibytes(),
Handler: `${ENTRYPOINT_FILENAME}.handler`,
Role: role.getAtt('Arn'),
Runtime: 'nodejs12.x',
Environment: this.renderEnvironmentVariables(props.environment),
},
});
handler.addDependsOn(role);
this.serviceToken = token_1.Token.asString(handler.getAtt('Arn'));
}
/**
* (experimental) Returns a stack-level singleton ARN (service token) for the custom resource provider.
*
* @param scope Construct scope.
* @param uniqueid A globally unique id that will be used for the stack-level construct.
* @param props Provider properties which will only be applied when the provider is first created.
* @returns the service token of the custom resource provider, which should be
* used when defining a `CustomResource`.
* @experimental
*/
static getOrCreate(scope, uniqueid, props) {
var _a;
const id = `${uniqueid}CustomResourceProvider`;
const stack = stack_1.Stack.of(scope);
const provider = (_a = stack.node.tryFindChild(id)) !== null && _a !== void 0 ? _a : new CustomResourceProvider(stack, id, props);
return provider.serviceToken;
}
renderEnvironmentVariables(env) {
if (!env || Object.keys(env).length === 0) {
return undefined;
}
// Sort environment so the hash of the function used to create
// `currentVersion` is not affected by key order (this is how lambda does
// it)
const variables = {};
const keys = Object.keys(env).sort();
for (const key of keys) {
variables[key] = env[key];
}
return { Variables: variables };
}
}
exports.CustomResourceProvider = CustomResourceProvider;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tLXJlc291cmNlLXByb3ZpZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY3VzdG9tLXJlc291cmNlLXByb3ZpZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHlCQUF5QjtBQUN6Qiw2QkFBNkI7QUFFN0Isb0RBQWdEO0FBQ2hELHNDQUErQztBQUMvQyxrREFBOEM7QUFDOUMsMENBQXVDO0FBQ3ZDLGtDQUErQjtBQUMvQixvQ0FBaUM7QUFDakMsb0NBQWlDO0FBRWpDLE1BQU0sbUJBQW1CLEdBQUcsZ0JBQWdCLENBQUM7QUFDN0MsTUFBTSx3QkFBd0IsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxzQkFBc0IsQ0FBQyxDQUFDO0FBRTlFLGdIQUFnSDtBQUNoSCwyQkFBMkI7QUFDM0IsMERBQWlFO0FBdURqRTs7OztHQUlHO0FBQ0gsSUFBWSw2QkFLWDtBQUxELFdBQVksNkJBQTZCO0lBSXZDLHVEQUFzQixDQUFBO0FBQ3hCLENBQUMsRUFMVyw2QkFBNkIsR0FBN0IscUNBQTZCLEtBQTdCLHFDQUE2QixRQUt4Qzs7Ozs7O0FBT0QsTUFBYSxzQkFBdUIsU0FBUSw0QkFBYTs7OztJQW9DdkQsWUFBc0IsS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBa0M7O1FBQ3BGLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFakIsTUFBTSxLQUFLLEdBQUcsYUFBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUU5Qiw2Q0FBNkM7UUFDN0MsRUFBRSxDQUFDLFlBQVksQ0FBQyx3QkFBd0IsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLEVBQUUsR0FBRyxtQkFBbUIsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUV2RyxxQ0FBcUM7UUFDckMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFF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QU0sUUFBUSxTQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBMkIsbUNBQ2pFLElBQUksc0JBQXNCLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUVsRCxPQUFPLFFBQVEsQ0FBQyxZQUFZLENBQUM7SUFDL0IsQ0FBQztJQXVGTywwQkFBMEIsQ0FBQyxHQUErQjtRQUNoRSxJQUFJLENBQUMsR0FBRyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtZQUN6QyxPQUFPLFNBQVMsQ0FBQztTQUNsQjtRQUVELDhEQUE4RDtRQUM5RCx5RUFBeUU7UUFDekUsTUFBTTtRQUNOLE1BQU0sU0FBUyxHQUE4QixFQUFFLENBQUM7UUFDaEQsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUVyQyxLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksRUFBRTtZQUN0QixTQUFTLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1NBQzNCO1FBRUQsT0FBTyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsQ0FBQztJQUNsQyxDQUFDO0NBQ0Y7QUE1SEQsd0RBNEhDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgQXNzZXRTdGFnaW5nIH0gZnJvbSAnLi4vYXNzZXQtc3RhZ2luZyc7XG5pbXBvcnQgeyBGaWxlQXNzZXRQYWNrYWdpbmcgfSBmcm9tICcuLi9hc3NldHMnO1xuaW1wb3J0IHsgQ2ZuUmVzb3VyY2UgfSBmcm9tICcuLi9jZm4tcmVzb3VyY2UnO1xuaW1wb3J0IHsgRHVyYXRpb24gfSBmcm9tICcuLi9kdXJhdGlvbic7XG5pbXBvcnQgeyBTaXplIH0gZnJvbSAnLi4vc2l6ZSc7XG5pbXBvcnQgeyBTdGFjayB9IGZyb20gJy4uL3N0YWNrJztcbmltcG9ydCB7IFRva2VuIH0gZnJvbSAnLi4vdG9rZW4nO1xuXG5jb25zdCBFTlRSWVBPSU5UX0ZJTEVOQU1FID0gJ19fZW50cnlwb2ludF9fJztcbmNvbnN0IEVOVFJZUE9JTlRfTk9ERUpTX1NPVVJDRSA9IHBhdGguam9pbihfX2Rpcm5hbWUsICdub2RlanMtZW50cnlwb2ludC5qcycpO1xuXG4vLyB2MiAtIGtlZXAgdGhpcyBpbXBvcnQgYXMgYSBzZXBhcmF0ZSBzZWN0aW9uIHRvIHJlZHVjZSBtZXJnZSBjb25mbGljdCB3aGVuIGZvcndhcmQgbWVyZ2luZyB3aXRoIHRoZSB2MiBicmFuY2guXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbmltcG9ydCB7IENvbnN0cnVjdCBhcyBDb3JlQ29uc3RydWN0IH0gZnJvbSAnLi4vY29uc3RydWN0LWNvbXBhdCc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5leHBvcnQgaW50ZXJmYWNlIEN1c3RvbVJlc291cmNlUHJvdmlkZXJQcm9wcyB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgY29kZURpcmVjdG9yeTogc3RyaW5nO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHJ1bnRpbWU6IEN1c3RvbVJlc291cmNlUHJvdmlkZXJSdW50aW1lO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHBvbGljeVN0YXRlbWVudHM/OiBhbnlbXTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHRpbWVvdXQ/OiBEdXJhdGlvbjtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IG1lbW9yeVNpemU/OiBTaXplO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgZW52aXJvbm1lbnQ/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9O1xufVxuXG4vKipcbiAqIFRoZSBsYW1iZGEgcnVudGltZSB0byB1c2UgZm9yIHRoZSByZXNvdXJjZSBwcm92aWRlci4gVGhpcyBhbHNvIGluZGljYXRlc1xuICogd2hpY2ggbGFuZ3VhZ2UgaXMgdXNlZCBmb3IgdGhlIGhhbmRsZXIuXG4gKiBAZXhwZXJpbWVudGFsXG4gKi9cbmV4cG9ydCBlbnVtIEN1c3RvbVJlc291cmNlUHJvdmlkZXJSdW50aW1lIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIE5PREVKU18xMiA9ICdub2RlanMxMidcbn1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbmV4cG9ydCBjbGFzcyBDdXN0b21SZXNvdXJjZVByb3ZpZGVyIGV4dGVuZHMgQ29yZUNvbnN0cnVjdCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgc3RhdGljIGdldE9yQ3JlYXRlKHNjb3BlOiBDb25zdHJ1Y3QsIHVuaXF1ZWlkOiBzdHJpbmcsIHByb3BzOiBDdXN0b21SZXNvdXJjZVByb3ZpZGVyUHJvcHMpIHtcbiAgICBjb25zdCBpZCA9IGAke3VuaXF1ZWlkfUN1c3RvbVJlc291cmNlUHJvdmlkZXJgO1xuICAgIGNvbnN0IHN0YWNrID0gU3RhY2sub2Yoc2NvcGUpO1xuICAgIGNvbnN0IHByb3ZpZGVyID0gc3RhY2subm9kZS50cnlGaW5kQ2hpbGQoaWQpIGFzIEN1c3RvbVJlc291cmNlUHJvdmlkZXJcbiAgICAgID8/IG5ldyBDdXN0b21SZXNvdXJjZVByb3ZpZGVyKHN0YWNrLCBpZCwgcHJvcHMpO1xuXG4gICAgcmV0dXJuIHByb3ZpZGVyLnNlcnZpY2VUb2tlbjtcbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyByZWFkb25seSBzZXJ2aWNlVG9rZW46IHN0cmluZztcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IEN1c3RvbVJlc291cmNlUHJvdmlkZXJQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICBjb25zdCBzdGFjayA9IFN0YWNrLm9mKHNjb3BlKTtcblxuICAgIC8vIGNvcHkgdGhlIGVudHJ5IHBvaW50IHRvIHRoZSBjb2RlIGRpcmVjdG9yeVxuICAgIGZzLmNvcHlGaWxlU3luYyhFTlRSWVBPSU5UX05PREVKU19TT1VSQ0UsIHBhdGguam9pbihwcm9wcy5jb2RlRGlyZWN0b3J5LCBgJHtFTlRSWVBPSU5UX0ZJTEVOQU1FfS5qc2ApKTtcblxuICAgIC8vIHZlcmlmeSB3ZSBoYXZlIGFuIGluZGV4IGZpbGUgdGhlcmVcbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMocGF0aC5qb2luKHByb3BzLmNvZGVEaXJlY3RvcnksICdpbmRleC5qcycpKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBjYW5ub3QgZmluZCAke3Byb3BzLmNvZGVEaXJlY3Rvcnl9L2luZGV4LmpzYCk7XG4gICAgfVxuXG4gICAgY29uc3Qgc3RhZ2luZyA9IG5ldyBBc3NldFN0YWdpbmcodGhpcywgJ1N0YWdpbmcnLCB7XG4gICAgICBzb3VyY2VQYXRoOiBwcm9wcy5jb2RlRGlyZWN0b3J5LFxuICAgIH0pO1xuXG4gICAgY29uc3QgYXNzZXQgPSBzdGFjay5hZGRGaWxlQXNzZXQoe1xuICAgICAgZmlsZU5hbWU6IHN0YWdpbmcuc3RhZ2VkUGF0aCxcbiAgICAgIHNvdXJjZUhhc2g6IHN0YWdpbmcuc291cmNlSGFzaCxcbiAgICAgIHBhY2thZ2luZzogRmlsZUFzc2V0UGFja2FnaW5nLlpJUF9ESVJFQ1RPUlksXG4gICAgfSk7XG5cbiAgICBjb25zdCBwb2xpY2llcyA9ICFwcm9wcy5wb2xpY3lTdGF0ZW1lbnRzID8gdW5kZWZpbmVkIDogW1xuICAgICAge1xuICAgICAgICBQb2xpY3lOYW1lOiAnSW5saW5lJyxcbiAgICAgICAgUG9saWN5RG9jdW1lbnQ6IHtcbiAgICAgICAgICBWZXJzaW9uOiAnMjAxMi0xMC0xNycsXG4gICAgICAgICAgU3RhdGVtZW50OiBwcm9wcy5wb2xpY3lTdGF0ZW1lbnRzLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICBdO1xuXG4gICAgY29uc3Qgcm9sZSA9IG5ldyBDZm5SZXNvdXJjZSh0aGlzLCAnUm9sZScsIHtcbiAgICAgIHR5cGU6ICdBV1M6OklBTTo6Um9sZScsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIEFzc3VtZVJvbGVQb2xpY3lEb2N1bWVudDoge1xuICAgICAgICAgIFZlcnNpb246ICcyMDEyLTEwLTE3JyxcbiAgICAgICAgICBTdGF0ZW1lbnQ6IFt7IEFjdGlvbjogJ3N0czpBc3N1bWVSb2xlJywgRWZmZWN0OiAnQWxsb3cnLCBQcmluY2lwYWw6IHsgU2VydmljZTogJ2xhbWJkYS5hbWF6b25hd3MuY29tJyB9IH1dLFxuICAgICAgICB9LFxuICAgICAgICBNYW5hZ2VkUG9saWN5QXJuczogW1xuICAgICAgICAgIHsgJ0ZuOjpTdWInOiAnYXJuOiR7QVdTOjpQYXJ0aXRpb259OmlhbTo6YXdzOnBvbGljeS9zZXJ2aWNlLXJvbGUvQVdTTGFtYmRhQmFzaWNFeGVjdXRpb25Sb2xlJyB9LFxuICAgICAgICBdLFxuICAgICAgICBQb2xpY2llczogcG9saWNpZXMsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgY29uc3QgdGltZW91dCA9IHByb3BzLnRpbWVvdXQgPz8gRHVyYXRpb24ubWludXRlcygxNSk7XG4gICAgY29uc3QgbWVtb3J5ID0gcHJvcHMubWVtb3J5U2l6ZSA/PyBTaXplLm1lYmlieXRlcygxMjgpO1xuXG4gICAgY29uc3QgaGFuZGxlciA9IG5ldyBDZm5SZXNvdXJjZSh0aGlzLCAnSGFuZGxlcicsIHtcbiAgICAgIHR5cGU6ICdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBDb2RlOiB7XG4gICAgICAgICAgUzNCdWNrZXQ6IGFzc2V0LmJ1Y2tldE5hbWUsXG4gICAgICAgICAgUzNLZXk6IGFzc2V0Lm9iamVjdEtleSxcbiAgICAgICAgfSxcbiAgICAgICAgVGltZW91dDogdGltZW91dC50b1NlY29uZHMoKSxcbiAgICAgICAgTWVtb3J5U2l6ZTogbWVtb3J5LnRvTWViaWJ5dGVzKCksXG4gICAgICAgIEhhbmRsZXI6IGAke0VOVFJZUE9JTlRfRklMRU5BTUV9LmhhbmRsZXJgLFxuICAgICAgICBSb2xlOiByb2xlLmdldEF0dCgnQXJuJyksXG4gICAgICAgIFJ1bnRpbWU6ICdub2RlanMxMi54JyxcbiAgICAgICAgRW52aXJvbm1lbnQ6IHRoaXMucmVuZGVyRW52aXJvbm1lbnRWYXJpYWJsZXMocHJvcHMuZW52aXJvbm1lbnQpLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGhhbmRsZXIuYWRkRGVwZW5kc09uKHJvbGUpO1xuXG4gICAgdGhpcy5zZXJ2aWNlVG9rZW4gPSBUb2tlbi5hc1N0cmluZyhoYW5kbGVyLmdldEF0dCgnQXJuJykpO1xuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJFbnZpcm9ubWVudFZhcmlhYmxlcyhlbnY/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9KSB7XG4gICAgaWYgKCFlbnYgfHwgT2JqZWN0LmtleXMoZW52KS5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLy8gU29ydCBlbnZpcm9ubWVudCBzbyB0aGUgaGFzaCBvZiB0aGUgZnVuY3Rpb24gdXNlZCB0byBjcmVhdGVcbiAgICAvLyBgY3VycmVudFZlcnNpb25gIGlzIG5vdCBhZmZlY3RlZCBieSBrZXkgb3JkZXIgKHRoaXMgaXMgaG93IGxhbWJkYSBkb2VzXG4gICAgLy8gaXQpXG4gICAgY29uc3QgdmFyaWFibGVzOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9ID0ge307XG4gICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKGVudikuc29ydCgpO1xuXG4gICAgZm9yIChjb25zdCBrZXkgb2Yga2V5cykge1xuICAgICAgdmFyaWFibGVzW2tleV0gPSBlbnZba2V5XTtcbiAgICB9XG5cbiAgICByZXR1cm4geyBWYXJpYWJsZXM6IHZhcmlhYmxlcyB9O1xuICB9XG59XG4iXX0=