UNPKG

@renovosolutions/cdk-library-crowdstrike-ingestion

Version:

A CDK library to ease repetetive construct creation for CrowdStrike data ingestion

157 lines 25.6 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.CrowdStrikeBucket = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const aws_cdk_lib_1 = require("aws-cdk-lib"); ; /** * A construct that creates an S3 bucket for CrowdStrike data ingestion, * along with an SQS queue for notifications, an IAM role for access, * and optionally a KMS key for encryption. */ class CrowdStrikeBucket extends aws_cdk_lib_1.aws_s3.Bucket { /** * Constructs a new CrowdStrikeBucket. * * @param scope The scope in which this construct is defined. * @param id The scoped construct ID. * @param props The properties for the bucket, queue, role, and optional KMS key. */ constructor(scope, id, props) { super(scope, id, { encryption: aws_cdk_lib_1.aws_s3.BucketEncryption.S3_MANAGED, blockPublicAccess: aws_cdk_lib_1.aws_s3.BlockPublicAccess.BLOCK_ALL, enforceSSL: true, versioned: true, removalPolicy: aws_cdk_lib_1.RemovalPolicy.RETAIN_ON_UPDATE_OR_DELETE, ...props, }); /** * If we have an orgId, grant bucket write access to all accounts in the organization. * This is useful for allowing multiple accounts in an organization to write to the same bucket. */ if (props.orgId) { this.grantWrite(new aws_cdk_lib_1.aws_iam.OrganizationPrincipal(props.orgId)); } // If a logging bucket source name is provided, add a policy to allow that bucket to write logs to this bucket. if (props.loggingBucketSourceName) { this.addToResourcePolicy(new aws_cdk_lib_1.aws_iam.PolicyStatement({ effect: aws_cdk_lib_1.aws_iam.Effect.ALLOW, actions: ['s3:PutObject'], resources: [this.arnForObjects('*')], principals: [new aws_cdk_lib_1.aws_iam.ServicePrincipal('logging.s3.amazonaws.com')], conditions: { ArnLike: { 'aws:SourceArn': `arn:aws:s3:::${props.loggingBucketSourceName}`, }, StringEquals: { 'aws:SourceAccount': aws_cdk_lib_1.Stack.of(this).account, }, }, })); } /** * Create an SQS queue for notifications. * If a queueName is provided, use it; otherwise, generate a default name based on the bucket name. */ this.queue = new aws_cdk_lib_1.aws_sqs.Queue(this, 'Queue', { queueName: props.queueProps?.queueName || `${this.bucketName}-queue`, enforceSSL: true, deadLetterQueue: { maxReceiveCount: 5, queue: new aws_cdk_lib_1.aws_sqs.Queue(this, 'DLQ', { queueName: `${this.bucketName}-dlq`, enforceSSL: true, }), }, ...props.queueProps, }); // Add a notification for bucket object creation events to the SQS queue. this.addEventNotification(aws_cdk_lib_1.aws_s3.EventType.OBJECT_CREATED, new aws_cdk_lib_1.aws_s3_notifications.SqsDestination(this.queue)); /** * Determine the principal for CrowdStrike. * If roleProps are provided, use the assumedBy property from there. * Otherwise, create a CrowdStrike principal using the role ARN and external ID from SSM parameters. */ let crowdStrikePrincipal; if (props.roleProps) { crowdStrikePrincipal = props.roleProps.assumedBy; } else if (props.crowdStrikeRoleArn && props.crowdStrikeExternalIdParameterArn) { const crowdStrikeRoleArn = props.crowdStrikeRoleArn; const crowdStrikeExternalId = aws_cdk_lib_1.aws_ssm.StringParameter.fromStringParameterArn(this, 'CrowdStrikeExternalIdParam', props.crowdStrikeExternalIdParameterArn).stringValue; crowdStrikePrincipal = new aws_cdk_lib_1.aws_iam.PrincipalWithConditions(new aws_cdk_lib_1.aws_iam.ArnPrincipal(crowdStrikeRoleArn), { StringEquals: { 'sts:ExternalId': crowdStrikeExternalId, }, }); } else { aws_cdk_lib_1.Annotations.of(this).addError('Either roleProps or both crowdStrikeRoleParameterArn and crowdStrikeExternalIdParameterArn must be provided.'); // This will not be used because of the error, but we need to initialize it to satisfy the type. crowdStrikePrincipal = new aws_cdk_lib_1.aws_iam.AnyPrincipal(); } /** * Create an IAM role for CrowdStrike to assume, granting it access to the resources created in this construct. * The role name can be provided in the props, or a default name will be generated based on the bucket name. */ this.role = new aws_cdk_lib_1.aws_iam.Role(this, 'Role', { roleName: props.roleProps?.roleName || `${this.bucketName}-role`, assumedBy: crowdStrikePrincipal, ...props.roleProps, }); // Grant the role permissions to read from the bucket and consume messages from the SQS queue. this.grantRead(this.role); this.queue.grantConsumeMessages(this.role); // If createKmsKey is true, create a KMS key for the data. if (props.createKmsKey) { this.key = new aws_cdk_lib_1.aws_kms.Key(this, 'Key', { alias: `alias/${this.bucketName}`, removalPolicy: aws_cdk_lib_1.RemovalPolicy.RETAIN_ON_UPDATE_OR_DELETE, enableKeyRotation: false, multiRegion: true, description: `KMS Key for CrowdStrike ingestion bucket ${this.bucketName}`, ...props.keyProps, }); // Grant the role permissions to use the KMS key for decryption. this.key.grantDecrypt(this.role); /** * If an orgId is provided, grant permissions to use the KMS key * for encryption and decryption for all accounts in the organization. */ if (props.orgId) { this.key.grantEncryptDecrypt(new aws_cdk_lib_1.aws_iam.OrganizationPrincipal(props.orgId)); } // Output the KMS key ARN for reference. new aws_cdk_lib_1.CfnOutput(this, 'KmsKeyArn', { value: this.key.keyArn, description: 'The ARN of the KMS key for CrowdStrike ingestion', }); } /** * Output the bucket name, bucket ARN, queue name, and role name. * You will need these values to configure CrowdStrike connectors. */ new aws_cdk_lib_1.CfnOutput(this, 'BucketName', { value: this.bucketName, description: 'The Name of the S3 bucket for CrowdStrike ingestion', }); new aws_cdk_lib_1.CfnOutput(this, 'BucketArn', { value: this.bucketArn, description: 'The ARN of the S3 bucket for CrowdStrike ingestion', }); new aws_cdk_lib_1.CfnOutput(this, 'QueueName', { value: this.queue.queueName, description: 'The Name of the SQS queue for CrowdStrike ingestion', }); new aws_cdk_lib_1.CfnOutput(this, 'RoleName', { value: this.role.roleName, description: 'The Name of the IAM role for CrowdStrike ingestion', }); } } exports.CrowdStrikeBucket = CrowdStrikeBucket; _a = JSII_RTTI_SYMBOL_1; CrowdStrikeBucket[_a] = { fqn: "@renovosolutions/cdk-library-crowdstrike-ingestion.CrowdStrikeBucket", version: "0.0.3" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVja2V0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2J1Y2tldC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLDZDQVdxQjtBQTZEcEIsQ0FBQztBQUVGOzs7O0dBSUc7QUFDSCxNQUFhLGlCQUFrQixTQUFRLG9CQUFFLENBQUMsTUFBTTtJQWtCOUM7Ozs7OztPQU1HO0lBQ0gsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUE2QjtRQUNyRSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRTtZQUNmLFVBQVUsRUFBRSxvQkFBRSxDQUFDLGdCQUFnQixDQUFDLFVBQVU7WUFDMUMsaUJBQWlCLEVBQUUsb0JBQUUsQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTO1lBQ2pELFVBQVUsRUFBRSxJQUFJO1lBQ2hCLFNBQVMsRUFBRSxJQUFJO1lBQ2YsYUFBYSxFQUFFLDJCQUFhLENBQUMsMEJBQTBCO1lBQ3ZELEdBQUcsS0FBSztTQUNULENBQUMsQ0FBQztRQUVIOzs7V0FHRztRQUNILElBQUksS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2hCLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxxQkFBRyxDQUFDLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQzlELENBQUM7UUFFRCwrR0FBK0c7UUFDL0csSUFBSSxLQUFLLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztZQUNsQyxJQUFJLENBQUMsbUJBQW1CLENBQ3RCLElBQUkscUJBQUcsQ0FBQyxlQUFlLENBQUM7Z0JBQ3RCLE1BQU0sRUFBRSxxQkFBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLO2dCQUN4QixPQUFPLEVBQUUsQ0FBQyxjQUFjLENBQUM7Z0JBQ3pCLFNBQVMsRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ3BDLFVBQVUsRUFBRSxDQUFDLElBQUkscUJBQUcsQ0FBQyxnQkFBZ0IsQ0FBQywwQkFB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QUFJLHVCQUFTLENBQUMsSUFBSSxFQUFFLFdBQVcsRUFBRTtZQUMvQixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTO1lBQzNCLFdBQVcsRUFBRSxxREFBcUQ7U0FDbkUsQ0FBQyxDQUFDO1FBRUgsSUFBSSx1QkFBUyxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUU7WUFDOUIsS0FBSyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUTtZQUN6QixXQUFXLEVBQUUsb0RBQW9EO1NBQ2xFLENBQUMsQ0FBQztJQUNMLENBQUM7O0FBdExILDhDQXVMQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFubm90YXRpb25zLFxuICBDZm5PdXRwdXQsXG4gIFJlbW92YWxQb2xpY3ksXG4gIFN0YWNrLFxuICBhd3NfaWFtIGFzIGlhbSxcbiAgYXdzX2ttcyBhcyBrbXMsXG4gIGF3c19zMyBhcyBzMyxcbiAgYXdzX3MzX25vdGlmaWNhdGlvbnMgYXMgczNuLFxuICBhd3Nfc3FzIGFzIHNxcyxcbiAgYXdzX3NzbSBhcyBzc20sXG59IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIHRoZSBDcm93ZFN0cmlrZUJ1Y2tldCBjb25zdHJ1Y3QuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ3Jvd2RTdHJpa2VCdWNrZXRQcm9wcyBleHRlbmRzIHMzLkJ1Y2tldFByb3BzIHtcbiAgLyoqXG4gICAqIFByb3BlcnRpZXMgZm9yIHRoZSBTUVMgcXVldWUuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gZW5mb3JjZVNTTDogdHJ1ZSwgZGVhZExldHRlclF1ZXVlOiB7IG1heFJlY2VpdmVDb3VudDogNSwgcXVldWU6IG5ldyBzcXMuUXVldWUodGhpcywgJ0RMUScsIHsgcXVldWVOYW1lOiBgJHt0aGlzLmJ1Y2tldE5hbWV9LWRscWAsIGVuZm9yY2VTU0w6IHRydWUsIH0pLCB9LFxuICAgKi9cbiAgcmVhZG9ubHkgcXVldWVQcm9wcz86IHNxcy5RdWV1ZVByb3BzO1xuICAvKipcbiAgICogV2hldGhlciB0byBjcmVhdGUgYSBLTVMga2V5IGZvciB0aGUgYnVja2V0LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGZhbHNlXG4gICAqL1xuICByZWFkb25seSBjcmVhdGVLbXNLZXk/OiBib29sZWFuO1xuICAvKipcbiAgICogUHJvcGVydGllcyBmb3IgdGhlIEtNUyBrZXkuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gcmVtb3ZhbFBvbGljeTogUmVtb3ZhbFBvbGljeS5SRVRBSU5fT05fVVBEQVRFX09SX0RFTEVURSwgZW5hYmxlS2V5Um90YXRpb246IGZhbHNlLCBtdWx0aVJlZ2lvbjogdHJ1ZSwgZGVzY3JpcHRpb246IGBLTVMgS2V5IGZvciBDcm93ZFN0cmlrZSBpbmdlc3Rpb24gYnVja2V0ICR7dGhpcy5idWNrZXROYW1lfWAsXG4gICAqL1xuICByZWFkb25seSBrZXlQcm9wcz86IGttcy5LZXlQcm9wcztcbiAgLyoqXG4gICAqIFByb3BlcnRpZXMgZm9yIHRoZSBJQU0gcm9sZS5cbiAgICpcbiAgICogSWYgeW91IHByb3ZpZGUgdGhpcywgeW91IG11c3QgcHJvdmlkZSB0aGUgcm9sZVByb3BzLmFzc3VtZWRCeSBwcm9wZXJ0eSxcbiAgICogYW5kIHlvdSBkb24ndCBuZWVkIHRvIHByb3ZpZGUgdGhlIGNyb3dkU3RyaWtlUm9sZVBhcmFtZXRlckFybiBhbmQgY3Jvd2RTdHJpa2VFeHRlcm5hbElkUGFyYW1ldGVyQXJuLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vbmUgZXhjZXB0IGZvciB0aGUgYXNzdW1lZEJ5IHByb3BlcnR5IHdoaWNoIGlzIHNldCB0byBhIENyb3dkU3RyaWtlIHByaW5jaXBhbC5cbiAgICovXG4gIHJlYWRvbmx5IHJvbGVQcm9wcz86IGlhbS5Sb2xlUHJvcHM7XG4gIC8qKlxuICAgKiBUaGUgQ3Jvd2RTdHJpa2Ugcm9sZSBBUk4uXG4gICAqXG4gICAqIFJlcXVpcmVkIHVubGVzcyB0aGUgcm9sZSBwcmluY2lwYWwgaXMgcHJvdmlkZWQgZGlyZWN0bHkgaW4gdGhlIHJvbGVQcm9wcy5cbiAgICovXG4gIHJlYWRvbmx5IGNyb3dkU3RyaWtlUm9sZUFybj86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBBUk4gb2YgdGhlIFNTTSBwYXJhbWV0ZXIgY29udGFpbmluZyB0aGUgQ3Jvd2RTdHJpa2UgZXh0ZXJuYWwgSUQuXG4gICAqXG4gICAqIFJlcXVpcmVkIHVubGVzcyB0aGUgcm9sZSBwcmluY2lwYWwgaXMgcHJvdmlkZWQgZGlyZWN0bHkgaW4gdGhlIHJvbGVQcm9wcy5cbiAgICovXG4gIHJlYWRvbmx5IGNyb3dkU3RyaWtlRXh0ZXJuYWxJZFBhcmFtZXRlckFybj86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBvcmdhbml6YXRpb24gSUQuXG4gICAqIElmIHByb3ZpZGVkLCB0aGUgYnVja2V0IHdpbGwgYWxsb3cgd3JpdGUgYWNjZXNzIHRvIGFsbCBhY2NvdW50cyBpbiB0aGUgb3JnYW5pemF0aW9uLlxuICAgKiBJZiB0aGVyZSBpcyBhIEtNUyBrZXksIGl0IHdpbGwgYWxzbyBhbGxvdyBlbmNyeXB0L2RlY3J5cHQgYWNjZXNzIHRvIHRoZSBvcmdhbml6YXRpb24uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm9uZVxuICAgKi9cbiAgcmVhZG9ubHkgb3JnSWQ/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgUzMgYnVja2V0IHRoYXQgd2lsbCBiZSBzZW5kaW5nIFMzIGFjY2VzcyBsb2dzIHRvIHRoaXMgYnVja2V0LlxuICAgKiBUaGlzIGlzIHVzZWQgdG8gY29uZmlndXJlIHRoZSBidWNrZXQgcG9saWN5IHRvIGFsbG93IGxvZ2dpbmcgZnJvbSB0aGF0IGJ1Y2tldC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBub25lXG4gICAqL1xuICByZWFkb25seSBsb2dnaW5nQnVja2V0U291cmNlTmFtZT86IHN0cmluZztcbn07XG5cbi8qKlxuICogQSBjb25zdHJ1Y3QgdGhhdCBjcmVhdGVzIGFuIFMzIGJ1Y2tldCBmb3IgQ3Jvd2RTdHJpa2UgZGF0YSBpbmdlc3Rpb24sXG4gKiBhbG9uZyB3aXRoIGFuIFNRUyBxdWV1ZSBmb3Igbm90aWZpY2F0aW9ucywgYW4gSUFNIHJvbGUgZm9yIGFjY2VzcyxcbiAqIGFuZCBvcHRpb25hbGx5IGEgS01TIGtleSBmb3IgZW5jcnlwdGlvbi5cbiAqL1xuZXhwb3J0IGNsYXNzIENyb3dkU3RyaWtlQnVja2V0IGV4dGVuZHMgczMuQnVja2V0IHtcbiAgLyoqXG4gICAqIFRoZSBTUVMgcXVldWUgdGhhdCByZWNlaXZlcyBub3RpZmljYXRpb25zIGZvciBuZXcgb2JqZWN0cyBpbiB0aGUgYnVja2V0LlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHF1ZXVlOiBzcXMuUXVldWU7XG4gIC8qKlxuICAgKiBUaGUgS01TIGtleSB1c2VkIGZvciBlbmNyeXB0aW5nIGRhdGEgaW4gdGhlIGJ1Y2tldCwgaWYgY3JlYXRlZC5cbiAgICogVGhpcyB3aWxsIGJlIHVuZGVmaW5lZCBpZiBjcmVhdGVLbXNLZXkgaXMgZmFsc2UuXG4gICAqXG4gICAqIE5vdGUgdGhhdCB0aGUgYnVja2V0IHdpbGwgc3RpbGwgYmUgY3JlYXRlZCB3aXRoIFMzLW1hbmFnZWQgZW5jcnlwdGlvblxuICAgKiBldmVuIGlmIHRoaXMgaXMgcHJvdmlkZWQuIFRoZSBrZXkgaXMgdXNlZCBieSB0aGUgc2VydmljZSB3cml0aW5nIHRvIHRoZSBidWNrZXQuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkga2V5Pzoga21zLktleTtcbiAgLyoqXG4gICAqIFRoZSBJQU0gcm9sZSB0aGF0IENyb3dkU3RyaWtlIHdpbGwgYXNzdW1lIHRvIGFjY2VzcyB0aGUgZGF0YSBpbiB0aGUgYnVja2V0LlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHJvbGU6IGlhbS5Sb2xlO1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3RzIGEgbmV3IENyb3dkU3RyaWtlQnVja2V0LlxuICAgKlxuICAgKiBAcGFyYW0gc2NvcGUgVGhlIHNjb3BlIGluIHdoaWNoIHRoaXMgY29uc3RydWN0IGlzIGRlZmluZWQuXG4gICAqIEBwYXJhbSBpZCBUaGUgc2NvcGVkIGNvbnN0cnVjdCBJRC5cbiAgICogQHBhcmFtIHByb3BzIFRoZSBwcm9wZXJ0aWVzIGZvciB0aGUgYnVja2V0LCBxdWV1ZSwgcm9sZSwgYW5kIG9wdGlvbmFsIEtNUyBrZXkuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQ3Jvd2RTdHJpa2VCdWNrZXRQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCwge1xuICAgICAgZW5jcnlwdGlvbjogczMuQnVja2V0RW5jcnlwdGlvbi5TM19NQU5BR0VELFxuICAgICAgYmxvY2tQdWJsaWNBY2Nlc3M6IHMzLkJsb2NrUHVibGljQWNjZXNzLkJMT0NLX0FMTCxcbiAgICAgIGVuZm9yY2VTU0w6IHRydWUsXG4gICAgICB2ZXJzaW9uZWQ6IHRydWUsXG4gICAgICByZW1vdmFsUG9saWN5OiBSZW1vdmFsUG9saWN5LlJFVEFJTl9PTl9VUERBVEVfT1JfREVMRVRFLFxuICAgICAgLi4ucHJvcHMsXG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBJZiB3ZSBoYXZlIGFuIG9yZ0lkLCBncmFudCBidWNrZXQgd3JpdGUgYWNjZXNzIHRvIGFsbCBhY2NvdW50cyBpbiB0aGUgb3JnYW5pemF0aW9uLlxuICAgICAqIFRoaXMgaXMgdXNlZnVsIGZvciBhbGxvd2luZyBtdWx0aXBsZSBhY2NvdW50cyBpbiBhbiBvcmdhbml6YXRpb24gdG8gd3JpdGUgdG8gdGhlIHNhbWUgYnVja2V0LlxuICAgICAqL1xuICAgIGlmIChwcm9wcy5vcmdJZCkge1xuICAgICAgdGhpcy5ncmFudFdyaXRlKG5ldyBpYW0uT3JnYW5pemF0aW9uUHJpbmNpcGFsKHByb3BzLm9yZ0lkKSk7XG4gICAgfVxuXG4gICAgLy8gSWYgYSBsb2dnaW5nIGJ1Y2tldCBzb3VyY2UgbmFtZSBpcyBwcm92aWRlZCwgYWRkIGEgcG9saWN5IHRvIGFsbG93IHRoYXQgYnVja2V0IHRvIHdyaXRlIGxvZ3MgdG8gdGhpcyBidWNrZXQuXG4gICAgaWYgKHByb3BzLmxvZ2dpbmdCdWNrZXRTb3VyY2VOYW1lKSB7XG4gICAgICB0aGlzLmFkZFRvUmVzb3VyY2VQb2xpY3koXG4gICAgICAgIG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICBlZmZlY3Q6IGlhbS5FZmZlY3QuQUxMT1csXG4gICAgICAgICAgYWN0aW9uczogWydzMzpQdXRPYmplY3QnXSxcbiAgICAgICAgICByZXNvdXJjZXM6IFt0aGlzLmFybkZvck9iamVjdHMoJyonKV0sXG4gICAgICAgICAgcHJpbmNpcGFsczogW25ldyBpYW0uU2VydmljZVByaW5jaXBhbCgnbG9nZ2luZy5zMy5hbWF6b25hd3MuY29tJyldLFxuICAgICAgICAgIGNvbmRpdGlvbnM6IHtcbiAgICAgICAgICAgIEFybkxpa2U6IHtcbiAgICAgICAgICAgICAgJ2F3czpTb3VyY2VBcm4nOiBgYXJuOmF3czpzMzo6OiR7cHJvcHMubG9nZ2luZ0J1Y2tldFNvdXJjZU5hbWV9YCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBTdHJpbmdFcXVhbHM6IHtcbiAgICAgICAgICAgICAgJ2F3czpTb3VyY2VBY2NvdW50JzogU3RhY2sub2YodGhpcykuYWNjb3VudCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhbiBTUVMgcXVldWUgZm9yIG5vdGlmaWNhdGlvbnMuXG4gICAgICogSWYgYSBxdWV1ZU5hbWUgaXMgcHJvdmlkZWQsIHVzZSBpdDsgb3RoZXJ3aXNlLCBnZW5lcmF0ZSBhIGRlZmF1bHQgbmFtZSBiYXNlZCBvbiB0aGUgYnVja2V0IG5hbWUuXG4gICAgICovXG4gICAgdGhpcy5xdWV1ZSA9IG5ldyBzcXMuUXVldWUodGhpcywgJ1F1ZXVlJywge1xuICAgICAgcXVldWVOYW1lOiBwcm9wcy5xdWV1ZVByb3BzPy5xdWV1ZU5hbWUgfHwgYCR7dGhpcy5idWNrZXROYW1lfS1xdWV1ZWAsXG4gICAgICBlbmZvcmNlU1NMOiB0cnVlLFxuICAgICAgZGVhZExldHRlclF1ZXVlOiB7XG4gICAgICAgIG1heFJlY2VpdmVDb3VudDogNSxcbiAgICAgICAgcXVldWU6IG5ldyBzcXMuUXVldWUodGhpcywgJ0RMUScsIHtcbiAgICAgICAgICBxdWV1ZU5hbWU6IGAke3RoaXMuYnVja2V0TmFtZX0tZGxxYCxcbiAgICAgICAgICBlbmZvcmNlU1NMOiB0cnVlLFxuICAgICAgICB9KSxcbiAgICAgIH0sXG4gICAgICAuLi5wcm9wcy5xdWV1ZVByb3BzLFxuICAgIH0pO1xuXG4gICAgLy8gQWRkIGEgbm90aWZpY2F0aW9uIGZvciBidWNrZXQgb2JqZWN0IGNyZWF0aW9uIGV2ZW50cyB0byB0aGUgU1FTIHF1ZXVlLlxuICAgIHRoaXMuYWRkRXZlbnROb3RpZmljYXRpb24oXG4gICAgICBzMy5FdmVudFR5cGUuT0JKRUNUX0NSRUFURUQsXG4gICAgICBuZXcgczNuLlNxc0Rlc3RpbmF0aW9uKHRoaXMucXVldWUpLFxuICAgICk7XG5cbiAgICAvKipcbiAgICAgKiBEZXRlcm1pbmUgdGhlIHByaW5jaXBhbCBmb3IgQ3Jvd2RTdHJpa2UuXG4gICAgICogSWYgcm9sZVByb3BzIGFyZSBwcm92aWRlZCwgdXNlIHRoZSBhc3N1bWVkQnkgcHJvcGVydHkgZnJvbSB0aGVyZS5cbiAgICAgKiBPdGhlcndpc2UsIGNyZWF0ZSBhIENyb3dkU3RyaWtlIHByaW5jaXBhbCB1c2luZyB0aGUgcm9sZSBBUk4gYW5kIGV4dGVybmFsIElEIGZyb20gU1NNIHBhcmFtZXRlcnMuXG4gICAgICovXG4gICAgbGV0IGNyb3dkU3RyaWtlUHJpbmNpcGFsOiBpYW0uSVByaW5jaXBhbDtcbiAgICBpZiAocHJvcHMucm9sZVByb3BzKSB7XG4gICAgICBjcm93ZFN0cmlrZVByaW5jaXBhbCA9IHByb3BzLnJvbGVQcm9wcy5hc3N1bWVkQnk7XG4gICAgfSBlbHNlIGlmIChwcm9wcy5jcm93ZFN0cmlrZVJvbGVBcm4gJiYgcHJvcHMuY3Jvd2RTdHJpa2VFeHRlcm5hbElkUGFyYW1ldGVyQXJuKSB7XG4gICAgICBjb25zdCBjcm93ZFN0cmlrZVJvbGVBcm4gPSBwcm9wcy5jcm93ZFN0cmlrZVJvbGVBcm47XG5cbiAgICAgIGNvbnN0IGNyb3dkU3RyaWtlRXh0ZXJuYWxJZCA9IHNzbS5TdHJpbmdQYXJhbWV0ZXIuZnJvbVN0cmluZ1BhcmFtZXRlckFybihcbiAgICAgICAgdGhpcyxcbiAgICAgICAgJ0Nyb3dkU3RyaWtlRXh0ZXJuYWxJZFBhcmFtJyxcbiAgICAgICAgcHJvcHMuY3Jvd2RTdHJpa2VFeHRlcm5hbElkUGFyYW1ldGVyQXJuLFxuICAgICAgKS5zdHJpbmdWYWx1ZTtcblxuICAgICAgY3Jvd2RTdHJpa2VQcmluY2lwYWwgPSBuZXcgaWFtLlByaW5jaXBhbFdpdGhDb25kaXRpb25zKG5ldyBpYW0uQXJuUHJpbmNpcGFsKGNyb3dkU3RyaWtlUm9sZUFybiksIHtcbiAgICAgICAgU3RyaW5nRXF1YWxzOiB7XG4gICAgICAgICAgJ3N0czpFeHRlcm5hbElkJzogY3Jvd2RTdHJpa2VFeHRlcm5hbElkLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIEFubm90YXRpb25zLm9mKHRoaXMpLmFkZEVycm9yKFxuICAgICAgICAnRWl0aGVyIHJvbGVQcm9wcyBvciBib3RoIGNyb3dkU3RyaWtlUm9sZVBhcmFtZXRlckFybiBhbmQgY3Jvd2RTdHJpa2VFeHRlcm5hbElkUGFyYW1ldGVyQXJuIG11c3QgYmUgcHJvdmlkZWQuJyxcbiAgICAgICk7XG4gICAgICAvLyBUaGlzIHdpbGwgbm90IGJlIHVzZWQgYmVjYXVzZSBvZiB0aGUgZXJyb3IsIGJ1dCB3ZSBuZWVkIHRvIGluaXRpYWxpemUgaXQgdG8gc2F0aXNmeSB0aGUgdHlwZS5cbiAgICAgIGNyb3dkU3RyaWtlUHJpbmNpcGFsID0gbmV3IGlhbS5BbnlQcmluY2lwYWwoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW4gSUFNIHJvbGUgZm9yIENyb3dkU3RyaWtlIHRvIGFzc3VtZSwgZ3JhbnRpbmcgaXQgYWNjZXNzIHRvIHRoZSByZXNvdXJjZXMgY3JlYXRlZCBpbiB0aGlzIGNvbnN0cnVjdC5cbiAgICAgKiBUaGUgcm9sZSBuYW1lIGNhbiBiZSBwcm92aWRlZCBpbiB0aGUgcHJvcHMsIG9yIGEgZGVmYXVsdCBuYW1lIHdpbGwgYmUgZ2VuZXJhdGVkIGJhc2VkIG9uIHRoZSBidWNrZXQgbmFtZS5cbiAgICAgKi9cbiAgICB0aGlzLnJvbGUgPSBuZXcgaWFtLlJvbGUodGhpcywgJ1JvbGUnLCB7XG4gICAgICByb2xlTmFtZTogcHJvcHMucm9sZVByb3BzPy5yb2xlTmFtZSB8fCBgJHt0aGlzLmJ1Y2tldE5hbWV9LXJvbGVgLFxuICAgICAgYXNzdW1lZEJ5OiBjcm93ZFN0cmlrZVByaW5jaXBhbCxcbiAgICAgIC4uLnByb3BzLnJvbGVQcm9wcyxcbiAgICB9KTtcblxuICAgIC8vIEdyYW50IHRoZSByb2xlIHBlcm1pc3Npb25zIHRvIHJlYWQgZnJvbSB0aGUgYnVja2V0IGFuZCBjb25zdW1lIG1lc3NhZ2VzIGZyb20gdGhlIFNRUyBxdWV1ZS5cbiAgICB0aGlzLmdyYW50UmVhZCh0aGlzLnJvbGUpO1xuICAgIHRoaXMucXVldWUuZ3JhbnRDb25zdW1lTWVzc2FnZXModGhpcy5yb2xlKTtcblxuICAgIC8vIElmIGNyZWF0ZUttc0tleSBpcyB0cnVlLCBjcmVhdGUgYSBLTVMga2V5IGZvciB0aGUgZGF0YS5cbiAgICBpZiAocHJvcHMuY3JlYXRlS21zS2V5KSB7XG4gICAgICB0aGlzLmtleSA9IG5ldyBrbXMuS2V5KHRoaXMsICdLZXknLCB7XG4gICAgICAgIGFsaWFzOiBgYWxpYXMvJHt0aGlzLmJ1Y2tldE5hbWV9YCxcbiAgICAgICAgcmVtb3ZhbFBvbGljeTogUmVtb3ZhbFBvbGljeS5SRVRBSU5fT05fVVBEQVRFX09SX0RFTEVURSxcbiAgICAgICAgZW5hYmxlS2V5Um90YXRpb246IGZhbHNlLFxuICAgICAgICBtdWx0aVJlZ2lvbjogdHJ1ZSxcbiAgICAgICAgZGVzY3JpcHRpb246IGBLTVMgS2V5IGZvciBDcm93ZFN0cmlrZSBpbmdlc3Rpb24gYnVja2V0ICR7dGhpcy5idWNrZXROYW1lfWAsXG4gICAgICAgIC4uLnByb3BzLmtleVByb3BzLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIEdyYW50IHRoZSByb2xlIHBlcm1pc3Npb25zIHRvIHVzZSB0aGUgS01TIGtleSBmb3IgZGVjcnlwdGlvbi5cbiAgICAgIHRoaXMua2V5LmdyYW50RGVjcnlwdCh0aGlzLnJvbGUpO1xuXG4gICAgICAvKipcbiAgICAgICAqIElmIGFuIG9yZ0lkIGlzIHByb3ZpZGVkLCBncmFudCBwZXJtaXNzaW9ucyB0byB1c2UgdGhlIEtNUyBrZXlcbiAgICAgICAqIGZvciBlbmNyeXB0aW9uIGFuZCBkZWNyeXB0aW9uIGZvciBhbGwgYWNjb3VudHMgaW4gdGhlIG9yZ2FuaXphdGlvbi5cbiAgICAgICAqL1xuICAgICAgaWYgKHByb3BzLm9yZ0lkKSB7XG4gICAgICAgIHRoaXMua2V5LmdyYW50RW5jcnlwdERlY3J5cHQobmV3IGlhbS5Pcmdhbml6YXRpb25QcmluY2lwYWwocHJvcHMub3JnSWQpKTtcbiAgICAgIH1cblxuICAgICAgLy8gT3V0cHV0IHRoZSBLTVMga2V5IEFSTiBmb3IgcmVmZXJlbmNlLlxuICAgICAgbmV3IENmbk91dHB1dCh0aGlzLCAnS21zS2V5QXJuJywge1xuICAgICAgICB2YWx1ZTogdGhpcy5rZXkua2V5QXJuLFxuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoZSBBUk4gb2YgdGhlIEtNUyBrZXkgZm9yIENyb3dkU3RyaWtlIGluZ2VzdGlvbicsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBPdXRwdXQgdGhlIGJ1Y2tldCBuYW1lLCBidWNrZXQgQVJOLCBxdWV1ZSBuYW1lLCBhbmQgcm9sZSBuYW1lLlxuICAgICAqIFlvdSB3aWxsIG5lZWQgdGhlc2UgdmFsdWVzIHRvIGNvbmZpZ3VyZSBDcm93ZFN0cmlrZSBjb25uZWN0b3JzLlxuICAgICAqL1xuICAgIG5ldyBDZm5PdXRwdXQodGhpcywgJ0J1Y2tldE5hbWUnLCB7XG4gICAgICB2YWx1ZTogdGhpcy5idWNrZXROYW1lLFxuICAgICAgZGVzY3JpcHRpb246ICdUaGUgTmFtZSBvZiB0aGUgUzMgYnVja2V0IGZvciBDcm93ZFN0cmlrZSBpbmdlc3Rpb24nLFxuICAgIH0pO1xuXG4gICAgbmV3IENmbk91dHB1dCh0aGlzLCAnQnVja2V0QXJuJywge1xuICAgICAgdmFsdWU6IHRoaXMuYnVja2V0QXJuLFxuICAgICAgZGVzY3JpcHRpb246ICdUaGUgQVJOIG9mIHRoZSBTMyBidWNrZXQgZm9yIENyb3dkU3RyaWtlIGluZ2VzdGlvbicsXG4gICAgfSk7XG5cbiAgICBuZXcgQ2ZuT3V0cHV0KHRoaXMsICdRdWV1ZU5hbWUnLCB7XG4gICAgICB2YWx1ZTogdGhpcy5xdWV1ZS5xdWV1ZU5hbWUsXG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZSBOYW1lIG9mIHRoZSBTUVMgcXVldWUgZm9yIENyb3dkU3RyaWtlIGluZ2VzdGlvbicsXG4gICAgfSk7XG5cbiAgICBuZXcgQ2ZuT3V0cHV0KHRoaXMsICdSb2xlTmFtZScsIHtcbiAgICAgIHZhbHVlOiB0aGlzLnJvbGUucm9sZU5hbWUsXG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZSBOYW1lIG9mIHRoZSBJQU0gcm9sZSBmb3IgQ3Jvd2RTdHJpa2UgaW5nZXN0aW9uJyxcbiAgICB9KTtcbiAgfVxufVxuIl19