aws-cdk
Version:
CDK Toolkit, the command line tool for CDK apps
156 lines • 26.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.LoadBalancerListenerContextProviderPlugin = exports.LoadBalancerContextProviderPlugin = void 0;
const cx_api_1 = require("@aws-cdk/cx-api");
const sdk_provider_1 = require("../api/aws-auth/sdk-provider");
const error_1 = require("../toolkit/error");
/**
* Provides load balancer context information.
*/
class LoadBalancerContextProviderPlugin {
constructor(aws) {
this.aws = aws;
}
async getValue(query) {
if (!query.loadBalancerArn && !query.loadBalancerTags) {
throw new error_1.ContextProviderError('The load balancer lookup query must specify either `loadBalancerArn` or `loadBalancerTags`');
}
const loadBalancer = await (await LoadBalancerProvider.getClient(this.aws, query)).getLoadBalancer();
const ipAddressType = loadBalancer.IpAddressType === 'ipv4' ? cx_api_1.LoadBalancerIpAddressType.IPV4 : cx_api_1.LoadBalancerIpAddressType.DUAL_STACK;
return {
loadBalancerArn: loadBalancer.LoadBalancerArn,
loadBalancerCanonicalHostedZoneId: loadBalancer.CanonicalHostedZoneId,
loadBalancerDnsName: loadBalancer.DNSName,
vpcId: loadBalancer.VpcId,
securityGroupIds: loadBalancer.SecurityGroups ?? [],
ipAddressType: ipAddressType,
};
}
}
exports.LoadBalancerContextProviderPlugin = LoadBalancerContextProviderPlugin;
/**
* Provides load balancer listener context information
*/
class LoadBalancerListenerContextProviderPlugin {
constructor(aws) {
this.aws = aws;
}
async getValue(query) {
if (!query.listenerArn && !query.loadBalancerArn && !query.loadBalancerTags) {
throw new error_1.ContextProviderError('The load balancer listener query must specify at least one of: `listenerArn`, `loadBalancerArn` or `loadBalancerTags`');
}
return (await LoadBalancerProvider.getClient(this.aws, query)).getListener();
}
}
exports.LoadBalancerListenerContextProviderPlugin = LoadBalancerListenerContextProviderPlugin;
class LoadBalancerProvider {
static async getClient(aws, query) {
const client = (await (0, sdk_provider_1.initContextProviderSdk)(aws, query)).elbv2();
try {
const listener = query.listenerArn
? // Assert we're sure there's at least one so it throws if not
(await client.describeListeners({ ListenerArns: [query.listenerArn] })).Listeners[0]
: undefined;
return new LoadBalancerProvider(client, { ...query, loadBalancerArn: listener?.LoadBalancerArn || query.loadBalancerArn }, listener);
}
catch (err) {
throw new error_1.ContextProviderError(`No load balancer listeners found matching arn ${query.listenerArn}`);
}
}
constructor(client, filter, listener) {
this.client = client;
this.filter = filter;
this.listener = listener;
}
async getLoadBalancer() {
const loadBalancers = await this.getLoadBalancers();
if (loadBalancers.length === 0) {
throw new error_1.ContextProviderError(`No load balancers found matching ${JSON.stringify(this.filter)}`);
}
if (loadBalancers.length > 1) {
throw new error_1.ContextProviderError(`Multiple load balancers found matching ${JSON.stringify(this.filter)} - please provide more specific criteria`);
}
return loadBalancers[0];
}
async getListener() {
if (this.listener) {
try {
const loadBalancer = await this.getLoadBalancer();
return {
listenerArn: this.listener.ListenerArn,
listenerPort: this.listener.Port,
securityGroupIds: loadBalancer.SecurityGroups || [],
};
}
catch (err) {
throw new error_1.ContextProviderError(`No associated load balancer found for listener arn ${this.filter.listenerArn}`);
}
}
const loadBalancers = await this.getLoadBalancers();
if (loadBalancers.length === 0) {
throw new error_1.ContextProviderError(`No associated load balancers found for load balancer listener query ${JSON.stringify(this.filter)}`);
}
const listeners = (await this.getListenersForLoadBalancers(loadBalancers)).filter((listener) => {
return ((!this.filter.listenerPort || listener.Port === this.filter.listenerPort) &&
(!this.filter.listenerProtocol || listener.Protocol === this.filter.listenerProtocol));
});
if (listeners.length === 0) {
throw new error_1.ContextProviderError(`No load balancer listeners found matching ${JSON.stringify(this.filter)}`);
}
if (listeners.length > 1) {
throw new error_1.ContextProviderError(`Multiple load balancer listeners found matching ${JSON.stringify(this.filter)} - please provide more specific criteria`);
}
return {
listenerArn: listeners[0].ListenerArn,
listenerPort: listeners[0].Port,
securityGroupIds: loadBalancers.find((lb) => listeners[0].LoadBalancerArn === lb.LoadBalancerArn)?.SecurityGroups || [],
};
}
async getLoadBalancers() {
const loadBalancerArns = this.filter.loadBalancerArn ? [this.filter.loadBalancerArn] : undefined;
const loadBalancers = (await this.client.paginateDescribeLoadBalancers({
LoadBalancerArns: loadBalancerArns,
})).filter((lb) => lb.Type === this.filter.loadBalancerType);
return this.filterByTags(loadBalancers);
}
async filterByTags(loadBalancers) {
if (!this.filter.loadBalancerTags) {
return loadBalancers;
}
return (await this.describeTags(loadBalancers.map((lb) => lb.LoadBalancerArn)))
.filter((tagDescription) => {
// For every tag in the filter, there is some tag in the LB that matches it.
// In other words, the set of tags in the filter is a subset of the set of tags in the LB.
return this.filter.loadBalancerTags.every((filter) => {
return tagDescription.Tags?.some((tag) => filter.key === tag.Key && filter.value === tag.Value);
});
})
.flatMap((tag) => loadBalancers.filter((loadBalancer) => tag.ResourceArn === loadBalancer.LoadBalancerArn));
}
/**
* Returns tag descriptions associated with the resources. The API doesn't support
* pagination, so this function breaks the resource list into chunks and issues
* the appropriate requests.
*/
async describeTags(resourceArns) {
// Max of 20 resource arns per request.
const chunkSize = 20;
const tags = Array();
for (let i = 0; i < resourceArns.length; i += chunkSize) {
const chunk = resourceArns.slice(i, Math.min(i + chunkSize, resourceArns.length));
const chunkTags = await this.client.describeTags({
ResourceArns: chunk,
});
tags.push(...(chunkTags.TagDescriptions || []));
}
return tags;
}
async getListenersForLoadBalancers(loadBalancers) {
const listeners = [];
for (const loadBalancer of loadBalancers.map((lb) => lb.LoadBalancerArn)) {
listeners.push(...(await this.client.paginateDescribeListeners({ LoadBalancerArn: loadBalancer })));
}
return listeners;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9hZC1iYWxhbmNlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJsb2FkLWJhbGFuY2Vycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSw0Q0FJeUI7QUFHekIsK0RBQXdGO0FBRXhGLDRDQUF3RDtBQUV4RDs7R0FFRztBQUNILE1BQWEsaUNBQWlDO0lBQzVDLFlBQTZCLEdBQWdCO1FBQWhCLFFBQUcsR0FBSCxHQUFHLENBQWE7SUFBRyxDQUFDO0lBRWpELEtBQUssQ0FBQyxRQUFRLENBQUMsS0FBK0I7UUFDNUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUN0RCxNQUFNLElBQUksNEJBQW9CLENBQUMsNEZBQTRGLENBQUMsQ0FBQztRQUMvSCxDQUFDO1FBRUQsTUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFDLE1BQU0sb0JBQW9CLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUVyRyxNQUFNLGFBQWEsR0FDakIsWUFBWSxDQUFDLGFBQWEsS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDLGtDQUF5QixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsa0NBQXlCLENBQUMsVUFBVSxDQUFDO1FBRWhILE9BQU87WUFDTCxlQUFlLEVBQUUsWUFBWSxDQUFDLGVBQWdCO1lBQzlDLGlDQUFpQyxFQUFFLFlBQVksQ0FBQyxxQkFBc0I7WUFDdEUsbUJBQW1CLEVBQUUsWUFBWSxDQUFDLE9BQVE7WUFDMUMsS0FBSyxFQUFFLFlBQVksQ0FBQyxLQUFNO1lBQzFCLGdCQUFnQixFQUFFLFlBQVksQ0FBQyxjQUFjLElBQUksRUFBRTtZQUNuRCxhQUFhLEVBQUUsYUFBYTtTQUM3QixDQUFDO0lBQ0osQ0FBQztDQUNGO0FBdEJELDhFQXNCQztBQUVEOztHQUVHO0FBQ0gsTUFBYSx5Q0FBeUM7SUFDcEQsWUFB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TSxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQztnQkFDL0MsWUFBWSxFQUFFLEtBQUs7YUFDcEIsQ0FBQyxDQUFDO1lBRUgsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLGVBQWUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2xELENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFTyxLQUFLLENBQUMsNEJBQTRCLENBQUMsYUFBNkI7UUFDdEUsTUFBTSxTQUFTLEdBQWUsRUFBRSxDQUFDO1FBQ2pDLEtBQUssTUFBTSxZQUFZLElBQUksYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUM7WUFDekUsU0FBUyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLHlCQUF5QixDQUFDLEVBQUUsZUFBZSxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RHLENBQUM7UUFDRCxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBMb2FkQmFsYW5jZXJDb250ZXh0UXVlcnksIExvYWRCYWxhbmNlckxpc3RlbmVyQ29udGV4dFF1ZXJ5IH0gZnJvbSAnQGF3cy1jZGsvY2xvdWQtYXNzZW1ibHktc2NoZW1hJztcbmltcG9ydCB7XG4gIExvYWRCYWxhbmNlckNvbnRleHRSZXNwb25zZSxcbiAgTG9hZEJhbGFuY2VySXBBZGRyZXNzVHlwZSxcbiAgTG9hZEJhbGFuY2VyTGlzdGVuZXJDb250ZXh0UmVzcG9uc2UsXG59IGZyb20gJ0Bhd3MtY2RrL2N4LWFwaSc7XG5pbXBvcnQgeyB0eXBlIExpc3RlbmVyLCBMb2FkQmFsYW5jZXIsIHR5cGUgVGFnRGVzY3JpcHRpb24gfSBmcm9tICdAYXdzLXNkay9jbGllbnQtZWxhc3RpYy1sb2FkLWJhbGFuY2luZy12Mic7XG5pbXBvcnQgdHlwZSB7IElFbGFzdGljTG9hZEJhbGFuY2luZ1YyQ2xpZW50IH0gZnJvbSAnLi4vYXBpJztcbmltcG9ydCB7IHR5cGUgU2RrUHJvdmlkZXIsIGluaXRDb250ZXh0UHJvdmlkZXJTZGsgfSBmcm9tICcuLi9hcGkvYXdzLWF1dGgvc2RrLXByb3ZpZGVyJztcbmltcG9ydCB7IENvbnRleHRQcm92aWRlclBsdWdpbiB9IGZyb20gJy4uL2FwaS9wbHVnaW4nO1xuaW1wb3J0IHsgQ29udGV4dFByb3ZpZGVyRXJyb3IgfSBmcm9tICcuLi90b29sa2l0L2Vycm9yJztcblxuLyoqXG4gKiBQcm92aWRlcyBsb2FkIGJhbGFuY2VyIGNvbnRleHQgaW5mb3JtYXRpb24uXG4gKi9cbmV4cG9ydCBjbGFzcyBMb2FkQmFsYW5jZXJDb250ZXh0UHJvdmlkZXJQbHVnaW4gaW1wbGVtZW50cyBDb250ZXh0UHJvdmlkZXJQbHVnaW4ge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGF3czogU2RrUHJvdmlkZXIpIHt9XG5cbiAgYXN5bmMgZ2V0VmFsdWUocXVlcnk6IExvYWRCYWxhbmNlckNvbnRleHRRdWVyeSk6IFByb21pc2U8TG9hZEJhbGFuY2VyQ29udGV4dFJlc3BvbnNlPiB7XG4gICAgaWYgKCFxdWVyeS5sb2FkQmFsYW5jZXJBcm4gJiYgIXF1ZXJ5LmxvYWRCYWxhbmNlclRhZ3MpIHtcbiAgICAgIHRocm93IG5ldyBDb250ZXh0UHJvdmlkZXJFcnJvcignVGhlIGxvYWQgYmFsYW5jZXIgbG9va3VwIHF1ZXJ5IG11c3Qgc3BlY2lmeSBlaXRoZXIgYGxvYWRCYWxhbmNlckFybmAgb3IgYGxvYWRCYWxhbmNlclRhZ3NgJyk7XG4gICAgfVxuXG4gICAgY29uc3QgbG9hZEJhbGFuY2VyID0gYXdhaXQgKGF3YWl0IExvYWRCYWxhbmNlclByb3ZpZGVyLmdldENsaWVudCh0aGlzLmF3cywgcXVlcnkpKS5nZXRMb2FkQmFsYW5jZXIoKTtcblxuICAgIGNvbnN0IGlwQWRkcmVzc1R5cGUgPVxuICAgICAgbG9hZEJhbGFuY2VyLklwQWRkcmVzc1R5cGUgPT09ICdpcHY0JyA/IExvYWRCYWxhbmNlcklwQWRkcmVzc1R5cGUuSVBWNCA6IExvYWRCYWxhbmNlcklwQWRkcmVzc1R5cGUuRFVBTF9TVEFDSztcblxuICAgIHJldHVybiB7XG4gICAgICBsb2FkQmFsYW5jZXJBcm46IGxvYWRCYWxhbmNlci5Mb2FkQmFsYW5jZXJBcm4hLFxuICAgICAgbG9hZEJhbGFuY2VyQ2Fub25pY2FsSG9zdGVkWm9uZUlkOiBsb2FkQmFsYW5jZXIuQ2Fub25pY2FsSG9zdGVkWm9uZUlkISxcbiAgICAgIGxvYWRCYWxhbmNlckRuc05hbWU6IGxvYWRCYWxhbmNlci5ETlNOYW1lISxcbiAgICAgIHZwY0lkOiBsb2FkQmFsYW5jZXIuVnBjSWQhLFxuICAgICAgc2VjdXJpdHlHcm91cElkczogbG9hZEJhbGFuY2VyLlNlY3VyaXR5R3JvdXBzID8/IFtdLFxuICAgICAgaXBBZGRyZXNzVHlwZTogaXBBZGRyZXNzVHlwZSxcbiAgICB9O1xuICB9XG59XG5cbi8qKlxuICogUHJvdmlkZXMgbG9hZCBiYWxhbmNlciBsaXN0ZW5lciBjb250ZXh0IGluZm9ybWF0aW9uXG4gKi9cbmV4cG9ydCBjbGFzcyBMb2FkQmFsYW5jZXJMaXN0ZW5lckNvbnRleHRQcm92aWRlclBsdWdpbiBpbXBsZW1lbnRzIENvbnRleHRQcm92aWRlclBsdWdpbiB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgYXdzOiBTZGtQcm92aWRlcikge31cblxuICBhc3luYyBnZXRWYWx1ZShxdWVyeTogTG9hZEJhbGFuY2VyTGlzdGVuZXJDb250ZXh0UXVlcnkpOiBQcm9taXNlPExvYWRCYWxhbmNlckxpc3RlbmVyQ29udGV4dFJlc3BvbnNlPiB7XG4gICAgaWYgKCFxdWVyeS5saXN0ZW5lckFybiAmJiAhcXVlcnkubG9hZEJhbGFuY2VyQXJuICYmICFxdWVyeS5sb2FkQmFsYW5jZXJUYWdzKSB7XG4gICAgICB0aHJvdyBuZXcgQ29udGV4dFByb3ZpZGVyRXJyb3IoXG4gICAgICAgICdUaGUgbG9hZCBiYWxhbmNlciBsaXN0ZW5lciBxdWVyeSBtdXN0IHNwZWNpZnkgYXQgbGVhc3Qgb25lIG9mOiBgbGlzdGVuZXJBcm5gLCBgbG9hZEJhbGFuY2VyQXJuYCBvciBgbG9hZEJhbGFuY2VyVGFnc2AnLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gKGF3YWl0IExvYWRCYWxhbmNlclByb3ZpZGVyLmdldENsaWVudCh0aGlzLmF3cywgcXVlcnkpKS5nZXRMaXN0ZW5lcigpO1xuICB9XG59XG5cbmNsYXNzIExvYWRCYWxhbmNlclByb3ZpZGVyIHtcbiAgcHVibGljIHN0YXRpYyBhc3luYyBnZXRDbGllbnQoXG4gICAgYXdzOiBTZGtQcm92aWRlcixcbiAgICBxdWVyeTogTG9hZEJhbGFuY2VyTGlzdGVuZXJDb250ZXh0UXVlcnksXG4gICk6IFByb21pc2U8TG9hZEJhbGFuY2VyUHJvdmlkZXI+IHtcbiAgICBjb25zdCBjbGllbnQgPSAoYXdhaXQgaW5pdENvbnRleHRQcm92aWRlclNkayhhd3MsIHF1ZXJ5KSkuZWxidjIoKTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBsaXN0ZW5lciA9IHF1ZXJ5Lmxpc3RlbmVyQXJuXG4gICAgICAgID8gLy8gQXNzZXJ0IHdlJ3JlIHN1cmUgdGhlcmUncyBhdCBsZWFzdCBvbmUgc28gaXQgdGhyb3dzIGlmIG5vdFxuICAgICAgICAoYXdhaXQgY2xpZW50LmRlc2NyaWJlTGlzdGVuZXJzKHsgTGlzdGVuZXJBcm5zOiBbcXVlcnkubGlzdGVuZXJBcm5dIH0pKS5MaXN0ZW5lcnMhWzBdIVxuICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICAgIHJldHVybiBuZXcgTG9hZEJhbGFuY2VyUHJvdmlkZXIoXG4gICAgICAgIGNsaWVudCxcbiAgICAgICAgeyAuLi5xdWVyeSwgbG9hZEJhbGFuY2VyQXJuOiBsaXN0ZW5lcj8uTG9hZEJhbGFuY2VyQXJuIHx8IHF1ZXJ5LmxvYWRCYWxhbmNlckFybiB9LFxuICAgICAgICBsaXN0ZW5lcixcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aHJvdyBuZXcgQ29udGV4dFByb3ZpZGVyRXJyb3IoYE5vIGxvYWQgYmFsYW5jZXIgbGlzdGVuZXJzIGZvdW5kIG1hdGNoaW5nIGFybiAke3F1ZXJ5Lmxpc3RlbmVyQXJufWApO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY2xpZW50OiBJRWxhc3RpY0xvYWRCYWxhbmNpbmdWMkNsaWVudCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGZpbHRlcjogTG9hZEJhbGFuY2VyTGlzdGVuZXJDb250ZXh0UXVlcnksXG4gICAgcHJpdmF0ZSByZWFkb25seSBsaXN0ZW5lcj86IExpc3RlbmVyLFxuICApIHt9XG5cbiAgcHVibGljIGFzeW5jIGdldExvYWRCYWxhbmNlcigpOiBQcm9taXNlPExvYWRCYWxhbmNlcj4ge1xuICAgIGNvbnN0IGxvYWRCYWxhbmNlcnMgPSBhd2FpdCB0aGlzLmdldExvYWRCYWxhbmNlcnMoKTtcblxuICAgIGlmIChsb2FkQmFsYW5jZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IENvbnRleHRQcm92aWRlckVycm9yKGBObyBsb2FkIGJhbGFuY2VycyBmb3VuZCBtYXRjaGluZyAke0pTT04uc3RyaW5naWZ5KHRoaXMuZmlsdGVyKX1gKTtcbiAgICB9XG5cbiAgICBpZiAobG9hZEJhbGFuY2Vycy5sZW5ndGggPiAxKSB7XG4gICAgICB0aHJvdyBuZXcgQ29udGV4dFByb3ZpZGVyRXJyb3IoXG4gICAgICAgIGBNdWx0aXBsZSBsb2FkIGJhbGFuY2VycyBmb3VuZCBtYXRjaGluZyAke0pTT04uc3RyaW5naWZ5KHRoaXMuZmlsdGVyKX0gLSBwbGVhc2UgcHJvdmlkZSBtb3JlIHNwZWNpZmljIGNyaXRlcmlhYCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGxvYWRCYWxhbmNlcnNbMF07XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZ2V0TGlzdGVuZXIoKTogUHJvbWlzZTxMb2FkQmFsYW5jZXJMaXN0ZW5lckNvbnRleHRSZXNwb25zZT4ge1xuICAgIGlmICh0aGlzLmxpc3RlbmVyKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBsb2FkQmFsYW5jZXIgPSBhd2FpdCB0aGlzLmdldExvYWRCYWxhbmNlcigpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGxpc3RlbmVyQXJuOiB0aGlzLmxpc3RlbmVyLkxpc3RlbmVyQXJuISxcbiAgICAgICAgICBsaXN0ZW5lclBvcnQ6IHRoaXMubGlzdGVuZXIuUG9ydCEsXG4gICAgICAgICAgc2VjdXJpdHlHcm91cElkczogbG9hZEJhbGFuY2VyLlNlY3VyaXR5R3JvdXBzIHx8IFtdLFxuICAgICAgICB9O1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIHRocm93IG5ldyBDb250ZXh0UHJvdmlkZXJFcnJvcihgTm8gYXNzb2NpYXRlZCBsb2FkIGJhbGFuY2VyIGZvdW5kIGZvciBsaXN0ZW5lciBhcm4gJHt0aGlzLmZpbHRlci5saXN0ZW5lckFybn1gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBsb2FkQmFsYW5jZXJzID0gYXdhaXQgdGhpcy5nZXRMb2FkQmFsYW5jZXJzKCk7XG4gICAgaWYgKGxvYWRCYWxhbmNlcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgQ29udGV4dFByb3ZpZGVyRXJyb3IoXG4gICAgICAgIGBObyBhc3NvY2lhdGVkIGxvYWQgYmFsYW5jZXJzIGZvdW5kIGZvciBsb2FkIGJhbGFuY2VyIGxpc3RlbmVyIHF1ZXJ5ICR7SlNPTi5zdHJpbmdpZnkodGhpcy5maWx0ZXIpfWAsXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IGxpc3RlbmVycyA9IChhd2FpdCB0aGlzLmdldExpc3RlbmVyc0ZvckxvYWRCYWxhbmNlcnMobG9hZEJhbGFuY2VycykpLmZpbHRlcigobGlzdGVuZXIpID0+IHtcbiAgICAgIHJldHVybiAoXG4gICAgICAgICghdGhpcy5maWx0ZXIubGlzdGVuZXJQb3J0IHx8IGxpc3RlbmVyLlBvcnQgPT09IHRoaXMuZmlsdGVyLmxpc3RlbmVyUG9ydCkgJiZcbiAgICAgICAgKCF0aGlzLmZpbHRlci5saXN0ZW5lclByb3RvY29sIHx8IGxpc3RlbmVyLlByb3RvY29sID09PSB0aGlzLmZpbHRlci5saXN0ZW5lclByb3RvY29sKVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGlmIChsaXN0ZW5lcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgQ29udGV4dFByb3ZpZGVyRXJyb3IoYE5vIGxvYWQgYmFsYW5jZXIgbGlzdGVuZXJzIGZvdW5kIG1hdGNoaW5nICR7SlNPTi5zdHJpbmdpZnkodGhpcy5maWx0ZXIpfWApO1xuICAgIH1cblxuICAgIGlmIChsaXN0ZW5lcnMubGVuZ3RoID4gMSkge1xuICAgICAgdGhyb3cgbmV3IENvbnRleHRQcm92aWRlckVycm9yKFxuICAgICAgICBgTXVsdGlwbGUgbG9hZCBiYWxhbmNlciBsaXN0ZW5lcnMgZm91bmQgbWF0Y2hpbmcgJHtKU09OLnN0cmluZ2lmeSh0aGlzLmZpbHRlcil9IC0gcGxlYXNlIHByb3ZpZGUgbW9yZSBzcGVjaWZpYyBjcml0ZXJpYWAsXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBsaXN0ZW5lckFybjogbGlzdGVuZXJzWzBdLkxpc3RlbmVyQXJuISxcbiAgICAgIGxpc3RlbmVyUG9ydDogbGlzdGVuZXJzWzBdLlBvcnQhLFxuICAgICAgc2VjdXJpdHlHcm91cElkczpcbiAgICAgICAgbG9hZEJhbGFuY2Vycy5maW5kKChsYikgPT4gbGlzdGVuZXJzWzBdLkxvYWRCYWxhbmNlckFybiA9PT0gbGIuTG9hZEJhbGFuY2VyQXJuKT8uU2VjdXJpdHlHcm91cHMgfHwgW10sXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZ2V0TG9hZEJhbGFuY2VycygpIHtcbiAgICBjb25zdCBsb2FkQmFsYW5jZXJBcm5zID0gdGhpcy5maWx0ZXIubG9hZEJhbGFuY2VyQXJuID8gW3RoaXMuZmlsdGVyLmxvYWRCYWxhbmNlckFybl0gOiB1bmRlZmluZWQ7XG4gICAgY29uc3QgbG9hZEJhbGFuY2VycyA9IChcbiAgICAgIGF3YWl0IHRoaXMuY2xpZW50LnBhZ2luYXRlRGVzY3JpYmVMb2FkQmFsYW5jZXJzKHtcbiAgICAgICAgTG9hZEJhbGFuY2VyQXJuczogbG9hZEJhbGFuY2VyQXJucyxcbiAgICAgIH0pXG4gICAgKS5maWx0ZXIoKGxiKSA9PiBsYi5UeXBlID09PSB0aGlzLmZpbHRlci5sb2FkQmFsYW5jZXJUeXBlKTtcblxuICAgIHJldHVybiB0aGlzLmZpbHRlckJ5VGFncyhsb2FkQmFsYW5jZXJzKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZmlsdGVyQnlUYWdzKGxvYWRCYWxhbmNlcnM6IExvYWRCYWxhbmNlcltdKTogUHJvbWlzZTxMb2FkQmFsYW5jZXJbXT4ge1xuICAgIGlmICghdGhpcy5maWx0ZXIubG9hZEJhbGFuY2VyVGFncykge1xuICAgICAgcmV0dXJuIGxvYWRCYWxhbmNlcnM7XG4gICAgfVxuICAgIHJldHVybiAoYXdhaXQgdGhpcy5kZXNjcmliZVRhZ3MobG9hZEJhbGFuY2Vycy5tYXAoKGxiKSA9PiBsYi5Mb2FkQmFsYW5jZXJBcm4hKSkpXG4gICAgICAuZmlsdGVyKCh0YWdEZXNjcmlwdGlvbikgPT4ge1xuICAgICAgICAvLyBGb3IgZXZlcnkgdGFnIGluIHRoZSBmaWx0ZXIsIHRoZXJlIGlzIHNvbWUgdGFnIGluIHRoZSBMQiB0aGF0IG1hdGNoZXMgaXQuXG4gICAgICAgIC8vIEluIG90aGVyIHdvcmRzLCB0aGUgc2V0IG9mIHRhZ3MgaW4gdGhlIGZpbHRlciBpcyBhIHN1YnNldCBvZiB0aGUgc2V0IG9mIHRhZ3MgaW4gdGhlIExCLlxuICAgICAgICByZXR1cm4gdGhpcy5maWx0ZXIubG9hZEJhbGFuY2VyVGFncyEuZXZlcnkoKGZpbHRlcikgPT4ge1xuICAgICAgICAgIHJldHVybiB0YWdEZXNjcmlwdGlvbi5UYWdzPy5zb21lKCh0YWcpID0+XG4gICAgICAgICAgICBmaWx0ZXIua2V5ID09PSB0YWcuS2V5ICYmIGZpbHRlci52YWx1ZSA9PT0gdGFnLlZhbHVlKTtcbiAgICAgICAgfSk7XG4gICAgICB9KVxuICAgICAgLmZsYXRNYXAoKHRhZykgPT4gbG9hZEJhbGFuY2Vycy5maWx0ZXIoKGxvYWRCYWxhbmNlcikgPT4gdGFnLlJlc291cmNlQXJuID09PSBsb2FkQmFsYW5jZXIuTG9hZEJhbGFuY2VyQXJuKSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0YWcgZGVzY3JpcHRpb25zIGFzc29jaWF0ZWQgd2l0aCB0aGUgcmVzb3VyY2VzLiBUaGUgQVBJIGRvZXNuJ3Qgc3VwcG9ydFxuICAgKiBwYWdpbmF0aW9uLCBzbyB0aGlzIGZ1bmN0aW9uIGJyZWFrcyB0aGUgcmVzb3VyY2UgbGlzdCBpbnRvIGNodW5rcyBhbmQgaXNzdWVzXG4gICAqIHRoZSBhcHByb3ByaWF0ZSByZXF1ZXN0cy5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZGVzY3JpYmVUYWdzKHJlc291cmNlQXJuczogc3RyaW5nW10pOiBQcm9taXNlPFRhZ0Rlc2NyaXB0aW9uW10+IHtcbiAgICAvLyBNYXggb2YgMjAgcmVzb3VyY2UgYXJucyBwZXIgcmVxdWVzdC5cbiAgICBjb25zdCBjaHVua1NpemUgPSAyMDtcbiAgICBjb25zdCB0YWdzID0gQXJyYXk8VGFnRGVzY3JpcHRpb24+KCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXNvdXJjZUFybnMubGVuZ3RoOyBpICs9IGNodW5rU2l6ZSkge1xuICAgICAgY29uc3QgY2h1bmsgPSByZXNvdXJjZUFybnMuc2xpY2UoaSwgTWF0aC5taW4oaSArIGNodW5rU2l6ZSwgcmVzb3VyY2VBcm5zLmxlbmd0aCkpO1xuICAgICAgY29uc3QgY2h1bmtUYWdzID0gYXdhaXQgdGhpcy5jbGllbnQuZGVzY3JpYmVUYWdzKHtcbiAgICAgICAgUmVzb3VyY2VBcm5zOiBjaHVuayxcbiAgICAgIH0pO1xuXG4gICAgICB0YWdzLnB1c2goLi4uKGNodW5rVGFncy5UYWdEZXNjcmlwdGlvbnMgfHwgW10pKTtcbiAgICB9XG4gICAgcmV0dXJuIHRhZ3M7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGdldExpc3RlbmVyc0ZvckxvYWRCYWxhbmNlcnMobG9hZEJhbGFuY2VyczogTG9hZEJhbGFuY2VyW10pOiBQcm9taXNlPExpc3RlbmVyW10+IHtcbiAgICBjb25zdCBsaXN0ZW5lcnM6IExpc3RlbmVyW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IGxvYWRCYWxhbmNlciBvZiBsb2FkQmFsYW5jZXJzLm1hcCgobGIpID0+IGxiLkxvYWRCYWxhbmNlckFybikpIHtcbiAgICAgIGxpc3RlbmVycy5wdXNoKC4uLihhd2FpdCB0aGlzLmNsaWVudC5wYWdpbmF0ZURlc2NyaWJlTGlzdGVuZXJzKHsgTG9hZEJhbGFuY2VyQXJuOiBsb2FkQmFsYW5jZXIgfSkpKTtcbiAgICB9XG4gICAgcmV0dXJuIGxpc3RlbmVycztcbiAgfVxufVxuIl19