cdk-secure-string-parameter
Version:
SecureStringParameter Custom Resource for CDK. Enables storing encrypted secrets in version control and using those values in creating SSM SecureString Parameters
147 lines • 22.8 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SecureStringParameter = exports.ValueType = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const aws_cdk_lib_1 = require("aws-cdk-lib");
const aws_iam_1 = require("aws-cdk-lib/aws-iam");
const aws_kms_1 = require("aws-cdk-lib/aws-kms");
const aws_logs_1 = require("aws-cdk-lib/aws-logs");
const aws_ssm_1 = require("aws-cdk-lib/aws-ssm");
const custom_resources_1 = require("aws-cdk-lib/custom-resources");
const uuid = require("uuid");
const secure_string_parameter_handler_function_1 = require("./lambda/secure-string-parameter-handler-function");
const util_1 = require("./util");
/**
* The type of the stringValue.
*/
var ValueType;
(function (ValueType) {
/**
* Indicates that the value of this parameter is encrypted with a kms key.
*/
ValueType["ENCRYPTED"] = "encrypted";
/**
* Indicates that the value of this parameter is in plain text.
*/
ValueType["PLAINTEXT"] = "plaintext";
})(ValueType || (exports.ValueType = ValueType = {}));
/**
* Creates a new SecureString SSM Parameter.
*
* If the valueType property is set to `encrypted`, the actual SSM SecureString Parameter will be created with a decrypted value from the stringValue property.
* @resource Custom::SecureStringParameter
*/
class SecureStringParameter extends aws_cdk_lib_1.Resource {
constructor(scope, id, props) {
super(scope, id);
this.tags = new aws_cdk_lib_1.TagManager(aws_cdk_lib_1.TagType.MAP, 'Custom::SecureStringParameter');
// We need to manually add tags from StackProps.
// Tags added with Tags.of(scope).add() are handled automatically.
aws_cdk_lib_1.Stack.of(this).tags.renderTags()?.forEach((tag) => {
this.tags.setTag(tag.Key, tag.Value);
});
this.valueType = props.valueType;
this.encryptionKey = props.encryptionKey;
this.stringValue = props.stringValue;
this.parameterType = aws_ssm_1.ParameterType.SECURE_STRING;
this.parameterName = props.parameterName ?? uuid.v4();
this.parameterArn = (0, util_1.arnForParameterName)(this, this.parameterName, { simpleName: props.simpleName });
this.eventHandler = this.getOrCreateHandler();
if (this.encryptionKey) {
const isIAlias = (key) => 'aliasTargetKey' in key;
const isAlias = (key) => key instanceof aws_kms_1.Alias;
const getKey = (key) => {
if (isAlias(key))
return key.aliasTargetKey;
if (isIAlias(key))
return aws_kms_1.Key.fromLookup(this, 'key', { aliasName: key.aliasName });
return key;
};
const key = getKey(this.encryptionKey);
this.eventHandler.addToRolePolicy(new aws_iam_1.PolicyStatement({
effect: aws_iam_1.Effect.ALLOW,
resources: [key.keyArn],
actions: ['kms:Decrypt', 'kms:Encrypt'],
}));
}
this.provider = this.getOrCreateProvider();
const properties = {
allowedPattern: props.allowedPattern,
description: props.description,
encryptionKey: this.encryptionKey?.keyId,
name: this.parameterName,
tags: this.tags.renderedTags,
tier: props.tier,
value: this.stringValue,
valueType: this.valueType,
};
new aws_cdk_lib_1.CustomResource(this, id, {
serviceToken: this.provider.serviceToken,
resourceType: 'Custom::SecureStringParameter',
removalPolicy: props.removalPolicy,
properties,
pascalCaseProperties: true,
});
}
grantRead(grantee) {
return this.asStringParameter().grantRead(grantee);
}
grantWrite(grantee) {
return this.asStringParameter().grantWrite(grantee);
}
/**
* Returns this parameter as a native StringParameter.
*/
asStringParameter() {
if (!this.stringParameter) {
this.stringParameter = aws_ssm_1.StringParameter.fromSecureStringParameterAttributes(this, 'StringParameter', {
parameterName: this.parameterName,
});
}
return this.stringParameter;
}
getOrCreateHandler() {
const id = 'SecureStringParameterCustomResourceHandler';
const stack = aws_cdk_lib_1.Stack.of(this);
const existing = stack.node.tryFindChild(id);
if (existing)
return existing;
const eventHandler = new secure_string_parameter_handler_function_1.SecureStringParameterHandlerFunction(stack, id, {
initialPolicy: [new aws_iam_1.PolicyStatement({
effect: aws_iam_1.Effect.ALLOW,
resources: ['*'], // Must allow * to handle parameter name changes
actions: [
'ssm:PutParameter',
'ssm:DeleteParameter',
'ssm:GetParameters',
'ssm:ListTagsForResource',
'ssm:AddTagsToResource',
'ssm:RemoveTagsFromResource',
],
})],
logGroup: new aws_logs_1.LogGroup(this, 'SecureStringParameterHandlerLogGroup', {
retention: aws_logs_1.RetentionDays.ONE_WEEK,
}),
});
return eventHandler;
}
getOrCreateProvider() {
const id = 'SecureStringParameterCustomResourceProvider';
const stack = aws_cdk_lib_1.Stack.of(this);
const existing = stack.node.tryFindChild(id);
if (existing)
return existing;
const provider = new custom_resources_1.Provider(stack, id, {
onEventHandler: this.eventHandler,
logGroup: new aws_logs_1.LogGroup(this, 'SecureStringParameterProviderLogGroup', {
retention: aws_logs_1.RetentionDays.ONE_WEEK,
}),
});
return provider;
}
}
exports.SecureStringParameter = SecureStringParameter;
_a = JSII_RTTI_SYMBOL_1;
SecureStringParameter[_a] = { fqn: "cdk-secure-string-parameter.SecureStringParameter", version: "0.0.20" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VjdXJlLXN0cmluZy1wYXJhbWV0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc2VjdXJlLXN0cmluZy1wYXJhbWV0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw2Q0FBNkc7QUFDN0csaURBQWlGO0FBQ2pGLGlEQUErRDtBQUUvRCxtREFBK0Q7QUFDL0QsaURBQTRIO0FBQzVILG1FQUF3RDtBQUV4RCw2QkFBNkI7QUFDN0IsZ0hBQXlHO0FBRXpHLGlDQUE2QztBQUU3Qzs7R0FFRztBQUNILElBQVksU0FTWDtBQVRELFdBQVksU0FBUztJQUNuQjs7T0FFRztJQUNILG9DQUF1QixDQUFBO0lBQ3ZCOztPQUVHO0lBQ0gsb0NBQXVCLENBQUE7QUFDekIsQ0FBQyxFQVRXLFNBQVMseUJBQVQsU0FBUyxRQVNwQjtBQTRERDs7Ozs7R0FLRztBQUNILE1BQWEscUJBQXNCLFNBQVEsc0JBQVE7SUFvQmpELFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBaUM7UUFDekUsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksd0JBQVUsQ0FBQyxxQkFBTyxDQUFDLEdBQUcsRUFBRSwrQkFBK0IsQ0FBQyxDQUFDO1FBQ3pFLGdEQUFnRDtRQUNoRCxrRUFBa0U7UUFDbEUsbUJBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxFQUFFLE9BQU8sQ0FBQyxDQUFDLEdBQWEsRUFBRSxFQUFFO1lBQzFELElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3ZDLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDO1FBQ2pDLElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSyxD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LENBQUM7UUFDekQsTUFBTSxLQUFLLEdBQUcsbUJBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDN0IsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDN0MsSUFBSSxRQUFRO1lBQUUsT0FBTyxRQUFvQixDQUFDO1FBQzFDLE1BQU0sUUFBUSxHQUFHLElBQUksMkJBQVEsQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFO1lBQ3ZDLGNBQWMsRUFBRSxJQUFJLENBQUMsWUFBWTtZQUNqQyxRQUFRLEVBQUUsSUFBSSxtQkFBUSxDQUFDLElBQUksRUFBRSx1Q0FBdUMsRUFBRTtnQkFDcEUsU0FBUyxFQUFFLHdCQUFhLENBQUMsUUFBUTthQUNsQyxDQUFDO1NBQ0gsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxRQUFRLENBQUM7SUFDbEIsQ0FBQzs7QUF4SUgsc0RBeUlDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ3VzdG9tUmVzb3VyY2UsIElUYWdnYWJsZSwgUmVtb3ZhbFBvbGljeSwgUmVzb3VyY2UsIFN0YWNrLCBUYWdNYW5hZ2VyLCBUYWdUeXBlIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgRWZmZWN0LCBHcmFudCwgSUdyYW50YWJsZSwgUG9saWN5U3RhdGVtZW50IH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWlhbSc7XG5pbXBvcnQgeyBBbGlhcywgSUFsaWFzLCBJS2V5LCBLZXkgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3Mta21zJztcbmltcG9ydCB7IElGdW5jdGlvbiB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1sYW1iZGEnO1xuaW1wb3J0IHsgTG9nR3JvdXAsIFJldGVudGlvbkRheXMgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbG9ncyc7XG5pbXBvcnQgeyBJU3RyaW5nUGFyYW1ldGVyLCBQYXJhbWV0ZXJEYXRhVHlwZSwgUGFyYW1ldGVyT3B0aW9ucywgUGFyYW1ldGVyVHlwZSwgU3RyaW5nUGFyYW1ldGVyIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLXNzbSc7XG5pbXBvcnQgeyBQcm92aWRlciB9IGZyb20gJ2F3cy1jZGstbGliL2N1c3RvbS1yZXNvdXJjZXMnO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgKiBhcyB1dWlkIGZyb20gJ3V1aWQnO1xuaW1wb3J0IHsgU2VjdXJlU3RyaW5nUGFyYW1ldGVySGFuZGxlckZ1bmN0aW9uIH0gZnJvbSAnLi9sYW1iZGEvc2VjdXJlLXN0cmluZy1wYXJhbWV0ZXItaGFuZGxlci1mdW5jdGlvbic7XG5pbXBvcnQgeyBTZWN1cmVTdHJpbmdQYXJhbWV0ZXJSZXNvdXJjZVByb3BlcnRpZXMgfSBmcm9tICcuL2xhbWJkYS9zZWN1cmUtc3RyaW5nLXBhcmFtZXRlci1oYW5kbGVyLmxhbWJkYSc7XG5pbXBvcnQgeyBhcm5Gb3JQYXJhbWV0ZXJOYW1lIH0gZnJvbSAnLi91dGlsJztcblxuLyoqXG4gKiBUaGUgdHlwZSBvZiB0aGUgc3RyaW5nVmFsdWUuXG4gKi9cbmV4cG9ydCBlbnVtIFZhbHVlVHlwZSB7XG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgdGhhdCB0aGUgdmFsdWUgb2YgdGhpcyBwYXJhbWV0ZXIgaXMgZW5jcnlwdGVkIHdpdGggYSBrbXMga2V5LlxuICAgKi9cbiAgRU5DUllQVEVEID0gJ2VuY3J5cHRlZCcsXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgdGhhdCB0aGUgdmFsdWUgb2YgdGhpcyBwYXJhbWV0ZXIgaXMgaW4gcGxhaW4gdGV4dC5cbiAgICovXG4gIFBMQUlOVEVYVCA9ICdwbGFpbnRleHQnLFxufVxuXG5leHBvcnQgdHlwZSBDYW1lbENhc2U8VD4gPSB7IFtLIGluIGtleW9mIFQgYXMgVW5jYXBpdGFsaXplPEsgJiBzdHJpbmc+XTogVFtLXTsgfTtcblxuaW50ZXJmYWNlIFN0YWNrVGFnIHtcbiAgS2V5OiBzdHJpbmc7XG4gIFZhbHVlOiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBCYXNlUHJvcHMgZXh0ZW5kcyBQYXJhbWV0ZXJPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSB2YWx1ZSBvZiB0aGUgcGFyYW1ldGVyLiBJdCBtYXkgbm90IHJlZmVyZW5jZSBhbm90aGVyIHBhcmFtZXRlciBhbmQgYGB7e319YGAgY2Fubm90IGJlIHVzZWQgaW4gdGhlIHZhbHVlLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RyaW5nVmFsdWU6IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBkYXRhIHR5cGUgb2YgdGhlIHBhcmFtZXRlciB2YWx1ZS4gT25seSBgdGV4dGAgaXMgYWxsb3dlZC5cbiAgICogQGRlZmF1bHQgUGFyYW1ldGVyRGF0YVR5cGUuVEVYVFxuICAgKi9cbiAgcmVhZG9ubHkgZGF0YVR5cGU/OiBQYXJhbWV0ZXJEYXRhVHlwZS5URVhUO1xuICAvKipcbiAgICogVGhlIHR5cGUgb2YgdGhlIHBhcmFtZXRlci4gT25seSBgU2VjdXJlU3RyaW5nYCBpcyBhbGxvd2VkLlxuICAgKiBAZGVmYXVsdCBQYXJhbWV0ZXJUeXBlLlNFQ1VSRV9TVFJJTkdcbiAgICovXG4gIHJlYWRvbmx5IHR5cGU/OiBQYXJhbWV0ZXJUeXBlLlNFQ1VSRV9TVFJJTkc7XG4gIC8qKlxuICAgKiBQb2xpY3kgdG8gYXBwbHkgd2hlbiB0aGUgcGFyYW1ldGVyIGlzIHJlbW92ZWQgZnJvbSB0aGlzIHN0YWNrLlxuICAgKiBAZGVmYXVsdCBSZW1vdmFsUG9saWN5LkRFU1RST1lcbiAgICovXG4gIHJlYWRvbmx5IHJlbW92YWxQb2xpY3k/OiBSZW1vdmFsUG9saWN5O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEVuY3J5cHRlZFNlY3VyZVN0cmluZ1BhcmFtZXRlclByb3BzIGV4dGVuZHMgQmFzZVByb3BzIHtcbiAgLyoqXG4gICAqIFRoZSBlbmNyeXB0aW9uIGtleSB0aGF0IGlzIHVzZWQgdG8gZW5jcnlwdCB0aGlzIHBhcmFtZXRlci5cbiAgICogKi9cbiAgcmVhZG9ubHkgZW5jcnlwdGlvbktleTogSUtleTtcbiAgLyoqXG4gICAqIFRoZSB0eXBlIG9mIHRoZSBzdHJpbmdWYWx1ZS4gVXNlIHR5cGUgYGVuY3J5cHRlZGAgaWYgdGhlIHZhbHVlIGlzIGVuY3J5cHRlZCB3aXRoIGEga21zIGtleS5cbiAgICpcbiAgICogKipXQVJOSU5HOioqIElmIHlvdSB1c2UgYHBsYWludGV4dGAsIHRoZSB1bmVjcnlwdGVkIHZhbHVlIG9mIHRoZSBwYXJhbWV0ZXIgaXMgdmlzaWJsZSB0byBhbnlvbmUgd2hvIGhhcyBhY2Nlc3MgdG8gY2xvdWRmb3JtYXRpb24gb3IgZGVwbG95IGFydGlmYWN0cy5cbiAgICovXG4gIHJlYWRvbmx5IHZhbHVlVHlwZTogVmFsdWVUeXBlLkVOQ1JZUFRFRDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQbGFpblRleHRTZWN1cmVTdHJpbmdQYXJhbWV0ZXJQcm9wcyBleHRlbmRzIEJhc2VQcm9wcyB7XG4gIC8qKlxuICAgKiBUaGUgZW5jcnlwdGlvbiBrZXkgdGhhdCBpcyB1c2VkIHRvIGVuY3J5cHQgdGhpcyBwYXJhbWV0ZXIuXG4gICAqIEBkZWZhdWx0IGFsaWFzL2F3cy9zc21cbiAgICogKi9cbiAgcmVhZG9ubHkgZW5jcnlwdGlvbktleT86IElLZXk7XG4gIC8qKlxuICAgKiBUaGUgdHlwZSBvZiB0aGUgc3RyaW5nVmFsdWUuIFVzZSB0eXBlIGBlbmNyeXB0ZWRgIGlmIHRoZSB2YWx1ZSBpcyBlbmNyeXB0ZWQgd2l0aCBhIGttcyBrZXkuXG4gICAqXG4gICAqICoqV0FSTklORzoqKiBJZiB5b3UgdXNlIGBwbGFpbnRleHRgLCB0aGUgdW5lY3J5cHRlZCB2YWx1ZSBvZiB0aGUgcGFyYW1ldGVyIGlzIHZpc2libGUgdG8gYW55b25lIHdobyBoYXMgYWNjZXNzIHRvIGNsb3VkZm9ybWF0aW9uIG9yIGRlcGxveSBhcnRpZmFjdHMuXG4gICAqL1xuICByZWFkb25seSB2YWx1ZVR5cGU6IFZhbHVlVHlwZS5QTEFJTlRFWFQ7XG59XG5cbmV4cG9ydCB0eXBlIFNlY3VyZVN0cmluZ1BhcmFtZXRlclByb3BzID0gRW5jcnlwdGVkU2VjdXJlU3RyaW5nUGFyYW1ldGVyUHJvcHMgfCBQbGFpblRleHRTZWN1cmVTdHJpbmdQYXJhbWV0ZXJQcm9wcztcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IFNlY3VyZVN0cmluZyBTU00gUGFyYW1ldGVyLlxuICpcbiAqIElmIHRoZSB2YWx1ZVR5cGUgcHJvcGVydHkgaXMgc2V0IHRvIGBlbmNyeXB0ZWRgLCB0aGUgYWN0dWFsIFNTTSBTZWN1cmVTdHJpbmcgUGFyYW1ldGVyIHdpbGwgYmUgY3JlYXRlZCB3aXRoIGEgZGVjcnlwdGVkIHZhbHVlIGZyb20gdGhlIHN0cmluZ1ZhbHVlIHByb3BlcnR5LlxuICogQHJlc291cmNlIEN1c3RvbTo6U2VjdXJlU3RyaW5nUGFyYW1ldGVyXG4gKi9cbmV4cG9ydCBjbGFzcyBTZWN1cmVTdHJpbmdQYXJhbWV0ZXIgZXh0ZW5kcyBSZXNvdXJjZSBpbXBsZW1lbnRzIElTdHJpbmdQYXJhbWV0ZXIsIElUYWdnYWJsZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgZXZlbnRIYW5kbGVyOiBJRnVuY3Rpb247XG4gIHByaXZhdGUgcmVhZG9ubHkgcHJvdmlkZXI6IFByb3ZpZGVyO1xuICBwcml2YXRlIHN0cmluZ1BhcmFtZXRlcj86IElTdHJpbmdQYXJhbWV0ZXI7XG4gIHJlYWRvbmx5IHRhZ3M6IFRhZ01hbmFnZXI7XG4gIC8qKlxuICAgKiBUaGUgZW5jcnlwdGlvbiBrZXkgdGhhdCBpcyB1c2VkIHRvIGVuY3J5cHQgdGhpcyBwYXJhbWV0ZXIuXG4gICAqXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHJlYWRvbmx5IGVuY3J5cHRpb25LZXk/OiBJS2V5O1xuICByZWFkb25seSBwYXJhbWV0ZXJBcm46IHN0cmluZztcbiAgcmVhZG9ubHkgcGFyYW1ldGVyTmFtZTogc3RyaW5nO1xuICByZWFkb25seSBwYXJhbWV0ZXJUeXBlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHN0cmluZ1ZhbHVlOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgdHlwZSBvZiB0aGUgc3RyaW5nVmFsdWUuXG4gICAqL1xuICByZWFkb25seSB2YWx1ZVR5cGU6IFZhbHVlVHlwZTtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogU2VjdXJlU3RyaW5nUGFyYW1ldGVyUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgdGhpcy50YWdzID0gbmV3IFRhZ01hbmFnZXIoVGFnVHlwZS5NQVAsICdDdXN0b206OlNlY3VyZVN0cmluZ1BhcmFtZXRlcicpO1xuICAgIC8vIFdlIG5lZWQgdG8gbWFudWFsbHkgYWRkIHRhZ3MgZnJvbSBTdGFja1Byb3BzLlxuICAgIC8vIFRhZ3MgYWRkZWQgd2l0aCBUYWdzLm9mKHNjb3BlKS5hZGQoKSBhcmUgaGFuZGxlZCBhdXRvbWF0aWNhbGx5LlxuICAgIFN0YWNrLm9mKHRoaXMpLnRhZ3MucmVuZGVyVGFncygpPy5mb3JFYWNoKCh0YWc6IFN0YWNrVGFnKSA9PiB7XG4gICAgICB0aGlzLnRhZ3Muc2V0VGFnKHRhZy5LZXksIHRhZy5WYWx1ZSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnZhbHVlVHlwZSA9IHByb3BzLnZhbHVlVHlwZTtcbiAgICB0aGlzLmVuY3J5cHRpb25LZXkgPSBwcm9wcy5lbmNyeXB0aW9uS2V5O1xuICAgIHRoaXMuc3RyaW5nVmFsdWUgPSBwcm9wcy5zdHJpbmdWYWx1ZTtcbiAgICB0aGlzLnBhcmFtZXRlclR5cGUgPSBQYXJhbWV0ZXJUeXBlLlNFQ1VSRV9TVFJJTkc7XG4gICAgdGhpcy5wYXJhbWV0ZXJOYW1lID0gcHJvcHMucGFyYW1ldGVyTmFtZSA/PyB1dWlkLnY0KCk7XG4gICAgdGhpcy5wYXJhbWV0ZXJBcm4gPSBhcm5Gb3JQYXJhbWV0ZXJOYW1lKHRoaXMsIHRoaXMucGFyYW1ldGVyTmFtZSwgeyBzaW1wbGVOYW1lOiBwcm9wcy5zaW1wbGVOYW1lIH0pO1xuXG4gICAgdGhpcy5ldmVudEhhbmRsZXIgPSB0aGlzLmdldE9yQ3JlYXRlSGFuZGxlcigpO1xuXG4gICAgaWYgKHRoaXMuZW5jcnlwdGlvbktleSkge1xuICAgICAgY29uc3QgaXNJQWxpYXMgPSAoa2V5OiBJS2V5KToga2V5IGlzIElBbGlhcyA9PiAnYWxpYXNUYXJnZXRLZXknIGluIGtleTtcbiAgICAgIGNvbnN0IGlzQWxpYXMgPSAoa2V5OiBJS2V5KToga2V5IGlzIEFsaWFzID0+IGtleSBpbnN0YW5jZW9mIEFsaWFzO1xuICAgICAgY29uc3QgZ2V0S2V5ID0gKGtleTogSUtleSk6IElLZXkgPT4ge1xuICAgICAgICBpZiAoaXNBbGlhcyhrZXkpKSByZXR1cm4ga2V5LmFsaWFzVGFyZ2V0S2V5O1xuICAgICAgICBpZiAoaXNJQWxpYXMoa2V5KSkgcmV0dXJuIEtleS5mcm9tTG9va3VwKHRoaXMsICdrZXknLCB7IGFsaWFzTmFtZToga2V5LmFsaWFzTmFtZSB9KTtcbiAgICAgICAgcmV0dXJuIGtleTtcbiAgICAgIH07XG4gICAgICBjb25zdCBrZXkgPSBnZXRLZXkodGhpcy5lbmNyeXB0aW9uS2V5KTtcbiAgICAgIHRoaXMuZXZlbnRIYW5kbGVyLmFkZFRvUm9sZVBvbGljeShcbiAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgZWZmZWN0OiBFZmZlY3QuQUxMT1csXG4gICAgICAgICAgcmVzb3VyY2VzOiBba2V5LmtleUFybl0sXG4gICAgICAgICAgYWN0aW9uczogWydrbXM6RGVjcnlwdCcsICdrbXM6RW5jcnlwdCddLFxuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdGhpcy5wcm92aWRlciA9IHRoaXMuZ2V0T3JDcmVhdGVQcm92aWRlcigpO1xuXG4gICAgY29uc3QgcHJvcGVydGllczogQ2FtZWxDYXNlPFNlY3VyZVN0cmluZ1BhcmFtZXRlclJlc291cmNlUHJvcGVydGllcz4gPSB7XG4gICAgICBhbGxvd2VkUGF0dGVybjogcHJvcHMuYWxsb3dlZFBhdHRlcm4sXG4gICAgICBkZXNjcmlwdGlvbjogcHJvcHMuZGVzY3JpcHRpb24sXG4gICAgICBlbmNyeXB0aW9uS2V5OiB0aGlzLmVuY3J5cHRpb25LZXk/LmtleUlkLFxuICAgICAgbmFtZTogdGhpcy5wYXJhbWV0ZXJOYW1lLFxuICAgICAgdGFnczogdGhpcy50YWdzLnJlbmRlcmVkVGFncyBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHN0cmluZz4gfCB1bmRlZmluZWQsXG4gICAgICB0aWVyOiBwcm9wcy50aWVyLFxuICAgICAgdmFsdWU6IHRoaXMuc3RyaW5nVmFsdWUsXG4gICAgICB2YWx1ZVR5cGU6IHRoaXMudmFsdWVUeXBlLFxuICAgIH07XG5cbiAgICBuZXcgQ3VzdG9tUmVzb3VyY2UodGhpcywgaWQsIHtcbiAgICAgIHNlcnZpY2VUb2tlbjogdGhpcy5wcm92aWRlci5zZXJ2aWNlVG9rZW4sXG4gICAgICByZXNvdXJjZVR5cGU6ICdDdXN0b206OlNlY3VyZVN0cmluZ1BhcmFtZXRlcicsXG4gICAgICByZW1vdmFsUG9saWN5OiBwcm9wcy5yZW1vdmFsUG9saWN5LFxuICAgICAgcHJvcGVydGllcyxcbiAgICAgIHBhc2NhbENhc2VQcm9wZXJ0aWVzOiB0cnVlLFxuICAgIH0pO1xuICB9XG5cbiAgZ3JhbnRSZWFkKGdyYW50ZWU6IElHcmFudGFibGUpOiBHcmFudCB7XG4gICAgcmV0dXJuIHRoaXMuYXNTdHJpbmdQYXJhbWV0ZXIoKS5ncmFudFJlYWQoZ3JhbnRlZSk7XG4gIH1cblxuICBncmFudFdyaXRlKGdyYW50ZWU6IElHcmFudGFibGUpOiBHcmFudCB7XG4gICAgcmV0dXJuIHRoaXMuYXNTdHJpbmdQYXJhbWV0ZXIoKS5ncmFudFdyaXRlKGdyYW50ZWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhpcyBwYXJhbWV0ZXIgYXMgYSBuYXRpdmUgU3RyaW5nUGFyYW1ldGVyLlxuICAgKi9cbiAgYXNTdHJpbmdQYXJhbWV0ZXIoKTogSVN0cmluZ1BhcmFtZXRlciB7XG4gICAgaWYgKCF0aGlzLnN0cmluZ1BhcmFtZXRlcikge1xuICAgICAgdGhpcy5zdHJpbmdQYXJhbWV0ZXIgPSBTdHJpbmdQYXJhbWV0ZXIuZnJvbVNlY3VyZVN0cmluZ1BhcmFtZXRlckF0dHJpYnV0ZXModGhpcywgJ1N0cmluZ1BhcmFtZXRlcicsIHtcbiAgICAgICAgcGFyYW1ldGVyTmFtZTogdGhpcy5wYXJhbWV0ZXJOYW1lLFxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnN0cmluZ1BhcmFtZXRlcjtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0T3JDcmVhdGVIYW5kbGVyKCk6IElGdW5jdGlvbiB7XG4gICAgY29uc3QgaWQgPSAnU2VjdXJlU3RyaW5nUGFyYW1ldGVyQ3VzdG9tUmVzb3VyY2VIYW5kbGVyJztcbiAgICBjb25zdCBzdGFjayA9IFN0YWNrLm9mKHRoaXMpO1xuICAgIGNvbnN0IGV4aXN0aW5nID0gc3RhY2subm9kZS50cnlGaW5kQ2hpbGQoaWQpO1xuICAgIGlmIChleGlzdGluZykgcmV0dXJuIGV4aXN0aW5nIGFzIElGdW5jdGlvbjtcbiAgICBjb25zdCBldmVudEhhbmRsZXIgPSBuZXcgU2VjdXJlU3RyaW5nUGFyYW1ldGVySGFuZGxlckZ1bmN0aW9uKHN0YWNrLCBpZCwge1xuICAgICAgaW5pdGlhbFBvbGljeTogW25ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICBlZmZlY3Q6IEVmZmVjdC5BTExPVyxcbiAgICAgICAgcmVzb3VyY2VzOiBbJyonXSwgLy8gTXVzdCBhbGxvdyAqIHRvIGhhbmRsZSBwYXJhbWV0ZXIgbmFtZSBjaGFuZ2VzXG4gICAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgICAnc3NtOlB1dFBhcmFtZXRlcicsXG4gICAgICAgICAgJ3NzbTpEZWxldGVQYXJhbWV0ZXInLFxuICAgICAgICAgICdzc206R2V0UGFyYW1ldGVycycsXG4gICAgICAgICAgJ3NzbTpMaXN0VGFnc0ZvclJlc291cmNlJyxcbiAgICAgICAgICAnc3NtOkFkZFRhZ3NUb1Jlc291cmNlJyxcbiAgICAgICAgICAnc3NtOlJlbW92ZVRhZ3NGcm9tUmVzb3VyY2UnLFxuICAgICAgICBdLFxuICAgICAgfSldLFxuICAgICAgbG9nR3JvdXA6IG5ldyBMb2dHcm91cCh0aGlzLCAnU2VjdXJlU3RyaW5nUGFyYW1ldGVySGFuZGxlckxvZ0dyb3VwJywge1xuICAgICAgICByZXRlbnRpb246IFJldGVudGlvbkRheXMuT05FX1dFRUssXG4gICAgICB9KSxcbiAgICB9KTtcbiAgICByZXR1cm4gZXZlbnRIYW5kbGVyO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRPckNyZWF0ZVByb3ZpZGVyKCk6IFByb3ZpZGVyIHtcbiAgICBjb25zdCBpZCA9ICdTZWN1cmVTdHJpbmdQYXJhbWV0ZXJDdXN0b21SZXNvdXJjZVByb3ZpZGVyJztcbiAgICBjb25zdCBzdGFjayA9IFN0YWNrLm9mKHRoaXMpO1xuICAgIGNvbnN0IGV4aXN0aW5nID0gc3RhY2subm9kZS50cnlGaW5kQ2hpbGQoaWQpO1xuICAgIGlmIChleGlzdGluZykgcmV0dXJuIGV4aXN0aW5nIGFzIFByb3ZpZGVyO1xuICAgIGNvbnN0IHByb3ZpZGVyID0gbmV3IFByb3ZpZGVyKHN0YWNrLCBpZCwge1xuICAgICAgb25FdmVudEhhbmRsZXI6IHRoaXMuZXZlbnRIYW5kbGVyLFxuICAgICAgbG9nR3JvdXA6IG5ldyBMb2dHcm91cCh0aGlzLCAnU2VjdXJlU3RyaW5nUGFyYW1ldGVyUHJvdmlkZXJMb2dHcm91cCcsIHtcbiAgICAgICAgcmV0ZW50aW9uOiBSZXRlbnRpb25EYXlzLk9ORV9XRUVLLFxuICAgICAgfSksXG4gICAgfSk7XG4gICAgcmV0dXJuIHByb3ZpZGVyO1xuICB9XG59XG4iXX0=