@aws-cdk/integ-tests-alpha
Version:
CDK Integration Testing Constructs
338 lines • 35 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
var useValue = arguments.length > 2;
for (var i = 0; i < initializers.length; i++) {
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
}
return useValue ? value : void 0;
};
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
var _, done = false;
for (var i = decorators.length - 1; i >= 0; i--) {
var context = {};
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
if (kind === "accessor") {
if (result === void 0) continue;
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
if (_ = accept(result.get)) descriptor.get = _;
if (_ = accept(result.set)) descriptor.set = _;
if (_ = accept(result.init)) initializers.unshift(_);
}
else if (_ = accept(result)) {
if (kind === "field") initializers.unshift(_);
else descriptor[key] = _;
}
}
if (target) Object.defineProperty(target, contextIn.name, descriptor);
done = true;
};
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.AssertionsProvider = void 0;
const jsiiDeprecationWarnings = require("../../../.warnings.jsii.js");
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const path = __importStar(require("path"));
const core_1 = require("aws-cdk-lib/core");
const helpers_internal_1 = require("aws-cdk-lib/core/lib/helpers-internal");
const helpers_internal_2 = require("aws-cdk-lib/custom-resources/lib/helpers-internal");
const constructs_1 = require("constructs");
/**
* integ-tests can only depend on '@aws-cdk/core' so
* this construct creates a lambda function provider using
* only CfnResource
*/
let LambdaFunctionProvider = (() => {
let _classSuper = constructs_1.Construct;
let _instanceExtraInitializers = [];
let _get_serviceToken_decorators;
return class LambdaFunctionProvider extends _classSuper {
static {
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
_get_serviceToken_decorators = [helpers_internal_1.memoizedGetter];
__esDecorate(this, null, _get_serviceToken_decorators, { kind: "getter", name: "serviceToken", static: false, private: false, access: { has: obj => "serviceToken" in obj, get: obj => obj.serviceToken }, metadata: _metadata }, null, _instanceExtraInitializers);
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
}
/**
* A Reference to the provider lambda exeuction role ARN
*/
roleArn = __runInitializers(this, _instanceExtraInitializers);
policies = [];
handler;
constructor(scope, id, props) {
super(scope, id);
const staging = new core_1.AssetStaging(this, 'Staging', {
sourcePath: path.join(__dirname, 'lambda-handler.bundle'),
});
const stack = core_1.Stack.of(this);
const asset = stack.synthesizer.addFileAsset({
fileName: staging.relativeStagedPath(stack),
sourceHash: staging.assetHash,
packaging: core_1.FileAssetPackaging.ZIP_DIRECTORY,
});
const role = new core_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: core_1.Lazy.any({
produce: () => {
const policies = this.policies.length > 0 ? [
{
PolicyName: 'Inline',
PolicyDocument: {
Version: '2012-10-17',
Statement: this.policies,
},
},
] : undefined;
return policies;
},
}),
},
});
const functionProperties = {
Runtime: (0, core_1.determineLatestNodeRuntimeName)(this),
Code: {
S3Bucket: asset.bucketName,
S3Key: asset.objectKey,
},
Timeout: core_1.Duration.minutes(2).toSeconds(),
Handler: props?.handler ?? 'index.handler',
Role: role.getAtt('Arn'),
LoggingConfig: {
LogFormat: 'JSON',
ApplicationLogLevel: props?.providerLogLevel ?? 'FATAL',
},
};
if (props?.logRetention) {
const logGroup = new core_1.CfnResource(this, 'LogGroup', {
type: 'AWS::Logs::LogGroup',
properties: {
LogGroupName: `/aws/lambda/${id}`,
RetentionInDays: props.logRetention,
},
});
functionProperties.LoggingConfig.LogGroup = logGroup.ref;
}
this.handler = new core_1.CfnResource(this, 'Handler', {
type: 'AWS::Lambda::Function',
properties: functionProperties,
});
this.roleArn = role.getAtt('Arn');
}
/**
* The ARN of the lambda function which can be used
* as a serviceToken to a CustomResource
*/
get serviceToken() {
return core_1.Token.asString(this.handler.getAtt('Arn'));
}
addPolicies(policies) {
this.policies.push(...policies);
}
};
})();
/**
* Mimic the singletonfunction construct in '@aws-cdk/aws-lambda'
*/
class SingletonFunction extends constructs_1.Construct {
serviceToken;
lambdaFunction;
constructor(scope, id, props) {
super(scope, id);
this.lambdaFunction = this.ensureFunction(props);
this.serviceToken = this.lambdaFunction.serviceToken;
}
ensureFunction(props) {
const constructName = 'SingletonFunction' + slugify(props.uuid);
const existing = core_1.Stack.of(this).node.tryFindChild(constructName);
if (existing) {
return existing;
}
return new LambdaFunctionProvider(core_1.Stack.of(this), constructName, {
handler: props.handler,
logRetention: props.logRetention,
providerLogLevel: props.providerLogLevel,
});
}
/**
* Add an IAM policy statement to the inline policy of the
* lambdas function's role
*
* **Please note**: this is a direct IAM JSON policy blob, *not* a `iam.PolicyStatement`
* object like you will see in the rest of the CDK.
*
*
* singleton.addToRolePolicy({
* Effect: 'Allow',
* Action: 's3:GetObject',
* Resources: '*',
* });
*/
addToRolePolicy(statement) {
this.lambdaFunction.addPolicies([statement]);
}
/**
* Create a policy statement from a specific api call
*/
addPolicyStatementFromSdkCall(service, api, resources) {
this.lambdaFunction.addPolicies([{
Action: [(0, helpers_internal_2.awsSdkToIamAction)(service, api)],
Effect: 'Allow',
Resource: resources || ['*'],
}]);
}
}
/**
* Represents an assertions provider. The creates a singletone
* Lambda Function that will create a single function per stack
* that serves as the custom resource provider for the various
* assertion providers
*/
class AssertionsProvider extends constructs_1.Construct {
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/integ-tests-alpha.AssertionsProvider", version: "2.260.0-alpha.0" };
/**
* The ARN of the lambda function which can be used
* as a serviceToken to a CustomResource
*/
serviceToken;
/**
* A reference to the provider Lambda Function
* execution Role ARN
*/
handlerRoleArn;
handler;
constructor(scope, id, props) {
super(scope, id);
try {
jsiiDeprecationWarnings._aws_cdk_integ_tests_alpha_AssertionsProviderProps(props);
}
catch (error) {
if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
Error.captureStackTrace(error, AssertionsProvider);
}
throw error;
}
this.handler = new SingletonFunction(this, 'AssertionsProvider', {
handler: props?.handler,
uuid: props?.uuid ?? '1488541a-7b23-4664-81b6-9b4408076b81',
logRetention: props?.logRetention,
providerLogLevel: props?.providerLogLevel,
});
this.handlerRoleArn = this.handler.lambdaFunction.roleArn;
this.serviceToken = this.handler.serviceToken;
}
/**
* Encode an object so it can be passed
* as custom resource parameters. Custom resources will convert
* all input parameters to strings so we encode non-strings here
* so we can then decode them correctly in the provider function
*/
encode(obj) {
if (!obj) {
return obj;
}
return Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, encodeValue(value)]));
function encodeValue(value) {
if (ArrayBuffer.isView(value)) {
return {
$type: 'ArrayBufferView',
string: new TextDecoder().decode(value),
};
}
return JSON.stringify(value);
}
}
/**
* Create a policy statement from a specific api call
*/
addPolicyStatementFromSdkCall(service, api, resources) {
this.handler.addPolicyStatementFromSdkCall(service, api, resources);
}
/**
* Add an IAM policy statement to the inline policy of the
* lambdas function's role
*
* **Please note**: this is a direct IAM JSON policy blob, *not* a `iam.PolicyStatement`
* object like you will see in the rest of the CDK.
*
*
* @example
* declare const provider: AssertionsProvider;
* provider.addToRolePolicy({
* Effect: 'Allow',
* Action: ['s3:GetObject'],
* Resource: ['*'],
* });
*/
addToRolePolicy(statement) {
this.handler.addToRolePolicy(statement);
}
/**
* Grant a principal access to invoke the assertion provider
* lambda function
* [disable-awslint:no-grants]
*
* @param principalArn the ARN of the principal that should be given
* permission to invoke the assertion provider
*/
grantInvoke(principalArn) {
new core_1.CfnResource(this, 'Invoke', {
type: 'AWS::Lambda::Permission',
properties: {
Action: 'lambda:InvokeFunction',
FunctionName: this.serviceToken,
Principal: principalArn,
},
});
}
}
exports.AssertionsProvider = AssertionsProvider;
function slugify(x) {
return x.replace(/[^a-zA-Z0-9]/g, '');
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJwcm92aWRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwyQ0FBNkI7QUFJN0IsMkNBUzBCO0FBQzFCLDRFQUF1RTtBQUN2RSx3RkFBc0Y7QUFDdEYsMkNBQXVDO0FBaUN2Qzs7OztHQUlHO0lBQ0csc0JBQXNCO3NCQUFTLHNCQUFTOzs7aUJBQXhDLHNCQUF1QixTQUFRLFdBQVM7Ozs0Q0EwRjNDLGlDQUFjO1lBQ2YsMkxBQVcsWUFBWSw2REFFdEI7OztRQTVGRDs7V0FFRztRQUNhLE9BQU8sR0FKbkIsbURBQXNCLENBSVM7UUFFbEIsUUFBUSxHQUFVLEVBQUUsQ0FBQztRQUVyQixPQUFPLENBQWM7UUFFdEMsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUFtQztZQUMzRSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBRWpCLE1BQU0sT0FBTyxHQUFHLElBQUksbUJBQVksQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFO2dCQUNoRCxVQUFVLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsdUJBQXVCLENBQUM7YUFDMUQsQ0FBQyxDQUFDO1lBRUgsTUFBTSxLQUFLLEdBQUcsWUFBSyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUM3QixNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsV0FBVyxDQUFDLFlBQVksQ0FBQztnQkFDM0MsUUFBUSxFQUFFLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUM7Z0JBQzNDLFVBQVUsRUFBRSxPQUFPLENBQUMsU0FBUztnQkFDN0IsU0FBUyxFQUFFLHlCQUFrQixDQUFDLGFBQWE7YUFDNUMsQ0FBQyxDQUFDO1lBRUgsTUFBTSxJQUFJLEdBQUcsSUFBSSxrQkFB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QUFDLENBQUMsQ0FBQztRQUVoRyxTQUFTLFdBQVcsQ0FBQyxLQUFVO1lBQzdCLElBQUksV0FBVyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUM5QixPQUFPO29CQUNMLEtBQUssRUFBRSxpQkFBaUI7b0JBQ3hCLE1BQU0sRUFBRSxJQUFJLFdBQVcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFtQixDQUFDO2lCQUN0RCxDQUFDO1lBQ0osQ0FBQztZQUVELE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMvQixDQUFDO0tBQ0Y7SUFFRDs7T0FFRztJQUNJLDZCQUE2QixDQUFDLE9BQWUsRUFBRSxHQUFXLEVBQUUsU0FBb0I7UUFDckYsSUFBSSxDQUFDLE9BQU8sQ0FBQyw2QkFBNkIsQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0tBQ3JFO0lBRUQ7Ozs7Ozs7Ozs7Ozs7OztPQWVHO0lBQ0ksZUFBZSxDQUFDLFNBQWM7UUFDbkMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLENBQUM7S0FDekM7SUFFRDs7Ozs7OztPQU9HO0lBQ0ksV0FBVyxDQUFDLFlBQW9CO1FBQ3JDLElBQUksa0JBQVcsQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFO1lBQzlCLElBQUksRUFBRSx5QkFBeUI7WUFDL0IsVUFBVSxFQUFFO2dCQUNWLE1BQU0sRUFBRSx1QkFBdUI7Z0JBQy9CLFlBQVksRUFBRSxJQUFJLENBQUMsWUFBWTtnQkFDL0IsU0FBUyxFQUFFLFlBQVk7YUFDeEI7U0FDRixDQUFDLENBQUM7S0FDSjs7QUFsR0gsZ0RBbUdDO0FBRUQsU0FBUyxPQUFPLENBQUMsQ0FBUztJQUN4QixPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQ3hDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHR5cGUgeyBBcHBsaWNhdGlvbkxvZ0xldmVsIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWxhbWJkYSc7XG5pbXBvcnQgdHlwZSB7IFJldGVudGlvbkRheXMgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbG9ncyc7XG5pbXBvcnQgdHlwZSB7IFJlZmVyZW5jZSB9IGZyb20gJ2F3cy1jZGstbGliL2NvcmUnO1xuaW1wb3J0IHtcbiAgRHVyYXRpb24sXG4gIENmblJlc291cmNlLFxuICBBc3NldFN0YWdpbmcsXG4gIFN0YWNrLFxuICBGaWxlQXNzZXRQYWNrYWdpbmcsXG4gIFRva2VuLFxuICBMYXp5LFxuICBkZXRlcm1pbmVMYXRlc3ROb2RlUnVudGltZU5hbWUsXG59IGZyb20gJ2F3cy1jZGstbGliL2NvcmUnO1xuaW1wb3J0IHsgbWVtb2l6ZWRHZXR0ZXIgfSBmcm9tICdhd3MtY2RrLWxpYi9jb3JlL2xpYi9oZWxwZXJzLWludGVybmFsJztcbmltcG9ydCB7IGF3c1Nka1RvSWFtQWN0aW9uIH0gZnJvbSAnYXdzLWNkay1saWIvY3VzdG9tLXJlc291cmNlcy9saWIvaGVscGVycy1pbnRlcm5hbCc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcblxuLyoqXG4gKiBTaGFyZWQgb3B0aW9ucyBmb3IgY29uZmlndXJpbmcgdGhlIGFzc2VydGlvbiBwcm92aWRlciBsYW1iZGEgZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHJvdmlkZXJPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBsb2cgbGV2ZWwgb2YgdGhlIHByb3ZpZGVyIGxhbWJkYSBmdW5jdGlvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgQXBwbGljYXRpb25Mb2dMZXZlbC5GQVRBTFxuICAgKi9cbiAgcmVhZG9ubHkgcHJvdmlkZXJMb2dMZXZlbD86IEFwcGxpY2F0aW9uTG9nTGV2ZWw7XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgYSBsYW1iZGEgZnVuY3Rpb24gcHJvdmlkZXJcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBMYW1iZGFGdW5jdGlvblByb3ZpZGVyUHJvcHMgZXh0ZW5kcyBQcm92aWRlck9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIGhhbmRsZXIgdG8gdXNlIGZvciB0aGUgbGFtYmRhIGZ1bmN0aW9uXG4gICAqXG4gICAqIEBkZWZhdWx0IGluZGV4LmhhbmRsZXJcbiAgICovXG4gIHJlYWRvbmx5IGhhbmRsZXI/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEhvdyBsb25nLCBpbiBkYXlzLCB0aGUgbG9nIGNvbnRlbnRzIHdpbGwgYmUgcmV0YWluZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gcmV0ZW50aW9uIGRheXMgc3BlY2lmaWVkXG4gICAqL1xuICByZWFkb25seSBsb2dSZXRlbnRpb24/OiBSZXRlbnRpb25EYXlzO1xufVxuXG4vKipcbiAqIGludGVnLXRlc3RzIGNhbiBvbmx5IGRlcGVuZCBvbiAnQGF3cy1jZGsvY29yZScgc29cbiAqIHRoaXMgY29uc3RydWN0IGNyZWF0ZXMgYSBsYW1iZGEgZnVuY3Rpb24gcHJvdmlkZXIgdXNpbmdcbiAqIG9ubHkgQ2ZuUmVzb3VyY2VcbiAqL1xuY2xhc3MgTGFtYmRhRnVuY3Rpb25Qcm92aWRlciBleHRlbmRzIENvbnN0cnVjdCB7XG4gIC8qKlxuICAgKiBBIFJlZmVyZW5jZSB0byB0aGUgcHJvdmlkZXIgbGFtYmRhIGV4ZXVjdGlvbiByb2xlIEFSTlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHJvbGVBcm46IFJlZmVyZW5jZTtcblxuICBwcml2YXRlIHJlYWRvbmx5IHBvbGljaWVzOiBhbnlbXSA9IFtdO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgaGFuZGxlcjogQ2ZuUmVzb3VyY2U7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM/OiBMYW1iZGFGdW5jdGlvblByb3ZpZGVyUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgY29uc3Qgc3RhZ2luZyA9IG5ldyBBc3NldFN0YWdpbmcodGhpcywgJ1N0YWdpbmcnLCB7XG4gICAgICBzb3VyY2VQYXRoOiBwYXRoLmpvaW4oX19kaXJuYW1lLCAnbGFtYmRhLWhhbmRsZXIuYnVuZGxlJyksXG4gICAgfSk7XG5cbiAgICBjb25zdCBzdGFjayA9IFN0YWNrLm9mKHRoaXMpO1xuICAgIGNvbnN0IGFzc2V0ID0gc3RhY2suc3ludGhlc2l6ZXIuYWRkRmlsZUFzc2V0KHtcbiAgICAgIGZpbGVOYW1lOiBzdGFnaW5nLnJlbGF0aXZlU3RhZ2VkUGF0aChzdGFjayksXG4gICAgICBzb3VyY2VIYXNoOiBzdGFnaW5nLmFzc2V0SGFzaCxcbiAgICAgIHBhY2thZ2luZzogRmlsZUFzc2V0UGFja2FnaW5nLlpJUF9ESVJFQ1RPUlksXG4gICAgfSk7XG5cbiAgICBjb25zdCByb2xlID0gbmV3IENmblJlc291cmNlKHRoaXMsICdSb2xlJywge1xuICAgICAgdHlwZTogJ0FXUzo6SUFNOjpSb2xlJyxcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgQXNzdW1lUm9sZVBvbGljeURvY3VtZW50OiB7XG4gICAgICAgICAgVmVyc2lvbjogJzIwMTItMTAtMTcnLFxuICAgICAgICAgIFN0YXRlbWVudDogW3sgQWN0aW9uOiAnc3RzOkFzc3VtZVJvbGUnLCBFZmZlY3Q6ICdBbGxvdycsIFByaW5jaXBhbDogeyBTZXJ2aWNlOiAnbGFtYmRhLmFtYXpvbmF3cy5jb20nIH0gfV0sXG4gICAgICAgIH0sXG4gICAgICAgIE1hbmFnZWRQb2xpY3lBcm5zOiBbXG4gICAgICAgICAgeyAnRm46OlN1Yic6ICdhcm46JHtBV1M6OlBhcnRpdGlvbn06aWFtOjphd3M6cG9saWN5L3NlcnZpY2Utcm9sZS9BV1NMYW1iZGFCYXNpY0V4ZWN1dGlvblJvbGUnIH0sXG4gICAgICAgIF0sXG4gICAgICAgIFBvbGljaWVzOiBMYXp5LmFueSh7XG4gICAgICAgICAgcHJvZHVjZTogKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcG9saWNpZXMgPSB0aGlzLnBvbGljaWVzLmxlbmd0aCA+IDAgPyBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBQb2xpY3lOYW1lOiAnSW5saW5lJyxcbiAgICAgICAgICAgICAgICBQb2xpY3lEb2N1bWVudDoge1xuICAgICAgICAgICAgICAgICAgVmVyc2lvbjogJzIwMTItMTAtMTcnLFxuICAgICAgICAgICAgICAgICAgU3RhdGVtZW50OiB0aGlzLnBvbGljaWVzLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgcmV0dXJuIHBvbGljaWVzO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGZ1bmN0aW9uUHJvcGVydGllczogYW55ID0ge1xuICAgICAgUnVudGltZTogZGV0ZXJtaW5lTGF0ZXN0Tm9kZVJ1bnRpbWVOYW1lKHRoaXMpLFxuICAgICAgQ29kZToge1xuICAgICAgICBTM0J1Y2tldDogYXNzZXQuYnVja2V0TmFtZSxcbiAgICAgICAgUzNLZXk6IGFzc2V0Lm9iamVjdEtleSxcbiAgICAgIH0sXG4gICAgICBUaW1lb3V0OiBEdXJhdGlvbi5taW51dGVzKDIpLnRvU2Vjb25kcygpLFxuICAgICAgSGFuZGxlcjogcHJvcHM/LmhhbmRsZXIgPz8gJ2luZGV4LmhhbmRsZXInLFxuICAgICAgUm9sZTogcm9sZS5nZXRBdHQoJ0FybicpLFxuICAgICAgTG9nZ2luZ0NvbmZpZzoge1xuICAgICAgICBMb2dGb3JtYXQ6ICdKU09OJyxcbiAgICAgICAgQXBwbGljYXRpb25Mb2dMZXZlbDogcHJvcHM/LnByb3ZpZGVyTG9nTGV2ZWwgPz8gJ0ZBVEFMJyxcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIGlmIChwcm9wcz8ubG9nUmV0ZW50aW9uKSB7XG4gICAgICBjb25zdCBsb2dHcm91cCA9IG5ldyBDZm5SZXNvdXJjZSh0aGlzLCAnTG9nR3JvdXAnLCB7XG4gICAgICAgIHR5cGU6ICdBV1M6OkxvZ3M6OkxvZ0dyb3VwJyxcbiAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgIExvZ0dyb3VwTmFtZTogYC9hd3MvbGFtYmRhLyR7aWR9YCxcbiAgICAgICAgICBSZXRlbnRpb25JbkRheXM6IHByb3BzLmxvZ1JldGVudGlvbixcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBmdW5jdGlvblByb3BlcnRpZXMuTG9nZ2luZ0NvbmZpZy5Mb2dHcm91cCA9IGxvZ0dyb3VwLnJlZjtcbiAgICB9XG5cbiAgICB0aGlzLmhhbmRsZXIgPSBuZXcgQ2ZuUmVzb3VyY2UodGhpcywgJ0hhbmRsZXInLCB7XG4gICAgICB0eXBlOiAnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJyxcbiAgICAgIHByb3BlcnRpZXM6IGZ1bmN0aW9uUHJvcGVydGllcyxcbiAgICB9KTtcblxuICAgIHRoaXMucm9sZUFybiA9IHJvbGUuZ2V0QXR0KCdBcm4nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgQVJOIG9mIHRoZSBsYW1iZGEgZnVuY3Rpb24gd2hpY2ggY2FuIGJlIHVzZWRcbiAgICogYXMgYSBzZXJ2aWNlVG9rZW4gdG8gYSBDdXN0b21SZXNvdXJjZVxuICAgKi9cbiAgQG1lbW9pemVkR2V0dGVyXG4gIHB1YmxpYyBnZXQgc2VydmljZVRva2VuKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIFRva2VuLmFzU3RyaW5nKHRoaXMuaGFuZGxlci5nZXRBdHQoJ0FybicpKTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRQb2xpY2llcyhwb2xpY2llczogYW55W10pOiB2b2lkIHtcbiAgICB0aGlzLnBvbGljaWVzLnB1c2goLi4ucG9saWNpZXMpO1xuICB9XG59XG5cbmludGVyZmFjZSBTaW5nbGV0b25GdW5jdGlvblByb3BzIGV4dGVuZHMgTGFtYmRhRnVuY3Rpb25Qcm92aWRlclByb3BzIHtcbiAgLyoqXG4gICAqIEEgdW5pcXVlIGlkZW50aWZpZXIgdG8gaWRlbnRpZnkgdGhpcyBsYW1iZGFcbiAgICpcbiAgICogVGhlIGlkZW50aWZpZXIgc2hvdWxkIGJlIHVuaXF1ZSBhY3Jvc3MgYWxsIGN1c3RvbSByZXNvdXJjZSBwcm92aWRlcnMuXG4gICAqIFdlIHJlY29tbWVuZCBnZW5lcmF0aW5nIGEgVVVJRCBwZXIgcHJvdmlkZXIuXG4gICAqL1xuICByZWFkb25seSB1dWlkOiBzdHJpbmc7XG59XG5cbi8qKlxuICogTWltaWMgdGhlIHNpbmdsZXRvbmZ1bmN0aW9uIGNvbnN0cnVjdCBpbiAnQGF3cy1jZGsvYXdzLWxhbWJkYSdcbiAqL1xuY2xhc3MgU2luZ2xldG9uRnVuY3Rpb24gZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICBwdWJsaWMgcmVhZG9ubHkgc2VydmljZVRva2VuOiBzdHJpbmc7XG5cbiAgcHVibGljIHJlYWRvbmx5IGxhbWJkYUZ1bmN0aW9uOiBMYW1iZGFGdW5jdGlvblByb3ZpZGVyO1xuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogU2luZ2xldG9uRnVuY3Rpb25Qcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG4gICAgdGhpcy5sYW1iZGFGdW5jdGlvbiA9IHRoaXMuZW5zdXJlRnVuY3Rpb24ocHJvcHMpO1xuICAgIHRoaXMuc2VydmljZVRva2VuID0gdGhpcy5sYW1iZGFGdW5jdGlvbi5zZXJ2aWNlVG9rZW47XG4gIH1cblxuICBwcml2YXRlIGVuc3VyZUZ1bmN0aW9uKHByb3BzOiBTaW5nbGV0b25GdW5jdGlvblByb3BzKTogTGFtYmRhRnVuY3Rpb25Qcm92aWRlciB7XG4gICAgY29uc3QgY29uc3RydWN0TmFtZSA9ICdTaW5nbGV0b25GdW5jdGlvbicgKyBzbHVnaWZ5KHByb3BzLnV1aWQpO1xuICAgIGNvbnN0IGV4aXN0aW5nID0gU3RhY2sub2YodGhpcykubm9kZS50cnlGaW5kQ2hpbGQoY29uc3RydWN0TmFtZSk7XG4gICAgaWYgKGV4aXN0aW5nKSB7XG4gICAgICByZXR1cm4gZXhpc3RpbmcgYXMgTGFtYmRhRnVuY3Rpb25Qcm92aWRlcjtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IExhbWJkYUZ1bmN0aW9uUHJvdmlkZXIoU3RhY2sub2YodGhpcyksIGNvbnN0cnVjdE5hbWUsIHtcbiAgICAgIGhhbmRsZXI6IHByb3BzLmhhbmRsZXIsXG4gICAgICBsb2dSZXRlbnRpb246IHByb3BzLmxvZ1JldGVudGlvbixcbiAgICAgIHByb3ZpZGVyTG9nTGV2ZWw6IHByb3BzLnByb3ZpZGVyTG9nTGV2ZWwsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGFuIElBTSBwb2xpY3kgc3RhdGVtZW50IHRvIHRoZSBpbmxpbmUgcG9saWN5IG9mIHRoZVxuICAgKiBsYW1iZGFzIGZ1bmN0aW9uJ3Mgcm9sZVxuICAgKlxuICAgKiAqKlBsZWFzZSBub3RlKio6IHRoaXMgaXMgYSBkaXJlY3QgSUFNIEpTT04gcG9saWN5IGJsb2IsICpub3QqIGEgYGlhbS5Qb2xpY3lTdGF0ZW1lbnRgXG4gICAqIG9iamVjdCBsaWtlIHlvdSB3aWxsIHNlZSBpbiB0aGUgcmVzdCBvZiB0aGUgQ0RLLlxuICAgKlxuICAgKlxuICAgKiBzaW5nbGV0b24uYWRkVG9Sb2xlUG9saWN5KHtcbiAgICogICBFZmZlY3Q6ICdBbGxvdycsXG4gICAqICAgQWN0aW9uOiAnczM6R2V0T2JqZWN0JyxcbiAgICogICBSZXNvdXJjZXM6ICcqJyxcbiAgICogfSk7XG4gICAqL1xuICBwdWJsaWMgYWRkVG9Sb2xlUG9saWN5KHN0YXRlbWVudDogYW55KTogdm9pZCB7XG4gICAgdGhpcy5sYW1iZGFGdW5jdGlvbi5hZGRQb2xpY2llcyhbc3RhdGVtZW50XSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgcG9saWN5IHN0YXRlbWVudCBmcm9tIGEgc3BlY2lmaWMgYXBpIGNhbGxcbiAgICovXG4gIHB1YmxpYyBhZGRQb2xpY3lTdGF0ZW1lbnRGcm9tU2RrQ2FsbChzZXJ2aWNlOiBzdHJpbmcsIGFwaTogc3RyaW5nLCByZXNvdXJjZXM/OiBzdHJpbmdbXSk6IHZvaWQge1xuICAgIHRoaXMubGFtYmRhRnVuY3Rpb24uYWRkUG9saWNpZXMoW3tcbiAgICAgIEFjdGlvbjogW2F3c1Nka1RvSWFtQWN0aW9uKHNlcnZpY2UsIGFwaSldLFxuICAgICAgRWZmZWN0OiAnQWxsb3cnLFxuICAgICAgUmVzb3VyY2U6IHJlc291cmNlcyB8fCBbJyonXSxcbiAgICB9XSk7XG4gIH1cbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBkZWZpbmluZyBhbiBBc3NlcnRpb25zUHJvdmlkZXJcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBc3NlcnRpb25zUHJvdmlkZXJQcm9wcyBleHRlbmRzIExhbWJkYUZ1bmN0aW9uUHJvdmlkZXJQcm9wcyB7XG4gIC8qKlxuICAgKiBUaGlzIGRldGVybWluZXMgdGhlIHVuaXF1ZW5lc3Mgb2YgZWFjaCBBc3NlcnRpb25zUHJvdmlkZXIuXG4gICAqIFlvdSBzaG91bGQgb25seSBuZWVkIHRvIHByb3ZpZGUgc29tZXRoaW5nIGRpZmZlcmVudCBoZXJlIGlmIHlvdVxuICAgKiBfa25vd18gdGhhdCB5b3UgbmVlZCBhIHNlcGFyYXRlIHByb3ZpZGVyXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdGhlIGRlZmF1bHQgdXVpZCBpcyB1c2VkXG4gICAqL1xuICByZWFkb25seSB1dWlkPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgYW4gYXNzZXJ0aW9ucyBwcm92aWRlci4gVGhlIGNyZWF0ZXMgYSBzaW5nbGV0b25lXG4gKiBMYW1iZGEgRnVuY3Rpb24gdGhhdCB3aWxsIGNyZWF0ZSBhIHNpbmdsZSBmdW5jdGlvbiBwZXIgc3RhY2tcbiAqIHRoYXQgc2VydmVzIGFzIHRoZSBjdXN0b20gcmVzb3VyY2UgcHJvdmlkZXIgZm9yIHRoZSB2YXJpb3VzXG4gKiBhc3NlcnRpb24gcHJvdmlkZXJzXG4gKi9cbmV4cG9ydCBjbGFzcyBBc3NlcnRpb25zUHJvdmlkZXIgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICAvKipcbiAgICogVGhlIEFSTiBvZiB0aGUgbGFtYmRhIGZ1bmN0aW9uIHdoaWNoIGNhbiBiZSB1c2VkXG4gICAqIGFzIGEgc2VydmljZVRva2VuIHRvIGEgQ3VzdG9tUmVzb3VyY2VcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBzZXJ2aWNlVG9rZW46IHN0cmluZztcblxuICAvKipcbiAgICogQSByZWZlcmVuY2UgdG8gdGhlIHByb3ZpZGVyIExhbWJkYSBGdW5jdGlvblxuICAgKiBleGVjdXRpb24gUm9sZSBBUk5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBoYW5kbGVyUm9sZUFybjogUmVmZXJlbmNlO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgaGFuZGxlcjogU2luZ2xldG9uRnVuY3Rpb247XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM/OiBBc3NlcnRpb25zUHJvdmlkZXJQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICB0aGlzLmhhbmRsZXIgPSBuZXcgU2luZ2xldG9uRnVuY3Rpb24odGhpcywgJ0Fzc2VydGlvbnNQcm92aWRlcicsIHtcbiAgICAgIGhhbmRsZXI6IHByb3BzPy5oYW5kbGVyLFxuICAgICAgdXVpZDogcHJvcHM/LnV1aWQgPz8gJzE0ODg1NDFhLTdiMjMtNDY2NC04MWI2LTliNDQwODA3NmI4MScsXG4gICAgICBsb2dSZXRlbnRpb246IHByb3BzPy5sb2dSZXRlbnRpb24sXG4gICAgICBwcm92aWRlckxvZ0xldmVsOiBwcm9wcz8ucHJvdmlkZXJMb2dMZXZlbCxcbiAgICB9KTtcblxuICAgIHRoaXMuaGFuZGxlclJvbGVBcm4gPSB0aGlzLmhhbmRsZXIubGFtYmRhRnVuY3Rpb24ucm9sZUFybjtcblxuICAgIHRoaXMuc2VydmljZVRva2VuID0gdGhpcy5oYW5kbGVyLnNlcnZpY2VUb2tlbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbmNvZGUgYW4gb2JqZWN0IHNvIGl0IGNhbiBiZSBwYXNzZWRcbiAgICogYXMgY3VzdG9tIHJlc291cmNlIHBhcmFtZXRlcnMuIEN1c3RvbSByZXNvdXJjZXMgd2lsbCBjb252ZXJ0XG4gICAqIGFsbCBpbnB1dCBwYXJhbWV0ZXJzIHRvIHN0cmluZ3Mgc28gd2UgZW5jb2RlIG5vbi1zdHJpbmdzIGhlcmVcbiAgICogc28gd2UgY2FuIHRoZW4gZGVjb2RlIHRoZW0gY29ycmVjdGx5IGluIHRoZSBwcm92aWRlciBmdW5jdGlvblxuICAgKi9cbiAgcHVibGljIGVuY29kZShvYmo6IGFueSk6IGFueSB7XG4gICAgaWYgKCFvYmopIHtcbiAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuICAgIHJldHVybiBPYmplY3QuZnJvbUVudHJpZXMoT2JqZWN0LmVudHJpZXMob2JqKS5tYXAoKFtrZXksIHZhbHVlXSkgPT4gW2tleSwgZW5jb2RlVmFsdWUodmFsdWUpXSkpO1xuXG4gICAgZnVuY3Rpb24gZW5jb2RlVmFsdWUodmFsdWU6IGFueSk6IGFueSB7XG4gICAgICBpZiAoQXJyYXlCdWZmZXIuaXNWaWV3KHZhbHVlKSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICR0eXBlOiAnQXJyYXlCdWZmZXJWaWV3JyxcbiAgICAgICAgICBzdHJpbmc6IG5ldyBUZXh0RGVjb2RlcigpLmRlY29kZSh2YWx1ZSBhcyBVaW50OEFycmF5KSxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgcG9saWN5IHN0YXRlbWVudCBmcm9tIGEgc3BlY2lmaWMgYXBpIGNhbGxcbiAgICovXG4gIHB1YmxpYyBhZGRQb2xpY3lTdGF0ZW1lbnRGcm9tU2RrQ2FsbChzZXJ2aWNlOiBzdHJpbmcsIGFwaTogc3RyaW5nLCByZXNvdXJjZXM/OiBzdHJpbmdbXSk6IHZvaWQge1xuICAgIHRoaXMuaGFuZGxlci5hZGRQb2xpY3lTdGF0ZW1lbnRGcm9tU2RrQ2FsbChzZXJ2aWNlLCBhcGksIHJlc291cmNlcyk7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGFuIElBTSBwb2xpY3kgc3RhdGVtZW50IHRvIHRoZSBpbmxpbmUgcG9saWN5IG9mIHRoZVxuICAgKiBsYW1iZGFzIGZ1bmN0aW9uJ3Mgcm9sZVxuICAgKlxuICAgKiAqKlBsZWFzZSBub3RlKio6IHRoaXMgaXMgYSBkaXJlY3QgSUFNIEpTT04gcG9saWN5IGJsb2IsICpub3QqIGEgYGlhbS5Qb2xpY3lTdGF0ZW1lbnRgXG4gICAqIG9iamVjdCBsaWtlIHlvdSB3aWxsIHNlZSBpbiB0aGUgcmVzdCBvZiB0aGUgQ0RLLlxuICAgKlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBkZWNsYXJlIGNvbnN0IHByb3ZpZGVyOiBBc3NlcnRpb25zUHJvdmlkZXI7XG4gICAqIHByb3ZpZGVyLmFkZFRvUm9sZVBvbGljeSh7XG4gICAqICAgRWZmZWN0OiAnQWxsb3cnLFxuICAgKiAgIEFjdGlvbjogWydzMzpHZXRPYmplY3QnXSxcbiAgICogICBSZXNvdXJjZTogWycqJ10sXG4gICAqIH0pO1xuICAgKi9cbiAgcHVibGljIGFkZFRvUm9sZVBvbGljeShzdGF0ZW1lbnQ6IGFueSk6IHZvaWQge1xuICAgIHRoaXMuaGFuZGxlci5hZGRUb1JvbGVQb2xpY3koc3RhdGVtZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudCBhIHByaW5jaXBhbCBhY2Nlc3MgdG8gaW52b2tlIHRoZSBhc3NlcnRpb24gcHJvdmlkZXJcbiAgICogbGFtYmRhIGZ1bmN0aW9uXG4gICAqIFtkaXNhYmxlLWF3c2xpbnQ6bm8tZ3JhbnRzXVxuICAgKlxuICAgKiBAcGFyYW0gcHJpbmNpcGFsQXJuIHRoZSBBUk4gb2YgdGhlIHByaW5jaXBhbCB0aGF0IHNob3VsZCBiZSBnaXZlblxuICAgKiAgcGVybWlzc2lvbiB0byBpbnZva2UgdGhlIGFzc2VydGlvbiBwcm92aWRlclxuICAgKi9cbiAgcHVibGljIGdyYW50SW52b2tlKHByaW5jaXBhbEFybjogc3RyaW5nKTogdm9pZCB7XG4gICAgbmV3IENmblJlc291cmNlKHRoaXMsICdJbnZva2UnLCB7XG4gICAgICB0eXBlOiAnQVdTOjpMYW1iZGE6OlBlcm1pc3Npb24nLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBBY3Rpb246ICdsYW1iZGE6SW52b2tlRnVuY3Rpb24nLFxuICAgICAgICBGdW5jdGlvbk5hbWU6IHRoaXMuc2VydmljZVRva2VuLFxuICAgICAgICBQcmluY2lwYWw6IHByaW5jaXBhbEFybixcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2x1Z2lmeSh4OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4geC5yZXBsYWNlKC9bXmEtekEtWjAtOV0vZywgJycpO1xufVxuIl19