UNPKG

@moonset/util

Version:
177 lines 20.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CDKResourceReader = void 0; const constants_1 = require("./constants"); /** * Moonset uses CDK to setup minimum required resources like VPC, role, s3 log * bucket etc, and then uses SDK to invoke the EMR. This helper class retrieve * the CDK generated resources for SDK's consumption. * */ class CDKResourceReader { /** * Constructor. * * Arguments: * session: To distinguish different moonset instances in the same * account. Usally different sessions are created by different users. * * sdk: The interface that represent AWS SDK. We need different sdk * instances for different accounts such as the working account and * reference accounts. * */ constructor(session, sdk) { this.session = session; this.sdk = sdk; } async findSecurityGroup(tag) { const ec2 = this.sdk.ec2(); const params = { Filters: [ { Name: `tag:${constants_1.CommonConstants.MOONSET_SESSION}`, Values: [this.session], }, { Name: `tag:${constants_1.CommonConstants.TAG_MOONSET_TYPE}`, Values: [tag], }, ], }; const data = await ec2.describeSecurityGroups(params).promise(); if (!data.SecurityGroups || data.SecurityGroups.length == 0) { throw new Error(`No Security Group found for tag: ${tag}.`); } if (data.SecurityGroups.length > 1) { throw new Error(`Multiple Security Group ${data.SecurityGroups} ` + `found for tag: ${tag}.`); } return data.SecurityGroups[0]; } async findVpc(tag) { const ec2 = this.sdk.ec2(); const params = { Filters: [ { Name: `tag:${constants_1.CommonConstants.MOONSET_SESSION}`, Values: [this.session], }, { Name: `tag:${constants_1.CommonConstants.TAG_MOONSET_TYPE}`, Values: [tag], }, ], }; const data = await ec2.describeVpcs(params).promise(); if (!data.Vpcs || data.Vpcs.length == 0) { throw new Error(`No Vpc found for tag: ${tag}.`); } if (data.Vpcs.length > 1) { throw new Error(`Multiple Vpcs ${data.Vpcs} ` + `found for tag: ${tag}.`); } return data.Vpcs[0]; } async findSubnets(tag) { const ec2 = this.sdk.ec2(); const params = { Filters: [ { Name: 'vpc-id', Values: [ (await this.findVpc(tag)).VpcId, ], }, ], }; const data = await ec2.describeSubnets(params).promise(); if (!data.Subnets) { throw new Error(`No Subnets found for tag: ${tag}.`); } return data.Subnets; } async findPrivateSubnet(tag) { const subnets = await this.findSubnets(tag); return subnets.filter((s) => !s.MapPublicIpOnLaunch)[0]; } /** * IAM Role API doesn't work well with Tag. * Check https://github.com/boto/boto3/issues/1855 * * ResourceGroupsTaggingAPI also doesn't work well with IAM Role Tag. Check * the support list: * https://docs.aws.amazon.com/resourcegroupstagging/latest/APIReference/Welcome.html * * So we go through all roles and check the tag for each role. */ async findRole(tag) { const iam = this.sdk.iam(); const roles = []; let data = await iam.listRoles({}).promise(); while (data.IsTruncated) { roles.push(...data.Roles); data = await iam.listRoles({ Marker: data.Marker, }).promise(); } roles.push(...data.Roles); const matchedRoles = []; for (const r of roles) { const tags = []; let data = await iam.listRoleTags({ RoleName: r.RoleName }).promise(); while (data.IsTruncated) { tags.push(...data.Tags); data = await iam.listRoleTags({ RoleName: r.RoleName, Marker: data.Marker, }).promise(); } tags.push(...data.Tags); if (tags.filter((t) => t.Key === constants_1.CommonConstants.MOONSET_SESSION && t.Value === this.session).length > 0 && tags.filter((t) => t.Key === constants_1.CommonConstants.TAG_MOONSET_TYPE && t.Value === tag).length > 0) { matchedRoles.push(r); } } if (!matchedRoles || matchedRoles.length == 0) { throw new Error(`No matchedRoles found for: ${tag}.`); } if (matchedRoles.length > 1) { throw new Error(`Multiple Roles ${matchedRoles} ` + `found for: ${tag}.`); } return matchedRoles[0]; } async findS3Bucket(tag) { const bucket = (await this.findResourceArn(tag)) .replace('arn:aws:s3:::', ''); return bucket; } async findResourceArn(tag) { const tagApi = this.sdk.tagApi(); const resources = await tagApi.getResources({ TagFilters: [ { Key: constants_1.CommonConstants.MOONSET_SESSION, Values: [this.session], }, { Key: constants_1.CommonConstants.TAG_MOONSET_TYPE, Values: [tag], }, ], }).promise(); if (!resources || !resources.ResourceTagMappingList || resources.ResourceTagMappingList.length != 1 || !resources.ResourceTagMappingList[0].ResourceARN) { throw new Error(`The resource should be uniquely identified.` + `However we found ${JSON.stringify(resources)}.`); } return resources.ResourceTagMappingList[0].ResourceARN; } } exports.CDKResourceReader = CDKResourceReader; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2RrLXJlc291cmNlLXJlYWRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImNkay1yZXNvdXJjZS1yZWFkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EsMkNBQWtEO0FBTWxEOzs7OztHQUtHO0FBQ0gsTUFBYSxpQkFBaUI7SUFDNUI7Ozs7Ozs7Ozs7O1NBV0s7SUFDTCxZQUE2QixPQUFlLEVBQVUsR0FBUztRQUFsQyxZQUFPLEdBQVAsT0FBTyxDQUFRO1FBQVUsUUFBRyxHQUFILEdBQUcsQ0FBTTtJQUUvRCxDQUFDO0lBRUQsS0FBSyxDQUFDLGlCQUFpQixDQUFDLEdBQVc7UUFDakMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUMzQixNQUFNLE1BQU0sR0FBRztZQUNiLE9BQU8sRUFBRTtnQkFDUDtvQkFDRSxJQUFJLEVBQUUsT0FBTywyQkFBRSxDQUFDLGVBQWUsRUFBRTtvQkFDakMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztpQkFDdkI7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLE9BQU8sMkJBQUUsQ0FBQyxnQkFBZ0IsRUFBRTtvQkFDbEMsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDO2lCQUNkO2FBQ0Y7U0FDRixDQUFDO1FBQ0YsTUFBTSxJQUFJLEdBQUcsTUFBTSxHQUFHLENBQUMsc0JBQXNCLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDaEUsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLElBQUksSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLElBQUksQ0FBQyxFQUFFO1lBQzNELE1BQU0sSUFBSSxLQUFLLENBQUMsb0NBQW9DLEdBQUcsR0FBRyxDQUFDLENBQUM7U0FDN0Q7UUFDRCxJQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtZQUNsQyxNQUFNLElBQUksS0FBSyxDQUFDLDJCQUEyQixJQUFJ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O1NBQ0YsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2IsSUFBSyxDQUFDLFNBQVM7WUFDUCxDQUFDLFNBQVMsQ0FBQyxzQkFBc0I7WUFDakMsU0FBUyxDQUFDLHNCQUFzQixDQUFDLE1BQU0sSUFBSSxDQUFDO1lBQzVDLENBQUMsU0FBUyxDQUFDLHNCQUFzQixDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFDdEQ7WUFDQSxNQUFNLElBQUksS0FBSyxDQUFDLDZDQUE2QztnQkFDekQsb0JBQW9CLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1NBQ3ZEO1FBQ0QsT0FBTyxTQUFTLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDO0lBQ3pELENBQUM7Q0FDRjtBQTlLRCw4Q0E4S0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0lTREt9IGZyb20gJy4vc2RrLXV0aWxzJztcbmltcG9ydCB7Q29tbW9uQ29uc3RhbnRzIGFzIENDfSBmcm9tICcuL2NvbnN0YW50cyc7XG5pbXBvcnQgKiBhcyBFQzIgZnJvbSAnYXdzLXNkay9jbGllbnRzL2VjMic7XG5pbXBvcnQgKiBhcyBJQU0gZnJvbSAnYXdzLXNkay9jbGllbnRzL2lhbSc7XG5pbXBvcnQgKiBhcyBDRk4gZnJvbSAnYXdzLXNkay9jbGllbnRzL2Nsb3VkZm9ybWF0aW9uJztcblxuXG4vKipcbiAqIE1vb25zZXQgdXNlcyBDREsgdG8gc2V0dXAgbWluaW11bSByZXF1aXJlZCByZXNvdXJjZXMgbGlrZSBWUEMsIHJvbGUsIHMzIGxvZ1xuICogYnVja2V0IGV0YywgYW5kIHRoZW4gdXNlcyBTREsgdG8gaW52b2tlIHRoZSBFTVIuIFRoaXMgaGVscGVyIGNsYXNzIHJldHJpZXZlXG4gKiB0aGUgQ0RLIGdlbmVyYXRlZCByZXNvdXJjZXMgZm9yIFNESydzIGNvbnN1bXB0aW9uLlxuICpcbiAqL1xuZXhwb3J0IGNsYXNzIENES1Jlc291cmNlUmVhZGVyIHtcbiAgLyoqXG4gICAgICogQ29uc3RydWN0b3IuXG4gICAgICpcbiAgICAgKiBBcmd1bWVudHM6XG4gICAgICogICAgc2Vzc2lvbjogVG8gZGlzdGluZ3Vpc2ggZGlmZmVyZW50IG1vb25zZXQgaW5zdGFuY2VzIGluIHRoZSBzYW1lXG4gICAgICogICAgYWNjb3VudC4gVXNhbGx5IGRpZmZlcmVudCBzZXNzaW9ucyBhcmUgY3JlYXRlZCBieSBkaWZmZXJlbnQgdXNlcnMuXG4gICAgICpcbiAgICAgKiAgICBzZGs6IFRoZSBpbnRlcmZhY2UgdGhhdCByZXByZXNlbnQgQVdTIFNESy4gV2UgbmVlZCBkaWZmZXJlbnQgc2RrXG4gICAgICogICAgaW5zdGFuY2VzIGZvciBkaWZmZXJlbnQgYWNjb3VudHMgc3VjaCBhcyB0aGUgd29ya2luZyBhY2NvdW50IGFuZFxuICAgICAqICAgIHJlZmVyZW5jZSBhY2NvdW50cy5cbiAgICAgKlxuICAgICAqL1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IHNlc3Npb246IHN0cmluZywgcHJpdmF0ZSBzZGs6IElTREspIHtcblxuICB9XG5cbiAgYXN5bmMgZmluZFNlY3VyaXR5R3JvdXAodGFnOiBzdHJpbmcpOiBQcm9taXNlPEVDMi5UeXBlcy5TZWN1cml0eUdyb3VwPiB7XG4gICAgY29uc3QgZWMyID0gdGhpcy5zZGsuZWMyKCk7XG4gICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgRmlsdGVyczogW1xuICAgICAgICB7XG4gICAgICAgICAgTmFtZTogYHRhZzoke0NDLk1PT05TRVRfU0VTU0lPTn1gLFxuICAgICAgICAgIFZhbHVlczogW3RoaXMuc2Vzc2lvbl0sXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBOYW1lOiBgdGFnOiR7Q0MuVEFHX01PT05TRVRfVFlQRX1gLFxuICAgICAgICAgIFZhbHVlczogW3RhZ10sXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH07XG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IGVjMi5kZXNjcmliZVNlY3VyaXR5R3JvdXBzKHBhcmFtcykucHJvbWlzZSgpO1xuICAgIGlmICghZGF0YS5TZWN1cml0eUdyb3VwcyB8fCBkYXRhLlNlY3VyaXR5R3JvdXBzLmxlbmd0aCA9PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIFNlY3VyaXR5IEdyb3VwIGZvdW5kIGZvciB0YWc6ICR7dGFnfS5gKTtcbiAgICB9XG4gICAgaWYgKGRhdGEuU2VjdXJpdHlHcm91cHMubGVuZ3RoID4gMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBNdWx0aXBsZSBTZWN1cml0eSBHcm91cCAke2RhdGEuU2VjdXJpdHlHcm91cHN9IGArXG4gICAgICAgICAgYGZvdW5kIGZvciB0YWc6ICR7dGFnfS5gKTtcbiAgICB9XG4gICAgcmV0dXJuIGRhdGEuU2VjdXJpdHlHcm91cHNbMF07XG4gIH1cblxuICBhc3luYyBmaW5kVnBjKHRhZzogc3RyaW5nKTogUHJvbWlzZTxFQzIuVHlwZXMuVnBjPiB7XG4gICAgY29uc3QgZWMyID0gdGhpcy5zZGsuZWMyKCk7XG4gICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgRmlsdGVyczogW1xuICAgICAgICB7XG4gICAgICAgICAgTmFtZTogYHRhZzoke0NDLk1PT05TRVRfU0VTU0lPTn1gLFxuICAgICAgICAgIFZhbHVlczogW3RoaXMuc2Vzc2lvbl0sXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBOYW1lOiBgdGFnOiR7Q0MuVEFHX01PT05TRVRfVFlQRX1gLFxuICAgICAgICAgIFZhbHVlczogW3RhZ10sXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH07XG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IGVjMi5kZXNjcmliZVZwY3MocGFyYW1zKS5wcm9taXNlKCk7XG4gICAgaWYgKCFkYXRhLlZwY3MgfHwgZGF0YS5WcGNzLmxlbmd0aCA9PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIFZwYyBmb3VuZCBmb3IgdGFnOiAke3RhZ30uYCk7XG4gICAgfVxuICAgIGlmIChkYXRhLlZwY3MubGVuZ3RoID4gMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBNdWx0aXBsZSBWcGNzICR7ZGF0YS5WcGNzfSBgK1xuICAgICAgICAgIGBmb3VuZCBmb3IgdGFnOiAke3RhZ30uYCk7XG4gICAgfVxuICAgIHJldHVybiBkYXRhLlZwY3NbMF07XG4gIH1cblxuICBhc3luYyBmaW5kU3VibmV0cyh0YWc6IHN0cmluZyk6IFByb21pc2U8RUMyLlR5cGVzLlN1Ym5ldExpc3Q+IHtcbiAgICBjb25zdCBlYzIgPSB0aGlzLnNkay5lYzIoKTtcbiAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICBGaWx0ZXJzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBOYW1lOiAndnBjLWlkJyxcbiAgICAgICAgICBWYWx1ZXM6IFtcbiAgICAgICAgICAgICAgICAgICAgICAoYXdhaXQgdGhpcy5maW5kVnBjKHRhZykpLlZwY0lkISxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9O1xuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBlYzIuZGVzY3JpYmVTdWJuZXRzKHBhcmFtcykucHJvbWlzZSgpO1xuICAgIGlmICghZGF0YS5TdWJuZXRzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIFN1Ym5ldHMgZm91bmQgZm9yIHRhZzogJHt0YWd9LmApO1xuICAgIH1cbiAgICByZXR1cm4gZGF0YS5TdWJuZXRzO1xuICB9XG5cbiAgYXN5bmMgZmluZFByaXZhdGVTdWJuZXQodGFnOiBzdHJpbmcpOiBQcm9taXNlPEVDMi5UeXBlcy5TdWJuZXQ+IHtcbiAgICBjb25zdCBzdWJuZXRzID0gYXdhaXQgdGhpcy5maW5kU3VibmV0cyh0YWcpO1xuICAgIHJldHVybiBzdWJuZXRzLmZpbHRlcigocykgPT4gIXMuTWFwUHVibGljSXBPbkxhdW5jaClbMF07XG4gIH1cblxuICAvKipcbiAgICogSUFNIFJvbGUgQVBJIGRvZXNuJ3Qgd29yayB3ZWxsIHdpdGggVGFnLlxuICAgKiBDaGVjayBodHRwczovL2dpdGh1Yi5jb20vYm90by9ib3RvMy9pc3N1ZXMvMTg1NVxuICAgKlxuICAgKiBSZXNvdXJjZUdyb3Vwc1RhZ2dpbmdBUEkgYWxzbyBkb2Vzbid0IHdvcmsgd2VsbCB3aXRoIElBTSBSb2xlIFRhZy4gQ2hlY2tcbiAgICogdGhlIHN1cHBvcnQgbGlzdDpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3Jlc291cmNlZ3JvdXBzdGFnZ2luZy9sYXRlc3QvQVBJUmVmZXJlbmNlL1dlbGNvbWUuaHRtbFxuICAgKlxuICAgKiBTbyB3ZSBnbyB0aHJvdWdoIGFsbCByb2xlcyBhbmQgY2hlY2sgdGhlIHRhZyBmb3IgZWFjaCByb2xlLlxuICAgKi9cbiAgYXN5bmMgZmluZFJvbGUodGFnOiBzdHJpbmcpOiBQcm9taXNlPElBTS5UeXBlcy5Sb2xlPiB7XG4gICAgY29uc3QgaWFtID0gdGhpcy5zZGsuaWFtKCk7XG4gICAgY29uc3Qgcm9sZXMgPSBbXTtcbiAgICBsZXQgZGF0YSA9IGF3YWl0IGlhbS5saXN0Um9sZXMoe30pLnByb21pc2UoKTtcbiAgICB3aGlsZSAoZGF0YS5Jc1RydW5jYXRlZCkge1xuICAgICAgcm9sZXMucHVzaCguLi5kYXRhLlJvbGVzKTtcbiAgICAgIGRhdGEgPSBhd2FpdCBpYW0ubGlzdFJvbGVzKHtcbiAgICAgICAgTWFya2VyOiBkYXRhLk1hcmtlcixcbiAgICAgIH0pLnByb21pc2UoKTtcbiAgICB9XG4gICAgcm9sZXMucHVzaCguLi5kYXRhLlJvbGVzKTtcblxuICAgIGNvbnN0IG1hdGNoZWRSb2xlcyA9IFtdO1xuICAgIGZvciAoY29uc3QgciBvZiByb2xlcykge1xuICAgICAgY29uc3QgdGFncyA9IFtdO1xuICAgICAgbGV0IGRhdGEgPSBhd2FpdCBpYW0ubGlzdFJvbGVUYWdzKHtSb2xlTmFtZTogci5Sb2xlTmFtZX0pLnByb21pc2UoKTtcbiAgICAgIHdoaWxlIChkYXRhLklzVHJ1bmNhdGVkKSB7XG4gICAgICAgIHRhZ3MucHVzaCguLi5kYXRhLlRhZ3MpO1xuICAgICAgICBkYXRhID0gYXdhaXQgaWFtLmxpc3RSb2xlVGFncyh7XG4gICAgICAgICAgUm9sZU5hbWU6IHIuUm9sZU5hbWUsXG4gICAgICAgICAgTWFya2VyOiBkYXRhLk1hcmtlcixcbiAgICAgICAgfSkucHJvbWlzZSgpO1xuICAgICAgfVxuICAgICAgdGFncy5wdXNoKC4uLmRhdGEuVGFncyk7XG4gICAgICBpZiAoIHRhZ3MuZmlsdGVyKCh0KSA9PlxuICAgICAgICB0LktleSA9PT0gQ0MuTU9PTlNFVF9TRVNTSU9OICYmXG4gICAgICAgIHQuVmFsdWUgPT09IHRoaXMuc2Vzc2lvbikubGVuZ3RoID4gMCAmJlxuICAgICAgICB0YWdzLmZpbHRlcigodCkgPT5cbiAgICAgICAgICB0LktleSA9PT0gQ0MuVEFHX01PT05TRVRfVFlQRSAmJlxuICAgICAgICB0LlZhbHVlID09PSB0YWcpLmxlbmd0aCA+IDAgKSB7XG4gICAgICAgIG1hdGNoZWRSb2xlcy5wdXNoKHIpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIW1hdGNoZWRSb2xlcyB8fCBtYXRjaGVkUm9sZXMubGVuZ3RoID09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gbWF0Y2hlZFJvbGVzIGZvdW5kIGZvcjogJHt0YWd9LmApO1xuICAgIH1cbiAgICBpZiAobWF0Y2hlZFJvbGVzLmxlbmd0aCA+IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTXVsdGlwbGUgUm9sZXMgJHttYXRjaGVkUm9sZXN9IGArXG4gICAgICAgICAgYGZvdW5kIGZvcjogJHt0YWd9LmApO1xuICAgIH1cbiAgICByZXR1cm4gbWF0Y2hlZFJvbGVzWzBdO1xuICB9XG5cbiAgYXN5bmMgZmluZFMzQnVja2V0KHRhZzogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBjb25zdCBidWNrZXQgPSAoYXdhaXQgdGhpcy5maW5kUmVzb3VyY2VBcm4odGFnKSlcbiAgICAgICAgLnJlcGxhY2UoJ2Fybjphd3M6czM6OjonLCAnJyk7XG4gICAgcmV0dXJuIGJ1Y2tldDtcbiAgfVxuXG4gIGFzeW5jIGZpbmRSZXNvdXJjZUFybih0YWc6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3QgdGFnQXBpID0gdGhpcy5zZGsudGFnQXBpKCk7XG4gICAgY29uc3QgcmVzb3VyY2VzID0gYXdhaXQgdGFnQXBpLmdldFJlc291cmNlcyh7XG4gICAgICBUYWdGaWx0ZXJzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBLZXk6IENDLk1PT05TRVRfU0VTU0lPTixcbiAgICAgICAgICBWYWx1ZXM6IFt0aGlzLnNlc3Npb25dLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgS2V5OiBDQy5UQUdfTU9PTlNFVF9UWVBFLFxuICAgICAgICAgIFZhbHVlczogW3RhZ10sXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0pLnByb21pc2UoKTtcbiAgICBpZiAoICFyZXNvdXJjZXMgfHxcbiAgICAgICAgICAgICFyZXNvdXJjZXMuUmVzb3VyY2VUYWdNYXBwaW5nTGlzdCB8fFxuICAgICAgICAgICAgcmVzb3VyY2VzLlJlc291cmNlVGFnTWFwcGluZ0xpc3QubGVuZ3RoICE9IDEgfHxcbiAgICAgICAgICAgICFyZXNvdXJjZXMuUmVzb3VyY2VUYWdNYXBwaW5nTGlzdFswXS5SZXNvdXJjZUFSTlxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgcmVzb3VyY2Ugc2hvdWxkIGJlIHVuaXF1ZWx5IGlkZW50aWZpZWQuYCArXG4gICAgICAgICAgYEhvd2V2ZXIgd2UgZm91bmQgJHtKU09OLnN0cmluZ2lmeShyZXNvdXJjZXMpfS5gKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc291cmNlcy5SZXNvdXJjZVRhZ01hcHBpbmdMaXN0WzBdLlJlc291cmNlQVJOO1xuICB9XG59XG4iXX0=