@aws/pdk
Version:
All documentation is located at: https://aws.github.io/aws-pdk
154 lines • 26.4 kB
JavaScript
;
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SonarCodeScanner = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0 */
const pdk_nag_1 = require("../../pdk-nag");
const aws_cdk_lib_1 = require("aws-cdk-lib");
const aws_codebuild_1 = require("aws-cdk-lib/aws-codebuild");
const aws_events_1 = require("aws-cdk-lib/aws-events");
const aws_events_targets_1 = require("aws-cdk-lib/aws-events-targets");
const aws_iam_1 = require("aws-cdk-lib/aws-iam");
const aws_secretsmanager_1 = require("aws-cdk-lib/aws-secretsmanager");
const cdk_nag_1 = require("cdk-nag");
const constructs_1 = require("constructs");
const sonarqube_commands_1 = require("./sonarqube-commands");
const unpackSourceAndArtifacts = (includeGlobsForScan) => [
'export BUILT_ARTIFACT_URI=`aws codebuild batch-get-builds --ids $SYNTH_BUILD_ID | jq -r \'.builds[0].secondaryArtifacts[] | select(.artifactIdentifier == "Synth__") | .location\' | awk \'{sub("arn:aws:s3:::","s3://")}1\' $1`',
"export SYNTH_SOURCE_URI=`aws codebuild batch-get-builds --ids $SYNTH_BUILD_ID | jq -r '.builds[0].sourceVersion' | awk '{sub(\"arn:aws:s3:::\",\"s3://\")}1' $1`",
"aws s3 cp $SYNTH_SOURCE_URI source.zip",
"aws s3 cp $BUILT_ARTIFACT_URI built.zip",
"unzip source.zip -d src",
"unzip built.zip -d built",
"rm source.zip built.zip",
`rsync -a built/* src --include="*/" ${includeGlobsForScan
? includeGlobsForScan.map((g) => `--include ${g}`).join(" ")
: ""} --include="**/coverage/**" --include="**/cdk.out/**" --exclude="**/node_modules/**/*" --exclude="**/.env/**" --exclude="*" --prune-empty-dirs`,
];
const owaspScan = () => `npx owasp-dependency-check --format HTML --out src/reports --exclude '**/.git/**/*' --scan src --enableExperimental --bin /tmp/dep-check --disableRetireJS`;
const cfnNagScan = (cdkOutDir, cfnNagIgnorePath) => cdkOutDir
? `cfn_nag ${cfnNagIgnorePath ? `--deny-list-path=${cfnNagIgnorePath}` : ""} built/${cdkOutDir}/**/*.template.json --output-format=json > src/reports/cfn-nag-report.json`
: 'echo "skipping cfn_nag as no cdkOutDir was specified.';
class SonarCodeScanner extends constructs_1.Construct {
constructor(scope, id, props) {
super(scope, id);
const sonarQubeToken = new aws_secretsmanager_1.Secret(this, "SonarQubeToken");
const synthBuildProject = aws_codebuild_1.Project.fromProjectArn(this, "SynthBuildProject", props.synthBuildArn);
const validationProject = new aws_codebuild_1.Project(this, "ValidationProject", {
environment: {
buildImage: aws_codebuild_1.LinuxBuildImage.STANDARD_5_0,
},
environmentVariables: {
SONARQUBE_TOKEN: {
type: aws_codebuild_1.BuildEnvironmentVariableType.SECRETS_MANAGER,
value: sonarQubeToken.secretArn,
},
SONARQUBE_ENDPOINT: {
type: aws_codebuild_1.BuildEnvironmentVariableType.PLAINTEXT,
value: props.sonarqubeEndpoint,
},
PROJECT_NAME: {
type: aws_codebuild_1.BuildEnvironmentVariableType.PLAINTEXT,
value: props.sonarqubeProjectName,
},
},
buildSpec: aws_codebuild_1.BuildSpec.fromObject({
version: "0.2",
env: {
shell: "bash",
},
phases: {
install: {
commands: ["npm install -g aws-cdk", "gem install cfn-nag"],
},
build: {
commands: [
"export RESOLVED_SOURCE_VERSION=`aws codebuild batch-get-builds --ids $SYNTH_BUILD_ID | jq -r '.builds[0].resolvedSourceVersion'`",
...unpackSourceAndArtifacts(props.includeGlobsForScan),
...(0, sonarqube_commands_1.createSonarqubeProject)(props),
"mkdir -p src/reports",
owaspScan(),
cfnNagScan(props.cdkOutDir, props.cfnNagIgnorePath),
"cd src",
(0, sonarqube_commands_1.sonarqubeScanner)(props.excludeGlobsForScan),
...(0, sonarqube_commands_1.generateSonarqubeReports)(),
...(props.preArchiveCommands || []),
],
},
},
}),
});
validationProject.addToRolePolicy(new aws_iam_1.PolicyStatement({
actions: ["codebuild:BatchGetBuilds"],
effect: aws_iam_1.Effect.ALLOW,
resources: [synthBuildProject.projectArn],
}));
validationProject.addToRolePolicy(new aws_iam_1.PolicyStatement({
actions: ["s3:GetObject*"],
effect: aws_iam_1.Effect.ALLOW,
resources: [props.artifactBucketArn, `${props.artifactBucketArn}/**`],
}));
props.artifactBucketKeyArn &&
validationProject.addToRolePolicy(new aws_iam_1.PolicyStatement({
actions: ["kms:Decrypt", "kms:DescribeKey"],
effect: aws_iam_1.Effect.ALLOW,
resources: [props.artifactBucketKeyArn],
}));
synthBuildProject.onBuildSucceeded("OnSynthSuccess", {
target: new aws_events_targets_1.CodeBuildProject(validationProject, {
event: aws_events_1.RuleTargetInput.fromObject({
environmentVariablesOverride: [
{
name: "SYNTH_BUILD_ID",
type: "PLAINTEXT",
value: aws_events_1.EventField.fromPath("$.detail.build-id"),
},
],
}),
}),
});
new aws_cdk_lib_1.CfnOutput(this, "SonarqubeSecretArn", {
value: sonarQubeToken.secretArn,
});
[
"AwsSolutions-SMG4",
"AwsPrototyping-SecretsManagerRotationEnabled",
].forEach((RuleId) => {
cdk_nag_1.NagSuppressions.addResourceSuppressions(sonarQubeToken, [
{
id: RuleId,
reason: "Key rotation is not possible as a user token needs to be generated from Sonarqube",
},
]);
});
const stack = aws_cdk_lib_1.Stack.of(this);
["AwsSolutions-IAM5", "AwsPrototyping-IAMNoWildcardPermissions"].forEach((RuleId) => {
cdk_nag_1.NagSuppressions.addResourceSuppressions(validationProject.role, [
{
id: RuleId,
reason: "Validation CodeBuild project requires access to the ArtifactsBucket and ability to create logs.",
appliesTo: [
{
regex: `/^Resource::arn:${pdk_nag_1.PDKNag.getStackPartitionRegex(stack)}:logs:${pdk_nag_1.PDKNag.getStackRegionRegex(stack)}:${pdk_nag_1.PDKNag.getStackAccountRegex(stack)}:log-group:/aws/codebuild/<.*SonarCodeScannerValidationProject.*>:\\*$/g`,
},
{
regex: `/^Resource::arn:${pdk_nag_1.PDKNag.getStackPartitionRegex(stack)}:codebuild:${pdk_nag_1.PDKNag.getStackRegionRegex(stack)}:${pdk_nag_1.PDKNag.getStackAccountRegex(stack)}:report-group/<.*SonarCodeScannerValidationProject.*>-\\*$/g`,
},
{
regex: `/^Action::s3:GetObject\\*$/g`,
},
{
regex: "/^Resource::<ArtifactsBucket.*.Arn>/\\*\\*$/g",
},
],
},
], true);
});
}
}
exports.SonarCodeScanner = SonarCodeScanner;
_a = JSII_RTTI_SYMBOL_1;
SonarCodeScanner[_a] = { fqn: "@aws/pdk.pipeline.SonarCodeScanner", version: "0.26.14" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29uYXItY29kZS1zY2FubmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic29uYXItY29kZS1zY2FubmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUE7c0NBQ3NDO0FBQ3RDLDBDQUFzQztBQUN0Qyw2Q0FBK0M7QUFDL0MsNkRBS21DO0FBQ25DLHVEQUFxRTtBQUNyRSx1RUFBa0U7QUFDbEUsaURBQThEO0FBQzlELHVFQUF3RDtBQUN4RCxxQ0FBMEM7QUFDMUMsMkNBQXVDO0FBQ3ZDLDZEQUk4QjtBQXFGOUIsTUFBTSx3QkFBd0IsR0FBRyxDQUFDLG1CQUE4QixFQUFFLEVBQUUsQ0FBQztJQUNuRSxrT0FBa087SUFDbE8sa0tBQWtLO0lBQ2xLLHdDQUF3QztJQUN4Qyx5Q0FBeUM7SUFDekMseUJBQXlCO0lBQ3pCLDBCQUEwQjtJQUMxQix5QkFBeUI7SUFDekIsdUNBQ0UsbUJBQW1CO1FBQ2pCLENBQUMsQ0FBQyxtQkFBbUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO1FBQzVELENBQUMsQ0FBQyxFQUNOLGdKQUFnSjtDQUNqSixDQUFDO0FBRUYsTUFBTSxTQUFTLEdBQUcsR0FBRyxFQUFFLENBQ3JCLDRKQUE0SixDQUFDO0FBRS9KLE1BQU0sVUFBVSxHQUFHLENBQUMsU0FBa0IsRUFBRSxnQkFBeUIsRUFBRSxFQUFFLENBQ25FLFNBQVM7SUFDUCxDQUFDLENBQUMsV0FDRSxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsb0JBQW9CLGdCQUFnQixFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQzlELFVBQVUsU0FBUyw0RUFBNEU7SUFDakcsQ0FBQyxDQUFDLHVEQUF1RCxDQUFDO0FBRTlELE1BQWEsZ0JBQWlCLFNBQVEsc0JBQVM7SUFDN0MsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUE0QjtRQUNwRSxLQUFLLENBQUMsS0FB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TSxDQUFDLG9CQUFvQixDQUM5QixLQUFLLENBQ04sMEVBQTBFO3lCQUM1RTt3QkFDRDs0QkFDRSxLQUFLLEVBQUUsbUJBQW1CLGdCQUFNLENBQUMsc0JBQXNCLENBQ3JELEtBQUssQ0FDTixjQUFjLGdCQUFNLENBQUMsbUJBQW1CLENBQ3ZDLEtBQUssQ0FDTixJQUFJLGdCQUFNLENBQUMsb0JBQW9CLENBQzlCLEtBQUssQ0FDTiw4REFBOEQ7eUJBQ2hFO3dCQUNEOzRCQUNFLEtBQUssRUFBRSw4QkFBOEI7eUJBQ3RDO3dCQUNEOzRCQUNFLEtBQUssRUFBRSwrQ0FBK0M7eUJBQ3ZEO3FCQUNGO2lCQUNGO2FBQ0YsRUFDRCxJQUFJLENBQ0wsQ0FBQztRQUNKLENBQUMsQ0FDRixDQUFDO0lBQ0osQ0FBQzs7QUE1SkgsNENBNkpDIiwic291cmNlc0NvbnRlbnQiOlsiLyohIENvcHlyaWdodCBbQW1hem9uLmNvbV0oaHR0cDovL2FtYXpvbi5jb20vKSwgSW5jLiBvciBpdHMgYWZmaWxpYXRlcy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cblNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wICovXG5pbXBvcnQgeyBQREtOYWcgfSBmcm9tIFwiQGF3cy9wZGstbmFnXCI7XG5pbXBvcnQgeyBDZm5PdXRwdXQsIFN0YWNrIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQge1xuICBCdWlsZEVudmlyb25tZW50VmFyaWFibGVUeXBlLFxuICBCdWlsZFNwZWMsXG4gIExpbnV4QnVpbGRJbWFnZSxcbiAgUHJvamVjdCxcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1jb2RlYnVpbGRcIjtcbmltcG9ydCB7IEV2ZW50RmllbGQsIFJ1bGVUYXJnZXRJbnB1dCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtZXZlbnRzXCI7XG5pbXBvcnQgeyBDb2RlQnVpbGRQcm9qZWN0IH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1ldmVudHMtdGFyZ2V0c1wiO1xuaW1wb3J0IHsgRWZmZWN0LCBQb2xpY3lTdGF0ZW1lbnQgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWlhbVwiO1xuaW1wb3J0IHsgU2VjcmV0IH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1zZWNyZXRzbWFuYWdlclwiO1xuaW1wb3J0IHsgTmFnU3VwcHJlc3Npb25zIH0gZnJvbSBcImNkay1uYWdcIjtcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQge1xuICBjcmVhdGVTb25hcnF1YmVQcm9qZWN0LFxuICBnZW5lcmF0ZVNvbmFycXViZVJlcG9ydHMsXG4gIHNvbmFycXViZVNjYW5uZXIsXG59IGZyb20gXCIuL3NvbmFycXViZS1jb21tYW5kc1wiO1xuXG5leHBvcnQgaW50ZXJmYWNlIFNvbmFyQ29kZVNjYW5uZXJDb25maWcge1xuICAvKipcbiAgICogcGF0aCB0byBhIGZpbGUgY29udGFpbmluZyB0aGUgY2ZuIG5hZyBzdXBwcmVzc2lvbiBydWxlcy5cbiAgICovXG4gIHJlYWRvbmx5IGNmbk5hZ0lnbm9yZVBhdGg/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIGRpcmVjdG9yeSBjb250YWluaW5nIHRoZSBzeW50aGVzaXplZCBjZGsgcmVzb3VyY2VzLlxuICAgKi9cbiAgcmVhZG9ubHkgY2RrT3V0RGlyPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBnbG9iIHBhdHRlcm5zIHRvIGV4Y2x1ZGUgZnJvbSBzb25hciBzY2FuLlxuICAgKi9cbiAgcmVhZG9ubHkgZXhjbHVkZUdsb2JzRm9yU2Nhbj86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBnbG9iIHBhdHRlcm5zIHRvIGluY2x1ZGUgZnJvbSBzb25hciBzY2FuLlxuICAgKi9cbiAgcmVhZG9ubHkgaW5jbHVkZUdsb2JzRm9yU2Nhbj86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBlbmRwb2ludCBvZiB0aGUgc29uYXJxdWJlIGluc3RhbmNlIGkuZTogaHR0cHM6Ly88eW91ci1zb25hcnF1YmUtZW5kcG9pbnQ+LlxuICAgKlxuICAgKiBOb3RlOiBFbnN1cmUgYSB0cmFpbGluZyAnLycgaXMgbm90IGluY2x1ZGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgc29uYXJxdWJlRW5kcG9pbnQ6IHN0cmluZztcblxuICAvKipcbiAgICogRGVmYXVsdCBwcm9maWxlL2dhdGUgbmFtZSBpLmU6IHlvdXIgb3JnIHByb2ZpbGUuXG4gICAqXG4gICAqIE5vdGU6IFRoZXNlIG5lZWQgdG8gYmUgc2V0IHVwIGluIFNvbmFycXViZSBtYW51YWxseS5cbiAgICovXG4gIHJlYWRvbmx5IHNvbmFycXViZURlZmF1bHRQcm9maWxlT3JHYXRlTmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBTcGVjaWZpYyBwcm9maWxlL2dhdGUgbmFtZSBpLmU6IGxhbmd1YWdlIHNwZWNpZmljLlxuICAgKlxuICAgKiBOb3RlOiBUaGVzZSBuZWVkIHRvIGJlIHNldCB1cCBpbiBTb25hcnF1YmUgbWFudWFsbHkuXG4gICAqL1xuICByZWFkb25seSBzb25hcnF1YmVTcGVjaWZpY1Byb2ZpbGVPckdhdGVOYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBHcm91cCBuYW1lIGluIFNvbmFycXViZSB3aXRoIGFjY2VzcyB0byBhZG1pbmlzdGVyIHRoaXMgcHJvamVjdC5cbiAgICovXG4gIHJlYWRvbmx5IHNvbmFycXViZUF1dGhvcml6ZWRHcm91cDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBOYW1lIG9mIHRoZSBwcm9qZWN0IHRvIGNyZWF0ZSBpbiBTb25hcnF1YmUuXG4gICAqL1xuICByZWFkb25seSBzb25hcnF1YmVQcm9qZWN0TmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUYWdzIHRvIGFzc29jaWF0ZSB3aXRoIHRoaXMgcHJvamVjdC5cbiAgICovXG4gIHJlYWRvbmx5IHNvbmFycXViZVRhZ3M/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogSG9vayB3aGljaCBhbGxvd3MgY3VzdG9tIGNvbW1hbmRzIHRvIGJlIGV4ZWN1dGVkIGJlZm9yZSB0aGUgcHJvY2VzcyBjb21tZW5jZXMgdGhlIGFyY2hpdmFsIHByb2Nlc3MuXG4gICAqL1xuICByZWFkb25seSBwcmVBcmNoaXZlQ29tbWFuZHM/OiBzdHJpbmdbXTtcbn1cblxuLyoqXG4gKiBTb25hckNvZGVTY2FubmVycyBwcm9wZXJ0aWVzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNvbmFyQ29kZVNjYW5uZXJQcm9wcyBleHRlbmRzIFNvbmFyQ29kZVNjYW5uZXJDb25maWcge1xuICAvKipcbiAgICogQVJOIGZvciB0aGUgQ29kZUJ1aWxkIHRhc2sgcmVzcG9uc2libGUgZm9yIGV4ZWN1dGluZyB0aGUgc3ludGggY29tbWFuZC5cbiAgICovXG4gIHJlYWRvbmx5IHN5bnRoQnVpbGRBcm46IHN0cmluZztcblxuICAvKipcbiAgICogUzMgYnVja2V0IEFSTiBjb250YWluaW5nIHRoZSBidWlsdCBhcnRpZmFjdHMgZnJvbSB0aGUgc3ludGggYnVpbGQuXG4gICAqL1xuICByZWFkb25seSBhcnRpZmFjdEJ1Y2tldEFybjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBcnRpZmFjdCBidWNrZXQga2V5IEFSTiB1c2VkIHRvIGVuY3J5cHQgdGhlIGFydGlmYWN0cy5cbiAgICovXG4gIHJlYWRvbmx5IGFydGlmYWN0QnVja2V0S2V5QXJuPzogc3RyaW5nO1xufVxuXG5jb25zdCB1bnBhY2tTb3VyY2VBbmRBcnRpZmFjdHMgPSAoaW5jbHVkZUdsb2JzRm9yU2Nhbj86IHN0cmluZ1tdKSA9PiBbXG4gICdleHBvcnQgQlVJTFRfQVJUSUZBQ1RfVVJJPWBhd3MgY29kZWJ1aWxkIGJhdGNoLWdldC1idWlsZHMgLS1pZHMgJFNZTlRIX0JVSUxEX0lEIHwganEgLXIgXFwnLmJ1aWxkc1swXS5zZWNvbmRhcnlBcnRpZmFjdHNbXSB8IHNlbGVjdCguYXJ0aWZhY3RJZGVudGlmaWVyID09IFwiU3ludGhfX1wiKSB8IC5sb2NhdGlvblxcJyB8IGF3ayBcXCd7c3ViKFwiYXJuOmF3czpzMzo6OlwiLFwiczM6Ly9cIil9MVxcJyAkMWAnLFxuICBcImV4cG9ydCBTWU5USF9TT1VSQ0VfVVJJPWBhd3MgY29kZWJ1aWxkIGJhdGNoLWdldC1idWlsZHMgLS1pZHMgJFNZTlRIX0JVSUxEX0lEIHwganEgLXIgJy5idWlsZHNbMF0uc291cmNlVmVyc2lvbicgfCBhd2sgJ3tzdWIoXFxcImFybjphd3M6czM6OjpcXFwiLFxcXCJzMzovL1xcXCIpfTEnICQxYFwiLFxuICBcImF3cyBzMyBjcCAkU1lOVEhfU09VUkNFX1VSSSBzb3VyY2UuemlwXCIsXG4gIFwiYXdzIHMzIGNwICRCVUlMVF9BUlRJRkFDVF9VUkkgYnVpbHQuemlwXCIsXG4gIFwidW56aXAgc291cmNlLnppcCAtZCBzcmNcIixcbiAgXCJ1bnppcCBidWlsdC56aXAgLWQgYnVpbHRcIixcbiAgXCJybSBzb3VyY2UuemlwIGJ1aWx0LnppcFwiLFxuICBgcnN5bmMgLWEgYnVpbHQvKiBzcmMgLS1pbmNsdWRlPVwiKi9cIiAke1xuICAgIGluY2x1ZGVHbG9ic0ZvclNjYW5cbiAgICAgID8gaW5jbHVkZUdsb2JzRm9yU2Nhbi5tYXAoKGcpID0+IGAtLWluY2x1ZGUgJHtnfWApLmpvaW4oXCIgXCIpXG4gICAgICA6IFwiXCJcbiAgfSAtLWluY2x1ZGU9XCIqKi9jb3ZlcmFnZS8qKlwiIC0taW5jbHVkZT1cIioqL2Nkay5vdXQvKipcIiAtLWV4Y2x1ZGU9XCIqKi9ub2RlX21vZHVsZXMvKiovKlwiIC0tZXhjbHVkZT1cIioqLy5lbnYvKipcIiAtLWV4Y2x1ZGU9XCIqXCIgLS1wcnVuZS1lbXB0eS1kaXJzYCxcbl07XG5cbmNvbnN0IG93YXNwU2NhbiA9ICgpID0+XG4gIGBucHggb3dhc3AtZGVwZW5kZW5jeS1jaGVjayAtLWZvcm1hdCBIVE1MIC0tb3V0IHNyYy9yZXBvcnRzIC0tZXhjbHVkZSAnKiovLmdpdC8qKi8qJyAtLXNjYW4gc3JjIC0tZW5hYmxlRXhwZXJpbWVudGFsIC0tYmluIC90bXAvZGVwLWNoZWNrIC0tZGlzYWJsZVJldGlyZUpTYDtcblxuY29uc3QgY2ZuTmFnU2NhbiA9IChjZGtPdXREaXI/OiBzdHJpbmcsIGNmbk5hZ0lnbm9yZVBhdGg/OiBzdHJpbmcpID0+XG4gIGNka091dERpclxuICAgID8gYGNmbl9uYWcgJHtcbiAgICAgICAgY2ZuTmFnSWdub3JlUGF0aCA/IGAtLWRlbnktbGlzdC1wYXRoPSR7Y2ZuTmFnSWdub3JlUGF0aH1gIDogXCJcIlxuICAgICAgfSBidWlsdC8ke2Nka091dERpcn0vKiovKi50ZW1wbGF0ZS5qc29uIC0tb3V0cHV0LWZvcm1hdD1qc29uID4gc3JjL3JlcG9ydHMvY2ZuLW5hZy1yZXBvcnQuanNvbmBcbiAgICA6ICdlY2hvIFwic2tpcHBpbmcgY2ZuX25hZyBhcyBubyBjZGtPdXREaXIgd2FzIHNwZWNpZmllZC4nO1xuXG5leHBvcnQgY2xhc3MgU29uYXJDb2RlU2Nhbm5lciBleHRlbmRzIENvbnN0cnVjdCB7XG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBTb25hckNvZGVTY2FubmVyUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgY29uc3Qgc29uYXJRdWJlVG9rZW4gPSBuZXcgU2VjcmV0KHRoaXMsIFwiU29uYXJRdWJlVG9rZW5cIik7XG5cbiAgICBjb25zdCBzeW50aEJ1aWxkUHJvamVjdCA9IFByb2plY3QuZnJvbVByb2plY3RBcm4oXG4gICAgICB0aGlzLFxuICAgICAgXCJTeW50aEJ1aWxkUHJvamVjdFwiLFxuICAgICAgcHJvcHMuc3ludGhCdWlsZEFyblxuICAgICk7XG5cbiAgICBjb25zdCB2YWxpZGF0aW9uUHJvamVjdCA9IG5ldyBQcm9qZWN0KHRoaXMsIFwiVmFsaWRhdGlvblByb2plY3RcIiwge1xuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgYnVpbGRJbWFnZTogTGludXhCdWlsZEltYWdlLlNUQU5EQVJEXzVfMCxcbiAgICAgIH0sXG4gICAgICBlbnZpcm9ubWVudFZhcmlhYmxlczoge1xuICAgICAgICBTT05BUlFVQkVfVE9LRU46IHtcbiAgICAgICAgICB0eXBlOiBCdWlsZEVudmlyb25tZW50VmFyaWFibGVUeXBlLlNFQ1JFVFNfTUFOQUdFUixcbiAgICAgICAgICB2YWx1ZTogc29uYXJRdWJlVG9rZW4uc2VjcmV0QXJuLFxuICAgICAgICB9LFxuICAgICAgICBTT05BUlFVQkVfRU5EUE9JTlQ6IHtcbiAgICAgICAgICB0eXBlOiBCdWlsZEVudmlyb25tZW50VmFyaWFibGVUeXBlLlBMQUlOVEVYVCxcbiAgICAgICAgICB2YWx1ZTogcHJvcHMuc29uYXJxdWJlRW5kcG9pbnQsXG4gICAgICAgIH0sXG4gICAgICAgIFBST0pFQ1RfTkFNRToge1xuICAgICAgICAgIHR5cGU6IEJ1aWxkRW52aXJvbm1lbnRWYXJpYWJsZVR5cGUuUExBSU5URVhULFxuICAgICAgICAgIHZhbHVlOiBwcm9wcy5zb25hcnF1YmVQcm9qZWN0TmFtZSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBidWlsZFNwZWM6IEJ1aWxkU3BlYy5mcm9tT2JqZWN0KHtcbiAgICAgICAgdmVyc2lvbjogXCIwLjJcIixcbiAgICAgICAgZW52OiB7XG4gICAgICAgICAgc2hlbGw6IFwiYmFzaFwiLFxuICAgICAgICB9LFxuICAgICAgICBwaGFzZXM6IHtcbiAgICAgICAgICBpbnN0YWxsOiB7XG4gICAgICAgICAgICBjb21tYW5kczogW1wibnBtIGluc3RhbGwgLWcgYXdzLWNka1wiLCBcImdlbSBpbnN0YWxsIGNmbi1uYWdcIl0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBidWlsZDoge1xuICAgICAgICAgICAgY29tbWFuZHM6IFtcbiAgICAgICAgICAgICAgXCJleHBvcnQgUkVTT0xWRURfU09VUkNFX1ZFUlNJT049YGF3cyBjb2RlYnVpbGQgYmF0Y2gtZ2V0LWJ1aWxkcyAtLWlkcyAkU1lOVEhfQlVJTERfSUQgfCBqcSAtciAnLmJ1aWxkc1swXS5yZXNvbHZlZFNvdXJjZVZlcnNpb24nYFwiLFxuICAgICAgICAgICAgICAuLi51bnBhY2tTb3VyY2VBbmRBcnRpZmFjdHMocHJvcHMuaW5jbHVkZUdsb2JzRm9yU2NhbiksXG4gICAgICAgICAgICAgIC4uLmNyZWF0ZVNvbmFycXViZVByb2plY3QocHJvcHMpLFxuICAgICAgICAgICAgICBcIm1rZGlyIC1wIHNyYy9yZXBvcnRzXCIsXG4gICAgICAgICAgICAgIG93YXNwU2NhbigpLFxuICAgICAgICAgICAgICBjZm5OYWdTY2FuKHByb3BzLmNka091dERpciwgcHJvcHMuY2ZuTmFnSWdub3JlUGF0aCksXG4gICAgICAgICAgICAgIFwiY2Qgc3JjXCIsXG4gICAgICAgICAgICAgIHNvbmFycXViZVNjYW5uZXIocHJvcHMuZXhjbHVkZUdsb2JzRm9yU2NhbiksXG4gICAgICAgICAgICAgIC4uLmdlbmVyYXRlU29uYXJxdWJlUmVwb3J0cygpLFxuICAgICAgICAgICAgICAuLi4ocHJvcHMucHJlQXJjaGl2ZUNvbW1hbmRzIHx8IFtdKSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgIH0pO1xuXG4gICAgdmFsaWRhdGlvblByb2plY3QuYWRkVG9Sb2xlUG9saWN5KFxuICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgIGFjdGlvbnM6IFtcImNvZGVidWlsZDpCYXRjaEdldEJ1aWxkc1wiXSxcbiAgICAgICAgZWZmZWN0OiBFZmZlY3QuQUxMT1csXG4gICAgICAgIHJlc291cmNlczogW3N5bnRoQnVpbGRQcm9qZWN0LnByb2plY3RBcm5dLFxuICAgICAgfSlcbiAgICApO1xuXG4gICAgdmFsaWRhdGlvblByb2plY3QuYWRkVG9Sb2xlUG9saWN5KFxuICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgIGFjdGlvbnM6IFtcInMzOkdldE9iamVjdCpcIl0sXG4gICAgICAgIGVmZmVjdDogRWZmZWN0LkFMTE9XLFxuICAgICAgICByZXNvdXJjZXM6IFtwcm9wcy5hcnRpZmFjdEJ1Y2tldEFybiwgYCR7cHJvcHMuYXJ0aWZhY3RCdWNrZXRBcm59LyoqYF0sXG4gICAgICB9KVxuICAgICk7XG5cbiAgICBwcm9wcy5hcnRpZmFjdEJ1Y2tldEtleUFybiAmJlxuICAgICAgdmFsaWRhdGlvblByb2plY3QuYWRkVG9Sb2xlUG9saWN5KFxuICAgICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICBhY3Rpb25zOiBbXCJrbXM6RGVjcnlwdFwiLCBcImttczpEZXNjcmliZUtleVwiXSxcbiAgICAgICAgICBlZmZlY3Q6IEVmZmVjdC5BTExPVyxcbiAgICAgICAgICByZXNvdXJjZXM6IFtwcm9wcy5hcnRpZmFjdEJ1Y2tldEtleUFybl0sXG4gICAgICAgIH0pXG4gICAgICApO1xuXG4gICAgc3ludGhCdWlsZFByb2plY3Qub25CdWlsZFN1Y2NlZWRlZChcIk9uU3ludGhTdWNjZXNzXCIsIHtcbiAgICAgIHRhcmdldDogbmV3IENvZGVCdWlsZFByb2plY3QodmFsaWRhdGlvblByb2plY3QsIHtcbiAgICAgICAgZXZlbnQ6IFJ1bGVUYXJnZXRJbnB1dC5mcm9tT2JqZWN0KHtcbiAgICAgICAgICBlbnZpcm9ubWVudFZhcmlhYmxlc092ZXJyaWRlOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIG5hbWU6IFwiU1lOVEhfQlVJTERfSURcIixcbiAgICAgICAgICAgICAgdHlwZTogXCJQTEFJTlRFWFRcIixcbiAgICAgICAgICAgICAgdmFsdWU6IEV2ZW50RmllbGQuZnJvbVBhdGgoXCIkLmRldGFpbC5idWlsZC1pZFwiKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSksXG4gICAgICB9KSxcbiAgICB9KTtcblxuICAgIG5ldyBDZm5PdXRwdXQodGhpcywgXCJTb25hcnF1YmVTZWNyZXRBcm5cIiwge1xuICAgICAgdmFsdWU6IHNvbmFyUXViZVRva2VuLnNlY3JldEFybixcbiAgICB9KTtcblxuICAgIFtcbiAgICAgIFwiQXdzU29sdXRpb25zLVNNRzRcIixcbiAgICAgIFwiQXdzUHJvdG90eXBpbmctU2VjcmV0c01hbmFnZXJSb3RhdGlvbkVuYWJsZWRcIixcbiAgICBdLmZvckVhY2goKFJ1bGVJZCkgPT4ge1xuICAgICAgTmFnU3VwcHJlc3Npb25zLmFkZFJlc291cmNlU3VwcHJlc3Npb25zKHNvbmFyUXViZVRva2VuLCBbXG4gICAgICAgIHtcbiAgICAgICAgICBpZDogUnVsZUlkLFxuICAgICAgICAgIHJlYXNvbjpcbiAgICAgICAgICAgIFwiS2V5IHJvdGF0aW9uIGlzIG5vdCBwb3NzaWJsZSBhcyBhIHVzZXIgdG9rZW4gbmVlZHMgdG8gYmUgZ2VuZXJhdGVkIGZyb20gU29uYXJxdWJlXCIsXG4gICAgICAgIH0sXG4gICAgICBdKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHN0YWNrID0gU3RhY2sub2YodGhpcyk7XG5cbiAgICBbXCJBd3NTb2x1dGlvbnMtSUFNNVwiLCBcIkF3c1Byb3RvdHlwaW5nLUlBTU5vV2lsZGNhcmRQZXJtaXNzaW9uc1wiXS5mb3JFYWNoKFxuICAgICAgKFJ1bGVJZCkgPT4ge1xuICAgICAgICBOYWdTdXBwcmVzc2lvbnMuYWRkUmVzb3VyY2VTdXBwcmVzc2lvbnMoXG4gICAgICAgICAgdmFsaWRhdGlvblByb2plY3Qucm9sZSEsXG4gICAgICAgICAgW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogUnVsZUlkLFxuICAgICAgICAgICAgICByZWFzb246XG4gICAgICAgICAgICAgICAgXCJWYWxpZGF0aW9uIENvZGVCdWlsZCBwcm9qZWN0IHJlcXVpcmVzIGFjY2VzcyB0byB0aGUgQXJ0aWZhY3RzQnVja2V0IGFuZCBhYmlsaXR5IHRvIGNyZWF0ZSBsb2dzLlwiLFxuICAgICAgICAgICAgICBhcHBsaWVzVG86IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICByZWdleDogYC9eUmVzb3VyY2U6OmFybjoke1BES05hZy5nZXRTdGFja1BhcnRpdGlvblJlZ2V4KFxuICAgICAgICAgICAgICAgICAgICBzdGFja1xuICAgICAgICAgICAgICAgICAgKX06bG9nczoke1BES05hZy5nZXRTdGFja1JlZ2lvblJlZ2V4KFxuICAgICAgICAgICAgICAgICAgICBzdGFja1xuICAgICAgICAgICAgICAgICAgKX06JHtQREtOYWcuZ2V0U3RhY2tBY2NvdW50UmVnZXgoXG4gICAgICAgICAgICAgICAgICAgIHN0YWNrXG4gICAgICAgICAgICAgICAgICApfTpsb2ctZ3JvdXA6L2F3cy9jb2RlYnVpbGQvPC4qU29uYXJDb2RlU2Nhbm5lclZhbGlkYXRpb25Qcm9qZWN0Lio+OlxcXFwqJC9nYCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIHJlZ2V4OiBgL15SZXNvdXJjZTo6YXJuOiR7UERLTmFnLmdldFN0YWNrUGFydGl0aW9uUmVnZXgoXG4gICAgICAgICAgICAgICAgICAgIHN0YWNrXG4gICAgICAgICAgICAgICAgICApfTpjb2RlYnVpbGQ6JHtQREtOYWcuZ2V0U3RhY2tSZWdpb25SZWdleChcbiAgICAgICAgICAgICAgICAgICAgc3RhY2tcbiAgICAgICAgICAgICAgICAgICl9OiR7UERLTmFnLmdldFN0YWNrQWNjb3VudFJlZ2V4KFxuICAgICAgICAgICAgICAgICAgICBzdGFja1xuICAgICAgICAgICAgICAgICAgKX06cmVwb3J0LWdyb3VwLzwuKlNvbmFyQ29kZVNjYW5uZXJWYWxpZGF0aW9uUHJvamVjdC4qPi1cXFxcKiQvZ2AsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICByZWdleDogYC9eQWN0aW9uOjpzMzpHZXRPYmplY3RcXFxcKiQvZ2AsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICByZWdleDogXCIvXlJlc291cmNlOjo8QXJ0aWZhY3RzQnVja2V0LiouQXJuPi9cXFxcKlxcXFwqJC9nXCIsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICB0cnVlXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxufVxuIl19