UNPKG

@aws-cdk/integ-tests-alpha

Version:

CDK Integration Testing Constructs

338 lines 35 kB
"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