@pepperize/cdk-autoscaling-gitlab-runner
Version:
AWS CDK GitLab Runner autoscaling on EC2 instances using docker+machine executor.
285 lines • 48.9 kB
JavaScript
;
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.GitlabRunnerAutoscalingManager = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const aws_cdk_lib_1 = require("aws-cdk-lib");
const aws_ec2_1 = require("aws-cdk-lib/aws-ec2");
const aws_iam_1 = require("aws-cdk-lib/aws-iam");
const constructs_1 = require("constructs");
const docker_machine_version_1 = require("./docker-machine-version");
const runner_configuration_1 = require("../runner-configuration");
const DEFAULT_SSH_KEY_PATH = "/etc/gitlab-runner/ssh-custom";
/**
* Settings for the manager (coordinator)
*
* Manager coordinates the placement of runner (job executor) instances
*/
class GitlabRunnerAutoscalingManager extends constructs_1.Construct {
constructor(scope, id, props) {
super(scope, id);
this.globalConfiguration =
props.globalConfiguration ||
{
concurrent: 10,
checkInterval: 0,
logFormat: "runner",
logLevel: "info",
};
this.machineImage =
props.machineImage ??
aws_ec2_1.MachineImage.latestAmazonLinux({
generation: aws_ec2_1.AmazonLinuxGeneration.AMAZON_LINUX_2,
edition: aws_ec2_1.AmazonLinuxEdition.STANDARD,
virtualization: aws_ec2_1.AmazonLinuxVirt.HVM,
storage: aws_ec2_1.AmazonLinuxStorage.EBS,
cpuType: aws_ec2_1.AmazonLinuxCpuType.X86_64,
});
this.instanceType = props.instanceType ?? aws_ec2_1.InstanceType.of(aws_ec2_1.InstanceClass.T3, aws_ec2_1.InstanceSize.NANO);
this.keyPairName = props.keyPairName;
this.runners = props.runners;
this.network = props.network;
this.cacheBucket = props.cacheBucket;
this.runnersSecurityGroupName = props.runnersSecurityGroup.securityGroupName;
this.role =
props.role ||
new aws_iam_1.Role(scope, "ManagerRole", {
assumedBy: new aws_iam_1.ServicePrincipal("ec2.amazonaws.com", {}),
managedPolicies: [aws_iam_1.ManagedPolicy.fromAwsManagedPolicyName("AmazonSSMManagedInstanceCore")],
inlinePolicies: {
Cache: aws_iam_1.PolicyDocument.fromJson({
Version: "2012-10-17",
Statement: [
{
Effect: "Allow",
Action: ["s3:ListObjects*", "s3:GetObject*", "s3:DeleteObject*", "s3:PutObject*"],
Resource: [`${this.cacheBucket.bucketArn}/*`],
},
{
Effect: "Allow",
Action: ["s3:ListBucket"],
Resource: [`${this.cacheBucket.bucketArn}`],
},
],
}),
Runners: aws_iam_1.PolicyDocument.fromJson({
Version: "2012-10-17",
Statement: [
{
Effect: "Allow",
Action: ["ec2:CreateKeyPair", "ec2:DeleteKeyPair", "ec2:ImportKeyPair", "ec2:Describe*"],
Resource: ["*"],
},
{
Effect: "Allow",
Action: ["ec2:CreateTags", "ssm:UpdateInstanceInformation"],
Resource: ["*"],
Condition: {
StringLike: {
"aws:RequestTag/Name": "*gitlab-runner-*",
},
"ForAllValues:StringEquals": {
"aws:TagKeys": ["Name"],
},
},
},
{
Effect: "Allow",
Action: ["ec2:RequestSpotInstances", "ec2:CancelSpotInstanceRequests"],
Resource: ["*"],
Condition: {
StringEqualsIfExists: {
"ec2:Region": `${aws_cdk_lib_1.Stack.of(this).region}`,
},
ArnEqualsIfExists: {
"ec2:Vpc": `arn:aws:ec2:${aws_cdk_lib_1.Stack.of(this).region}:${aws_cdk_lib_1.Stack.of(this).account}:vpc/${this.network.vpc.vpcId}`,
},
},
},
{
Effect: "Allow",
Action: ["ec2:RunInstances"],
Resource: ["*"],
Condition: {
"ForAllValues:StringEquals": {
"ec2:InstanceType": (this.runners || []).map((runner) => {
const runnersInstanceType = (this.runners && runner.instanceType) || aws_ec2_1.InstanceType.of(aws_ec2_1.InstanceClass.T3, aws_ec2_1.InstanceSize.MICRO);
return runnersInstanceType.toString();
}),
},
},
},
{
Effect: "Allow",
Action: ["ec2:TerminateInstances", "ec2:StopInstances", "ec2:StartInstances", "ec2:RebootInstances"],
Resource: ["*"],
Condition: {
StringLike: {
"ec2:ResourceTag/Name": "*gitlab-runner-*",
},
},
},
{
Effect: "Allow",
Action: ["iam:PassRole"],
Resource: ["*"],
Condition: {
"ForAllValues:StringEquals": {
"aws:TagKeys": ["RunnersRole"],
},
},
},
],
}),
ECRLogin: aws_iam_1.PolicyDocument.fromJson({
Version: "2012-10-17",
Statement: [
{
Effect: "Allow",
Action: ["ecr:BatchGetImage", "ecr:GetAuthorizationToken", "ecr:GetDownloadUrlForLayer"],
Resource: "*",
},
],
}),
},
});
this.userData = aws_ec2_1.UserData.forLinux({});
this.userData.addCommands(`yum update -y aws-cfn-bootstrap`, // !/bin/bash -xe
`yum install -y amazon-ecr-credential-helper`);
// https://github.com/awslabs/amazon-ecr-credential-helper
const userDataRunners = aws_ec2_1.UserData.forLinux({});
userDataRunners.addCommands(`[ ! -z "$(which apt-get)" ] && apt-get update && apt-get install -y amazon-ecr-credential-helper`, `[ ! -z "$(which yum)" ] && yum install -y amazon-ecr-credential-helper`);
const gitlabRunnerConfigRestartHandle = new aws_ec2_1.InitServiceRestartHandle();
gitlabRunnerConfigRestartHandle._addFile("/etc/gitlab-runner/config.toml");
const rsyslogConfigRestartHandle = new aws_ec2_1.InitServiceRestartHandle();
rsyslogConfigRestartHandle._addFile("/etc/rsyslog.d/25-gitlab-runner.conf");
/**
* Config set keys
* @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-init.html#aws-resource-init-configsets
*/
const REPOSITORIES = "repositories";
const PACKAGES = "packages";
const CONFIG = "config";
const RESTART = "restart";
this.initConfig = aws_ec2_1.CloudFormationInit.fromConfigSets({
configSets: {
default: [REPOSITORIES, PACKAGES, CONFIG, RESTART],
},
configs: {
[REPOSITORIES]: new aws_ec2_1.InitConfig([
aws_ec2_1.InitCommand.shellCommand("curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | bash", { key: "10-gitlab-runner" }),
]),
[PACKAGES]: new aws_ec2_1.InitConfig([
aws_ec2_1.InitPackage.yum("docker"),
aws_ec2_1.InitPackage.yum("gitlab-runner"),
aws_ec2_1.InitPackage.yum("tzdata"),
aws_ec2_1.InitPackage.yum("jq"),
aws_ec2_1.InitCommand.shellCommand(`curl -L https://gitlab-docker-machine-downloads.s3.amazonaws.com/${props.dockerMachineVersion?.version ?? docker_machine_version_1.DockerMachineVersion.V0_16_2_GITLAB_15.version}/docker-machine-\`uname -s\`-\`uname -m\` > /tmp/docker-machine && install /tmp/docker-machine /usr/bin/docker-machine`,
//"curl -L https://github.com/docker/machine/releases/download/v0.16.2/docker-machine-`uname -s`-`uname -m` > /tmp/docker-machine && install /tmp/docker-machine /usr/bin/docker-machine",
{ key: "10-docker-machine" }),
aws_ec2_1.InitCommand.shellCommand("gitlab-runner start", {
key: "20-gitlab-runner-start",
}),
]),
[CONFIG]: new aws_ec2_1.InitConfig([
aws_ec2_1.InitFile.fromString("/etc/gitlab-runner/config.toml", runner_configuration_1.ConfigurationMapper.withDefaults({
globalConfiguration: this.globalConfiguration,
runnersConfiguration: this.runners.map((runner) => {
const configuration = runner.configuration;
return {
...configuration,
machine: {
...configuration.machine,
machineOptions: {
sshKeypath:
// drivers/amazonec2/amazonec2.go SSHPrivateKeyPath
runner.keyPair
? `${DEFAULT_SSH_KEY_PATH}/${configuration.machine?.machineOptions?.keypairName}`
: "",
...configuration.machine?.machineOptions,
instanceType: runner.instanceType.toString(),
ami: runner.machineImage.getImage(scope).imageId,
region: aws_cdk_lib_1.Stack.of(this).region,
vpcId: this.network.vpc.vpcId,
zone: this.network.availabilityZone.slice(-1),
subnetId: this.network.subnet.subnetId,
securityGroup: this.runnersSecurityGroupName,
privateAddressOnly: configuration.machine?.machineOptions?.privateAddressOnly ?? this.network.hasPrivateSubnets(),
usePrivateAddress: configuration.machine?.machineOptions?.usePrivateAddress ?? true,
iamInstanceProfile: runner.instanceProfile.ref,
userdata: "/etc/gitlab-runner/user_data_runners",
engineInstallUrl: configuration.machine?.machineOptions?.engineInstallUrl ??
"https://releases.rancher.com/install-docker/20.10.21.sh",
},
},
cache: {
s3: {
serverAddress: `s3.${aws_cdk_lib_1.Stack.of(this).urlSuffix}`,
bucketName: `${this.cacheBucket.bucketName}`,
bucketLocation: `${aws_cdk_lib_1.Stack.of(this).region}`,
authenticationType: "iam",
},
},
};
}),
}).toToml(), {
owner: "gitlab-runner",
group: "gitlab-runner",
mode: "000600",
}),
aws_ec2_1.InitFile.fromString("/etc/rsyslog.d/25-gitlab-runner.conf", `:programname, isequal, "gitlab-runner" /var/log/gitlab-runner.log`, {
owner: "root",
group: "root",
mode: "000644",
}),
aws_ec2_1.InitService.enable("gitlab-runner", {
ensureRunning: true,
enabled: true,
serviceRestartHandle: gitlabRunnerConfigRestartHandle,
}),
aws_ec2_1.InitService.enable("rsyslog", {
ensureRunning: true,
enabled: true,
serviceRestartHandle: rsyslogConfigRestartHandle,
}),
aws_ec2_1.InitCommand.shellCommand(
// Download custom EC2 key pair for manager <> runner ssh connect
this.runners
.map((runner) => {
if (!runner.keyPair) {
return "";
}
runner.keyPair.grantRead(this.role);
const region = aws_cdk_lib_1.Stack.of(this).region;
const secretArn = runner.keyPair.secretArn;
const keyPairName = runner.configuration.machine.machineOptions.keypairName;
const sshKeyPath = runner.configuration.machine.machineOptions.sshKeypath ?? DEFAULT_SSH_KEY_PATH;
return [
`mkdir -p ${sshKeyPath};`,
`echo $(aws secretsmanager get-secret-value --region ${region} --secret-id ${secretArn} --query SecretString --output text) | jq -r '."${keyPairName}"' > ${sshKeyPath}/${keyPairName};`,
`echo $(aws secretsmanager get-secret-value --region ${region} --secret-id ${secretArn} --query SecretString --output text) | jq -r '."${keyPairName}.pub"' > ${sshKeyPath}/${keyPairName}.pub;`,
].join("\n");
})
.filter((s) => s.length > 0)
.join("\n"), {
key: "999-retrieve-ec2-key-pair",
}),
aws_ec2_1.InitFile.fromString("/etc/gitlab-runner/user_data_runners", userDataRunners.render(), {
owner: "gitlab-runner",
group: "gitlab-runner",
mode: "000600",
}),
]),
[RESTART]: new aws_ec2_1.InitConfig([
aws_ec2_1.InitCommand.shellCommand("gitlab-runner restart", {
key: "10-gitlab-runner-restart",
}),
]),
},
});
}
}
exports.GitlabRunnerAutoscalingManager = GitlabRunnerAutoscalingManager;
_a = JSII_RTTI_SYMBOL_1;
GitlabRunnerAutoscalingManager[_a] = { fqn: "@pepperize/cdk-autoscaling-gitlab-runner.GitlabRunnerAutoscalingManager", version: "0.2.683" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydW5uZXIvbWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUNBLDZDQUFvQztBQUNwQyxpREFtQjZCO0FBQzdCLGlEQUFtRztBQUVuRywyQ0FBdUM7QUFDdkMscUVBQWdFO0FBR2hFLGtFQUF3RztBQW9DeEcsTUFBTSxvQkFBb0IsR0FBRywrQkFBK0IsQ0FBQztBQUU3RDs7OztHQUlHO0FBQ0gsTUFBYSw4QkFBK0IsU0FBUSxzQkFBUztJQWEzRCxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQTBDO1FBQ2xGLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDakIsSUFBSSxDQUFDLG1CQUFtQjtZQUN0QixLQUFLLENBQUMsbUJBQW1CO2dCQUN4QjtvQkFDQyxVQUFVLEVBQUUsRUFBRTtvQkFDZCxhQUFhLEVBQUUsQ0FBQztvQkFDaEIsU0FBUyxFQUFFLFFBQVE7b0JBQ25CLFFBQVEsRUFBRSxNQUFNO2lCQUNPLENBQUM7UUFDNUIsSUFBSSxDQUFDLFlBQVk7WUFDZixLQUFLLENBQUMsWUFBWTtnQkFDbEIsc0JBQVksQ0FBQyxpQkFBaUIsQ0FBQztvQkFDN0IsVUFBVSxFQUFFLCtCQUFxQixDQUFDLGNBQWM7b0JBQ2hELE9BQU8sRUFBRSw0QkFBa0IsQ0FBQyxRQUFRO29CQUNwQyxjQUFjLEVBQUUseUJBQWUsQ0FBQyxHQUFHO29CQUNuQyxPQUFPLEVBQUUsNEJBQWtCLENBQUMsR0FBRztvQkFDL0IsT0FBTyxFQUFFLDRCQUFrQixDQUFDLE1BQU07aUJBQ25DLENBQUMsQ0FBQztRQUNMLElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDLFlBQVksSUFBSSxzQkFBWSxDQUFDLEVBQUUsQ0FBQyx1QkFBYSxDQUFDLEVBQUUsRUFBRSxzQkFBWSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQy9GLElBQUksQ0FBQyxXQUFXLEdBQUcs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cG9ydCB7IFNlY3VyaXR5R3JvdXAgfSBmcm9tIFwiQHBlcHBlcml6ZS9jZGstc2VjdXJpdHktZ3JvdXBcIjtcbmltcG9ydCB7IFN0YWNrIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQge1xuICBBbWF6b25MaW51eENwdVR5cGUsXG4gIEFtYXpvbkxpbnV4RWRpdGlvbixcbiAgQW1hem9uTGludXhHZW5lcmF0aW9uLFxuICBBbWF6b25MaW51eFN0b3JhZ2UsXG4gIEFtYXpvbkxpbnV4VmlydCxcbiAgQ2xvdWRGb3JtYXRpb25Jbml0LFxuICBJTWFjaGluZUltYWdlLFxuICBJbml0Q29tbWFuZCxcbiAgSW5pdENvbmZpZyxcbiAgSW5pdEZpbGUsXG4gIEluaXRQYWNrYWdlLFxuICBJbml0U2VydmljZSxcbiAgSW5pdFNlcnZpY2VSZXN0YXJ0SGFuZGxlLFxuICBJbnN0YW5jZUNsYXNzLFxuICBJbnN0YW5jZVNpemUsXG4gIEluc3RhbmNlVHlwZSxcbiAgTWFjaGluZUltYWdlLFxuICBVc2VyRGF0YSxcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1lYzJcIjtcbmltcG9ydCB7IElSb2xlLCBNYW5hZ2VkUG9saWN5LCBQb2xpY3lEb2N1bWVudCwgUm9sZSwgU2VydmljZVByaW5jaXBhbCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtaWFtXCI7XG5pbXBvcnQgeyBJQnVja2V0IH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1zM1wiO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB7IERvY2tlck1hY2hpbmVWZXJzaW9uIH0gZnJvbSBcIi4vZG9ja2VyLW1hY2hpbmUtdmVyc2lvblwiO1xuaW1wb3J0IHsgR2l0bGFiUnVubmVyQXV0b3NjYWxpbmdKb2JSdW5uZXIgfSBmcm9tIFwiLi9qb2ItcnVubmVyXCI7XG5pbXBvcnQgeyBOZXR3b3JrIH0gZnJvbSBcIi4vbmV0d29ya1wiO1xuaW1wb3J0IHsgQ29uZmlndXJhdGlvbk1hcHBlciwgR2xvYmFsQ29uZmlndXJhdGlvbiwgUnVubmVyQ29uZmlndXJhdGlvbiB9IGZyb20gXCIuLi9ydW5uZXItY29uZmlndXJhdGlvblwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIEdpdGxhYlJ1bm5lckF1dG9zY2FsaW5nTWFuYWdlckJhc2VQcm9wcyB7XG4gIC8qKlxuICAgKiBBbiBBbWF6b24gTWFjaGluZSBJbWFnZSBJRCBmb3IgdGhlIE1hbmFnZXIgRUMyIGluc3RhbmNlLiBJZiBlbXB0eSB0aGUgbGF0ZXN0IEFtYXpvbiAyIEltYWdlIHdpbGwgYmUgbG9va2VkIHVwLlxuICAgKlxuICAgKiBTaG91bGQgYmUgUkhFTCBmbGF2b3IgbGlrZSBBbWF6b24gTGludXggMiB3aXRoIHl1bSBhdmFpbGFibGUgZm9yIGluc3RhbmNlIGluaXRpYWxpemF0aW9uLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vY2xvdWRpbml0LnJlYWR0aGVkb2NzLmlvL2VuL2xhdGVzdC9cbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9jZm4taW5pdC5odG1sXG4gICAqL1xuICByZWFkb25seSBtYWNoaW5lSW1hZ2U/OiBJTWFjaGluZUltYWdlO1xuXG4gIC8qKlxuICAgKiBJbnN0YW5jZSB0eXBlIGZvciBtYW5hZ2VyIEVDMiBpbnN0YW5jZS4gSXQncyBhIGNvbWJpbmF0aW9uIG9mIGEgY2xhc3MgYW5kIHNpemUuXG4gICAqIEBkZWZhdWx0IEluc3RhbmNlVHlwZS5vZihJbnN0YW5jZUNsYXNzLlQzLCBJbnN0YW5jZVNpemUuTkFOTylcbiAgICovXG4gIHJlYWRvbmx5IGluc3RhbmNlVHlwZT86IEluc3RhbmNlVHlwZTtcblxuICAvKipcbiAgICogQSBzZXQgb2Ygc2VjdXJpdHkgY3JlZGVudGlhbHMgdGhhdCB5b3UgdXNlIHRvIHByb3ZlIHlvdXIgaWRlbnRpdHkgd2hlbiBjb25uZWN0aW5nIHRvIGFuIEFtYXpvbiBFQzIgaW5zdGFuY2UuIFlvdSB3b24ndCBiZSBhYmxlIHRvIHNzaCBpbnRvIGFuIGluc3RhbmNlIHdpdGhvdXQgdGhlIEtleSBQYWlyLlxuICAgKi9cbiAgcmVhZG9ubHkga2V5UGFpck5hbWU/OiBzdHJpbmc7XG5cbiAgcmVhZG9ubHkgZG9ja2VyTWFjaGluZVZlcnNpb24/OiBEb2NrZXJNYWNoaW5lVmVyc2lvbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHaXRsYWJSdW5uZXJBdXRvc2NhbGluZ01hbmFnZXJQcm9wcyBleHRlbmRzIEdpdGxhYlJ1bm5lckF1dG9zY2FsaW5nTWFuYWdlckJhc2VQcm9wcyB7XG4gIHJlYWRvbmx5IGdsb2JhbENvbmZpZ3VyYXRpb24/OiBHbG9iYWxDb25maWd1cmF0aW9uO1xuICByZWFkb25seSBydW5uZXJzOiBHaXRsYWJSdW5uZXJBdXRvc2NhbGluZ0pvYlJ1bm5lcltdO1xuICByZWFkb25seSBuZXR3b3JrOiBOZXR3b3JrO1xuICByZWFkb25seSBjYWNoZUJ1Y2tldDogSUJ1Y2tldDtcbiAgcmVhZG9ubHkgcm9sZT86IElSb2xlO1xuICByZWFkb25seSBydW5uZXJzU2VjdXJpdHlHcm91cDogU2VjdXJpdHlHcm91cDtcbn1cblxuY29uc3QgREVGQVVMVF9TU0hfS0VZX1BBVEggPSBcIi9ldGMvZ2l0bGFiLXJ1bm5lci9zc2gtY3VzdG9tXCI7XG5cbi8qKlxuICogU2V0dGluZ3MgZm9yIHRoZSBtYW5hZ2VyIChjb29yZGluYXRvcilcbiAqXG4gKiAgTWFuYWdlciBjb29yZGluYXRlcyB0aGUgcGxhY2VtZW50IG9mIHJ1bm5lciAoam9iIGV4ZWN1dG9yKSBpbnN0YW5jZXNcbiAqL1xuZXhwb3J0IGNsYXNzIEdpdGxhYlJ1bm5lckF1dG9zY2FsaW5nTWFuYWdlciBleHRlbmRzIENvbnN0cnVjdCB7XG4gIHJlYWRvbmx5IG1hY2hpbmVJbWFnZTogSU1hY2hpbmVJbWFnZTtcbiAgcmVhZG9ubHkgaW5zdGFuY2VUeXBlOiBJbnN0YW5jZVR5cGU7XG4gIHJlYWRvbmx5IGtleVBhaXJOYW1lPzogc3RyaW5nO1xuICByZWFkb25seSBydW5uZXJzOiBHaXRsYWJSdW5uZXJBdXRvc2NhbGluZ0pvYlJ1bm5lcltdO1xuICByZWFkb25seSBuZXR3b3JrOiBOZXR3b3JrO1xuICByZWFkb25seSBydW5uZXJzU2VjdXJpdHlHcm91cE5hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgcm9sZTogSVJvbGU7XG4gIHJlYWRvbmx5IGluaXRDb25maWc6IENsb3VkRm9ybWF0aW9uSW5pdDtcbiAgcmVhZG9ubHkgdXNlckRhdGE6IFVzZXJEYXRhO1xuICByZWFkb25seSBjYWNoZUJ1Y2tldDogSUJ1Y2tldDtcbiAgcmVhZG9ubHkgZ2xvYmFsQ29uZmlndXJhdGlvbjogR2xvYmFsQ29uZmlndXJhdGlvbjtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogR2l0bGFiUnVubmVyQXV0b3NjYWxpbmdNYW5hZ2VyUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuICAgIHRoaXMuZ2xvYmFsQ29uZmlndXJhdGlvbiA9XG4gICAgICBwcm9wcy5nbG9iYWxDb25maWd1cmF0aW9uIHx8XG4gICAgICAoe1xuICAgICAgICBjb25jdXJyZW50OiAxMCxcbiAgICAgICAgY2hlY2tJbnRlcnZhbDogMCxcbiAgICAgICAgbG9nRm9ybWF0OiBcInJ1bm5lclwiLFxuICAgICAgICBsb2dMZXZlbDogXCJpbmZvXCIsXG4gICAgICB9IGFzIEdsb2JhbENvbmZpZ3VyYXRpb24pO1xuICAgIHRoaXMubWFjaGluZUltYWdlID1cbiAgICAgIHByb3BzLm1hY2hpbmVJbWFnZSA/P1xuICAgICAgTWFjaGluZUltYWdlLmxhdGVzdEFtYXpvbkxpbnV4KHtcbiAgICAgICAgZ2VuZXJhdGlvbjogQW1hem9uTGludXhHZW5lcmF0aW9uLkFNQVpPTl9MSU5VWF8yLFxuICAgICAgICBlZGl0aW9uOiBBbWF6b25MaW51eEVkaXRpb24uU1RBTkRBUkQsXG4gICAgICAgIHZpcnR1YWxpemF0aW9uOiBBbWF6b25MaW51eFZpcnQuSFZNLFxuICAgICAgICBzdG9yYWdlOiBBbWF6b25MaW51eFN0b3JhZ2UuRUJTLFxuICAgICAgICBjcHVUeXBlOiBBbWF6b25MaW51eENwdVR5cGUuWDg2XzY0LFxuICAgICAgfSk7XG4gICAgdGhpcy5pbnN0YW5jZVR5cGUgPSBwcm9wcy5pbnN0YW5jZVR5cGUgPz8gSW5zdGFuY2VUeXBlLm9mKEluc3RhbmNlQ2xhc3MuVDMsIEluc3RhbmNlU2l6ZS5OQU5PKTtcbiAgICB0aGlzLmtleVBhaXJOYW1lID0gcHJvcHMua2V5UGFpck5hbWU7XG4gICAgdGhpcy5ydW5uZXJzID0gcHJvcHMucnVubmVycztcbiAgICB0aGlzLm5ldHdvcmsgPSBwcm9wcy5uZXR3b3JrO1xuICAgIHRoaXMuY2FjaGVCdWNrZXQgPSBwcm9wcy5jYWNoZUJ1Y2tldDtcbiAgICB0aGlzLnJ1bm5lcnNTZWN1cml0eUdyb3VwTmFtZSA9IHByb3BzLnJ1bm5lcnNTZWN1cml0eUdyb3VwLnNlY3VyaXR5R3JvdXBOYW1lO1xuXG4gICAgdGhpcy5yb2xlID1cbiAgICAgIHByb3BzLnJvbGUgfHxcbiAgICAgIG5ldyBSb2xlKHNjb3BlLCBcIk1hbmFnZXJSb2xlXCIsIHtcbiAgICAgICAgYXNzdW1lZEJ5OiBuZXcgU2VydmljZVByaW5jaXBhbChcImVjMi5hbWF6b25hd3MuY29tXCIsIHt9KSxcbiAgICAgICAgbWFuYWdlZFBvbGljaWVzOiBbTWFuYWdlZFBvbGljeS5mcm9tQXdzTWFuYWdlZFBvbGljeU5hbWUoXCJBbWF6b25TU01NYW5hZ2VkSW5zdGFuY2VDb3JlXCIpXSxcbiAgICAgICAgaW5saW5lUG9saWNpZXM6IHtcbiAgICAgICAgICBDYWNoZTogUG9saWN5RG9jdW1lbnQuZnJvbUpzb24oe1xuICAgICAgICAgICAgVmVyc2lvbjogXCIyMDEyLTEwLTE3XCIsXG4gICAgICAgICAgICBTdGF0ZW1lbnQ6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIEVmZmVjdDogXCJBbGxvd1wiLFxuICAgICAgICAgICAgICAgIEFjdGlvbjogW1wiczM6TGlzdE9iamVjdHMqXCIsIFwiczM6R2V0T2JqZWN0KlwiLCBcInMzOkRlbGV0ZU9iamVjdCpcIiwgXCJzMzpQdXRPYmplY3QqXCJdLFxuICAgICAgICAgICAgICAgIFJlc291cmNlOiBbYCR7dGhpcy5jYWNoZUJ1Y2tldC5idWNrZXRBcm59LypgXSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIEVmZmVjdDogXCJBbGxvd1wiLFxuICAgICAgICAgICAgICAgIEFjdGlvbjogW1wiczM6TGlzdEJ1Y2tldFwiXSxcbiAgICAgICAgICAgICAgICBSZXNvdXJjZTogW2Ake3RoaXMuY2FjaGVCdWNrZXQuYnVja2V0QXJufWBdLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBSdW5uZXJzOiBQb2xpY3lEb2N1bWVudC5mcm9tSnNvbih7XG4gICAgICAgICAgICBWZXJzaW9uOiBcIjIwMTItMTAtMTdcIixcbiAgICAgICAgICAgIFN0YXRlbWVudDogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgRWZmZWN0OiBcIkFsbG93XCIsXG4gICAgICAgICAgICAgICAgQWN0aW9uOiBbXCJlYzI6Q3JlYXRlS2V5UGFpclwiLCBcImVjMjpEZWxldGVLZXlQYWlyXCIsIFwiZWMyOkltcG9ydEtleVBhaXJcIiwgXCJlYzI6RGVzY3JpYmUqXCJdLFxuICAgICAgICAgICAgICAgIFJlc291cmNlOiBbXCIqXCJdLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgRWZmZWN0OiBcIkFsbG93XCIsXG4gICAgICAgICAgICAgICAgQWN0aW9uOiBbXCJlYzI6Q3JlYXRlVGFnc1wiLCBcInNzbTpVcGRhdGVJbnN0YW5jZUluZm9ybWF0aW9uXCJdLFxuICAgICAgICAgICAgICAgIFJlc291cmNlOiBbXCIqXCJdLFxuICAgICAgICAgICAgICAgIENvbmRpdGlvbjoge1xuICAgICAgICAgICAgICAgICAgU3RyaW5nTGlrZToge1xuICAgICAgICAgICAgICAgICAgICBcImF3czpSZXF1ZXN0VGFnL05hbWVcIjogXCIqZ2l0bGFiLXJ1bm5lci0qXCIsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgXCJGb3JBbGxWYWx1ZXM6U3RyaW5nRXF1YWxzXCI6IHtcbiAgICAgICAgICAgICAgICAgICAgXCJhd3M6VGFnS2V5c1wiOiBbXCJOYW1lXCJdLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgRWZmZWN0OiBcIkFsbG93XCIsXG4gICAgICAgICAgICAgICAgQWN0aW9uOiBbXCJlYzI6UmVxdWVzdFNwb3RJbnN0YW5jZXNcIiwgXCJlYzI6Q2FuY2VsU3BvdEluc3RhbmNlUmVxdWVzdHNcIl0sXG4gICAgICAgICAgICAgICAgUmVzb3VyY2U6IFtcIipcIl0sXG4gICAgICAgICAgICAgICAgQ29uZGl0aW9uOiB7XG4gICAgICAgICAgICAgICAgICBTdHJpbmdFcXVhbHNJZkV4aXN0czoge1xuICAgICAgICAgICAgICAgICAgICBcImVjMjpSZWdpb25cIjogYCR7U3RhY2sub2YodGhpcykucmVnaW9ufWAsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgQXJuRXF1YWxzSWZFeGlzdHM6IHtcbiAgICAgICAgICAgICAgICAgICAgXCJlYzI6VnBjXCI6IGBhcm46YXdzOmVjMjoke1N0YWNrLm9mKHRoaXMpLnJlZ2lvbn06JHtTdGFjay5vZih0aGlzKS5hY2NvdW50fTp2cGMvJHtcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLm5ldHdvcmsudnBjLnZwY0lkXG4gICAgICAgICAgICAgICAgICAgIH1gLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgRWZmZWN0OiBcIkFsbG93XCIsXG4gICAgICAgICAgICAgICAgQWN0aW9uOiBbXCJlYzI6UnVuSW5zdGFuY2VzXCJdLFxuICAgICAgICAgICAgICAgIFJlc291cmNlOiBbXCIqXCJdLFxuICAgICAgICAgICAgICAgIENvbmRpdGlvbjoge1xuICAgICAgICAgICAgICAgICAgXCJGb3JBbGxWYWx1ZXM6U3RyaW5nRXF1YWxzXCI6IHtcbiAgICAgICAgICAgICAgICAgICAgXCJlYzI6SW5zdGFuY2VUeXBlXCI6ICh0aGlzLnJ1bm5lcnMgfHwgW10pLm1hcCgocnVubmVyKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgY29uc3QgcnVubmVyc0luc3RhbmNlVHlwZSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAodGhpcy5ydW5uZXJzICYmIHJ1bm5lci5pbnN0YW5jZVR5cGUpIHx8IEluc3RhbmNlVHlwZS5vZihJbnN0YW5jZUNsYXNzLlQzLCBJbnN0YW5jZVNpemUuTUlDUk8pO1xuICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBydW5uZXJzSW5zdGFuY2VUeXBlLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgRWZmZWN0OiBcIkFsbG93XCIsXG4gICAgICAgICAgICAgICAgQWN0aW9uOiBbXCJlYzI6VGVybWluYXRlSW5zdGFuY2VzXCIsIFwiZWMyOlN0b3BJbnN0YW5jZXNcIiwgXCJlYzI6U3RhcnRJbnN0YW5jZXNcIiwgXCJlYzI6UmVib290SW5zdGFuY2VzXCJdLFxuICAgICAgICAgICAgICAgIFJlc291cmNlOiBbXCIqXCJdLFxuICAgICAgICAgICAgICAgIENvbmRpdGlvbjoge1xuICAgICAgICAgICAgICAgICAgU3RyaW5nTGlrZToge1xuICAgICAgICAgICAgICAgICAgICBcImVjMjpSZXNvdXJjZVRhZy9OYW1lXCI6IFwiKmdpdGxhYi1ydW5uZXItKlwiLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgRWZmZWN0OiBcIkFsbG93XCIsXG4gICAgICAgICAgICAgICAgQWN0aW9uOiBbXCJpYW06UGFzc1JvbGVcIl0sXG4gICAgICAgICAgICAgICAgUmVzb3VyY2U6IFtcIipcIl0sXG4gICAgICAgICAgICAgICAgQ29uZGl0aW9uOiB7XG4gICAgICAgICAgICAgICAgICBcIkZvckFsbFZhbHVlczpTdHJpbmdFcXVhbHNcIjoge1xuICAgICAgICAgICAgICAgICAgICBcImF3czpUYWdLZXlzXCI6IFtcIlJ1bm5lcnNSb2xlXCJdLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBFQ1JMb2dpbjogUG9saWN5RG9jdW1lbnQuZnJvbUpzb24oe1xuICAgICAgICAgICAgVmVyc2lvbjogXCIyMDEyLTEwLTE3XCIsXG4gICAgICAgICAgICBTdGF0ZW1lbnQ6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIEVmZmVjdDogXCJBbGxvd1wiLFxuICAgICAgICAgICAgICAgIEFjdGlvbjogW1wiZWNyOkJhdGNoR2V0SW1hZ2VcIiwgXCJlY3I6R2V0QXV0aG9yaXphdGlvblRva2VuXCIsIFwiZWNyOkdldERvd25sb2FkVXJsRm9yTGF5ZXJcIl0sXG4gICAgICAgICAgICAgICAgUmVzb3VyY2U6IFwiKlwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgdGhpcy51c2VyRGF0YSA9IFVzZXJEYXRhLmZvckxpbnV4KHt9KTtcbiAgICB0aGlzLnVzZXJEYXRhLmFkZENvbW1hbmRzKFxuICAgICAgYHl1bSB1cGRhdGUgLXkgYXdzLWNmbi1ib290c3RyYXBgLCAvLyAhL2Jpbi9iYXNoIC14ZVxuICAgICAgYHl1bSBpbnN0YWxsIC15IGFtYXpvbi1lY3ItY3JlZGVudGlhbC1oZWxwZXJgXG4gICAgKTtcblxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9hd3NsYWJzL2FtYXpvbi1lY3ItY3JlZGVudGlhbC1oZWxwZXJcbiAgICBjb25zdCB1c2VyRGF0YVJ1bm5lcnMgPSBVc2VyRGF0YS5mb3JMaW51eCh7fSk7XG4gICAgdXNlckRhdGFSdW5uZXJzLmFkZENvbW1hbmRzKFxuICAgICAgYFsgISAteiBcIiQod2hpY2ggYXB0LWdldClcIiBdICYmIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSBhbWF6b24tZWNyLWNyZWRlbnRpYWwtaGVscGVyYCxcbiAgICAgIGBbICEgLXogXCIkKHdoaWNoIHl1bSlcIiBdICYmIHl1bSBpbnN0YWxsIC15IGFtYXpvbi1lY3ItY3JlZGVudGlhbC1oZWxwZXJgXG4gICAgKTtcblxuICAgIGNvbnN0IGdpdGxhYlJ1bm5lckNvbmZpZ1Jlc3RhcnRIYW5kbGUgPSBuZXcgSW5pdFNlcnZpY2VSZXN0YXJ0SGFuZGxlKCk7XG4gICAgZ2l0bGFiUnVubmVyQ29uZmlnUmVzdGFydEhhbmRsZS5fYWRkRmlsZShcIi9ldGMvZ2l0bGFiLXJ1bm5lci9jb25maWcudG9tbFwiKTtcblxuICAgIGNvbnN0IHJzeXNsb2dDb25maWdSZXN0YXJ0SGFuZGxlID0gbmV3IEluaXRTZXJ2aWNlUmVzdGFydEhhbmRsZSgpO1xuICAgIHJzeXNsb2dDb25maWdSZXN0YXJ0SGFuZGxlLl9hZGRGaWxlKFwiL2V0Yy9yc3lzbG9nLmQvMjUtZ2l0bGFiLXJ1bm5lci5jb25mXCIpO1xuXG4gICAgLyoqXG4gICAgICogQ29uZmlnIHNldCBrZXlzXG4gICAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtaW5pdC5odG1sI2F3cy1yZXNvdXJjZS1pbml0LWNvbmZpZ3NldHNcbiAgICAgKi9cbiAgICBjb25zdCBSRVBPU0lUT1JJRVMgPSBcInJlcG9zaXRvcmllc1wiO1xuICAgIGNvbnN0IFBBQ0tBR0VTID0gXCJwYWNrYWdlc1wiO1xuICAgIGNvbnN0IENPTkZJRyA9IFwiY29uZmlnXCI7XG4gICAgY29uc3QgUkVTVEFSVCA9IFwicmVzdGFydFwiO1xuXG4gICAgdGhpcy5pbml0Q29uZmlnID0gQ2xvdWRGb3JtYXRpb25Jbml0LmZyb21Db25maWdTZXRzKHtcbiAgICAgIGNvbmZpZ1NldHM6IHtcbiAgICAgICAgZGVmYXVsdDogW1JFUE9TSVRPUklFUywgUEFDS0FHRVMsIENPTkZJRywgUkVTVEFSVF0sXG4gICAgICB9LFxuICAgICAgY29uZmlnczoge1xuICAgICAgICBbUkVQT1NJVE9SSUVTXTogbmV3IEluaXRDb25maWcoW1xuICAgICAgICAgIEluaXRDb21tYW5kLnNoZWxsQ29tbWFuZChcbiAgICAgICAgICAgIFwiY3VybCAtTCBodHRwczovL3BhY2thZ2VzLmdpdGxhYi5jb20vaW5zdGFsbC9yZXBvc2l0b3JpZXMvcnVubmVyL2dpdGxhYi1ydW5uZXIvc2NyaXB0LnJwbS5zaCB8IGJhc2hcIixcbiAgICAgICAgICAgIHsga2V5OiBcIjEwLWdpdGxhYi1ydW5uZXJcIiB9XG4gICAgICAgICAgKSxcbiAgICAgICAgXSksXG4gICAgICAgIFtQQUNLQUdFU106IG5ldyBJbml0Q29uZmlnKFtcbiAgICAgICAgICBJbml0UGFja2FnZS55dW0oXCJkb2NrZXJcIiksXG4gICAgICAgICAgSW5pdFBhY2thZ2UueXVtKFwiZ2l0bGFiLXJ1bm5lclwiKSxcbiAgICAgICAgICBJbml0UGFja2FnZS55dW0oXCJ0emRhdGFcIiksXG4gICAgICAgICAgSW5pdFBhY2thZ2UueXVtKFwianFcIiksXG4gICAgICAgICAgSW5pdENvbW1hbmQuc2hlbGxDb21tYW5kKFxuICAgICAgICAgICAgYGN1cmwgLUwgaHR0cHM6Ly9naXRsYWItZG9ja2VyLW1hY2hpbmUtZG93bmxvYWRzLnMzLmFtYXpvbmF3cy5jb20vJHtcbiAgICAgICAgICAgICAgcHJvcHMuZG9ja2VyTWFjaGluZVZlcnNpb24/LnZlcnNpb24gPz8gRG9ja2VyTWFjaGluZVZlcnNpb24uVjBfMTZfMl9HSVRMQUJfMTUudmVyc2lvblxuICAgICAgICAgICAgfS9kb2NrZXItbWFjaGluZS1cXGB1bmFtZSAtc1xcYC1cXGB1bmFtZSAtbVxcYCA+IC90bXAvZG9ja2VyLW1hY2hpbmUgJiYgaW5zdGFsbCAvdG1wL2RvY2tlci1tYWNoaW5lIC91c3IvYmluL2RvY2tlci1tYWNoaW5lYCxcbiAgICAgICAgICAgIC8vXCJjdXJsIC1MIGh0dHBzOi8vZ2l0aHViLmNvbS9kb2NrZXIvbWFjaGluZS9yZWxlYXNlcy9kb3dubG9hZC92MC4xNi4yL2RvY2tlci1tYWNoaW5lLWB1bmFtZSAtc2AtYHVuYW1lIC1tYCA+IC90bXAvZG9ja2VyLW1hY2hpbmUgJiYgaW5zdGFsbCAvdG1wL2RvY2tlci1tYWNoaW5lIC91c3IvYmluL2RvY2tlci1tYWNoaW5lXCIsXG4gICAgICAgICAgICB7IGtleTogXCIxMC1kb2NrZXItbWFjaGluZVwiIH1cbiAgICAgICAgICApLFxuICAgICAgICAgIEluaXRDb21tYW5kLnNoZWxsQ29tbWFuZChcImdpdGxhYi1ydW5uZXIgc3RhcnRcIiwge1xuICAgICAgICAgICAga2V5OiBcIjIwLWdpdGxhYi1ydW5uZXItc3RhcnRcIixcbiAgICAgICAgICB9KSxcbiAgICAgICAgXSksXG4gICAgICAgIFtDT05GSUddOiBuZXcgSW5pdENvbmZpZyhbXG4gICAgICAgICAgSW5pdEZpbGUuZnJvbVN0cmluZyhcbiAgICAgICAgICAgIFwiL2V0Yy9naXRsYWItcnVubmVyL2NvbmZpZy50b21sXCIsXG4gICAgICAgICAgICBDb25maWd1cmF0aW9uTWFwcGVyLndpdGhEZWZhdWx0cyh7XG4gICAgICAgICAgICAgIGdsb2JhbENvbmZpZ3VyYXRpb246IHRoaXMuZ2xvYmFsQ29uZmlndXJhdGlvbixcbiAgICAgICAgICAgICAgcnVubmVyc0NvbmZpZ3VyYXRpb246IHRoaXMucnVubmVycy5tYXAoKHJ1bm5lcikgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbmZpZ3VyYXRpb24gPSBydW5uZXIuY29uZmlndXJhdGlvbjtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgLi4uY29uZmlndXJhdGlvbixcbiAgICAgICAgICAgICAgICAgIG1hY2hpbmU6IHtcbiAgICAgICAgICAgICAgICAgICAgLi4uY29uZmlndXJhdGlvbi5tYWNoaW5lLFxuICAgICAgICAgICAgICAgICAgICBtYWNoaW5lT3B0aW9uczoge1xuICAgICAgICAgICAgICAgICAgICAgIHNzaEtleXBhdGg6XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBkcml2ZXJzL2FtYXpvbmVjMi9hbWF6b25lYzIuZ28gU1NIUHJpdmF0ZUtleVBhdGhcbiAgICAgICAgICAgICAgICAgICAgICAgIHJ1bm5lci5rZXlQYWlyXG4gICAgICAgICAgICAgICAgICAgICAgICAgID8gYCR7REVGQVVMVF9TU0hfS0VZX1BBVEh9LyR7Y29uZmlndXJhdGlvbi5tYWNoaW5lPy5tYWNoaW5lT3B0aW9ucz8ua2V5cGFpck5hbWV9YFxuICAgICAgICAgICAgICAgICAgICAgICAgICA6IFwiXCIsXG4gICAgICAgICAgICAgICAgICAgICAgLi4uY29uZmlndXJhdGlvbi5tYWNoaW5lPy5tYWNoaW5lT3B0aW9ucyxcbiAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZVR5cGU6IHJ1bm5lci5pbnN0YW5jZVR5cGUudG9TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICAgICAgICBhbWk6IHJ1bm5lci5tYWNoaW5lSW1hZ2UuZ2V0SW1hZ2Uoc2NvcGUpLmltYWdlSWQsXG4gICAgICAgICAgICAgICAgICAgICAgcmVnaW9uOiBTdGFjay5vZih0aGlzKS5yZWdpb24sXG4gICAgICAgICAgICAgICAgICAgICAgdnBjSWQ6IHRoaXMubmV0d29yay52cGMudnBjSWQsXG4gICAgICAgICAgICAgICAgICAgICAgem9uZTogdGhpcy5uZXR3b3JrLmF2YWlsYWJpbGl0eVpvbmUuc2xpY2UoLTEpLFxuICAgICAgICAgICAgICAgICAgICAgIHN1Ym5ldElkOiB0aGlzLm5ldHdvcmsuc3VibmV0LnN1Ym5ldElkLFxuICAgICAgICAgICAgICAgICAgICAgIHNlY3VyaXR5R3JvdXA6IHRoaXMucnVubmVyc1NlY3VyaXR5R3JvdXBOYW1lLFxuICAgICAgICAgICAgICAgICAgICAgIHByaXZhdGVBZGRyZXNzT25seTpcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZ3VyYXRpb24ubWFjaGluZT8ubWFjaGluZU9wdGlvbnM/LnByaXZhdGVBZGRyZXNzT25seSA/PyB0aGlzLm5ldHdvcmsuaGFzUHJpdmF0ZVN1Ym5ldHMoKSxcbiAgICAgICAgICAgICAgICAgICAgICB1c2VQcml2YXRlQWRkcmVzczogY29uZmlndXJhdGlvbi5tYWNoaW5lPy5tYWNoaW5lT3B0aW9ucz8udXNlUHJpdmF0ZUFkZHJlc3MgPz8gdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICBpYW1JbnN0YW5jZVByb2ZpbGU6IHJ1bm5lci5pbnN0YW5jZVByb2ZpbGUucmVmLFxuICAgICAgICAgICAgICAgICAgICAgIHVzZXJkYXRhOiBcIi9ldGMvZ2l0bGFiLXJ1bm5lci91c2VyX2RhdGFfcnVubmVyc1wiLFxuICAgICAgICAgICAgICAgICAgICAgIGVuZ2luZUluc3RhbGxVcmw6XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25maWd1cmF0aW9uLm1hY2hpbmU/Lm1hY2hpbmVPcHRpb25zPy5lbmdpbmVJbnN0YWxsVXJsID8/XG4gICAgICAgICAgICAgICAgICAgICAgICBcImh0dHBzOi8vcmVsZWFzZXMucmFuY2hlci5jb20vaW5zdGFsbC1kb2NrZXIvMjAuMTAuMjEuc2hcIixcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBjYWNoZToge1xuICAgICAgICAgICAgICAgICAgICBzMzoge1xuICAgICAgICAgICAgICAgICAgICAgIHNlcnZlckFkZHJlc3M6IGBzMy4ke1N0YWNrLm9mKHRoaXMpLnVybFN1ZmZpeH1gLFxuICAgICAgICAgICAgICAgICAgICAgIGJ1Y2tldE5hbWU6IGAke3RoaXMuY2FjaGVCdWNrZXQuYnVja2V0TmFtZX1gLFxuICAgICAgICAgICAgICAgICAgICAgIGJ1Y2tldExvY2F0aW9uOiBgJHtTdGFjay5vZih0aGlzKS5yZWdpb259YCxcbiAgICAgICAgICAgICAgICAgICAgICBhdXRoZW50aWNhdGlvblR5cGU6IFwiaWFtXCIsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0gYXMgUnVubmVyQ29uZmlndXJhdGlvbjtcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9KS50b1RvbWwoKSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgb3duZXI6IFwiZ2l0bGFiLXJ1bm5lclwiLFxuICAgICAgICAgICAgICBncm91cDogXCJnaXRsYWItcnVubmVyXCIsXG4gICAgICAgICAgICAgIG1vZGU6IFwiMDAwNjAwXCIsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgKSxcbiAgICAgICAgICBJbml0RmlsZS5mcm9tU3RyaW5nKFxuICAgICAgICAgICAgXCIvZXRjL3JzeXNsb2cuZC8yNS1naXRsYWItcnVubmVyLmNvbmZcIixcbiAgICAgICAgICAgIGA6cHJvZ3JhbW5hbWUsIGlzZXF1YWwsIFwiZ2l0bGFiLXJ1bm5lclwiIC92YXIvbG9nL2dpdGxhYi1ydW5uZXIubG9nYCxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgb3duZXI6IFwicm9vdFwiLFxuICAgICAgICAgICAgICBncm91cDogXCJyb290XCIsXG4gICAgICAgICAgICAgIG1vZGU6IFwiMDAwNjQ0XCIsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgKSxcbiAgICAgICAgICBJbml0U2VydmljZS5lbmFibGUoXCJnaXRsYWItcnVubmVyXCIsIHtcbiAgICAgICAgICAgIGVuc3VyZVJ1bm5pbmc6IHRydWUsXG4gICAgICAgICAgICBlbmFibGVkOiB0cnVlLFxuICAgICAgICAgICAgc2VydmljZVJlc3RhcnRIYW5kbGU6IGdpdGxhYlJ1bm5lckNvbmZpZ1Jlc3RhcnRIYW5kbGUsXG4gICAgICAgICAgfSksXG4gICAgICAgICAgSW5pdFNlcnZpY2UuZW5hYmxlKFwicnN5c2xvZ1wiLCB7XG4gICAgICAgICAgICBlbnN1cmVSdW5uaW5nOiB0cnVlLFxuICAgICAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgICAgIHNlcnZpY2VSZXN0YXJ0SGFuZGxlOiByc3lzbG9nQ29uZmlnUmVzdGFydEhhbmRsZSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBJbml0Q29tbWFuZC5zaGVsbENvbW1hbmQoXG4gICAgICAgICAgICAvLyBEb3dubG9hZCBjdXN0b20gRUMyIGtleSBwYWlyIGZvciBtYW5hZ2VyIDw+IHJ1bm5lciBzc2ggY29ubmVjdFxuICAgICAgICAgICAgdGhpcy5ydW5uZXJzXG4gICAgICAgICAgICAgIC5tYXAoKHJ1bm5lcikgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghcnVubmVyLmtleVBhaXIpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBcIlwiO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJ1bm5lci5rZXlQYWlyLmdyYW50UmVhZCh0aGlzLnJvbGUpO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgcmVnaW9uID0gU3RhY2sub2YodGhpcykucmVnaW9uO1xuICAgICAgICAgICAgICAgIGNvbnN0IHNlY3JldEFybiA9IHJ1bm5lci5rZXlQYWlyLnNlY3JldEFybjtcbiAgICAgICAgICAgICAgICBjb25zdCBrZXlQYWlyTmFtZSA9IHJ1bm5lci5jb25maWd1cmF0aW9uLm1hY2hpbmUhLm1hY2hpbmVPcHRpb25zIS5rZXlwYWlyTmFtZTtcbiAgICAgICAgICAgICAgICBjb25zdCBzc2hLZXlQYXRoID0gcnVubmVyLmNvbmZpZ3VyYXRpb24ubWFjaGluZSEubWFjaGluZU9wdGlvbnMhLnNzaEtleXBhdGggPz8gREVGQVVMVF9TU0hfS0VZX1BBVEg7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgICAgICAgYG1rZGlyIC1wICR7c3NoS2V5UGF0aH07YCxcbiAgICAgICAgICAgICAgICAgIGBlY2hvICQoYXdzIHNlY3JldHNtYW5hZ2VyIGdldC1zZWNyZXQtdmFsdWUgLS1yZWdpb24gJHtyZWdpb259IC0tc2VjcmV0LWlkICR7c2VjcmV0QXJufSAtLXF1ZXJ5IFNlY3JldFN0cmluZyAtLW91dHB1dCB0ZXh0KSB8IGpxIC1yICcuXCIke2tleVBhaXJOYW1lfVwiJyA+ICR7c3NoS2V5UGF0aH0vJHtrZXlQYWlyTmFtZX07YCxcbiAgICAgICAgICAgICAgICAgIGBlY2hvICQoYXdzIHNlY3JldHNtYW5hZ2VyIGdldC1zZWNyZXQtdmFsdWUgLS1yZWdpb24gJHtyZWdpb259IC0tc2VjcmV0LWlkICR7c2VjcmV0QXJufSAtLXF1ZXJ5IFNlY3JldFN0cmluZyAtLW91dHB1dCB0ZXh0KSB8IGpxIC1yICcuXCIke2tleVBhaXJOYW1lfS5wdWJcIicgPiAke3NzaEtleVBhdGh9LyR7a2V5UGFpck5hbWV9LnB1YjtgLFxuICAgICAgICAgICAgICAgIF0uam9pbihcIlxcblwiKTtcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgLmZpbHRlcigocykgPT4gcy5sZW5ndGggPiAwKVxuICAgICAgICAgICAgICAuam9pbihcIlxcblwiKSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAga2V5OiBcIjk5OS1yZXRyaWV2ZS1lYzIta2V5LXBhaXJcIixcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApLFxuICAgICAgICAgIEluaXRGaWxlLmZyb21TdHJpbmcoXCIvZXRjL2dpdGxhYi1ydW5uZXIvdXNlcl9kYXRhX3J1bm5lcnNcIiwgdXNlckRhdGFSdW5uZXJzLnJlbmRlcigpLCB7XG4gICAgICAgICAgICBvd25lcjogXCJnaXRsYWItcnVubmVyXCIsXG4gICAgICAgICAgICBncm91cDogXCJnaXRsYWItcnVubmVyXCIsXG4gICAgICAgICAgICBtb2RlOiBcIjAwMDYwMFwiLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdKSxcbiAgICAgICAgW1JFU1RBUlRdOiBuZXcgSW5pdENvbmZpZyhbXG4gICAgICAgICAgSW5pdENvbW1hbmQuc2hlbGxDb21tYW5kKFwiZ2l0bGFiLXJ1bm5lciByZXN0YXJ0XCIsIHtcbiAgICAgICAgICAgIGtleTogXCIxMC1naXRsYWItcnVubmVyLXJlc3RhcnRcIixcbiAgICAgICAgICB9KSxcbiAgICAgICAgXSksXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG59XG4iXX0=