@pepperize/cdk-organizations
Version:
Manage AWS organizations, organizational units (OU), accounts and service control policies (SCP).
126 lines • 17.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.handler = void 0;
const aws_sdk_1 = require("aws-sdk");
let organizationsClient;
const organizationsRegion = process.env.ORGANIZATIONS_ENDPOINT_REGION ?? "us-east-1";
/**
* The onEvent handler is invoked whenever a resource lifecycle event for an organizational unit occurs
*
* @see https://docs.aws.amazon.com/cdk/api/v1/docs/custom-resources-readme.html#handling-lifecycle-events-onevent
*/
const handler = async (event) => {
console.log(`Request of type ${event.RequestType} received`);
if (!organizationsClient) {
organizationsClient = new aws_sdk_1.Organizations({ region: organizationsRegion });
}
console.log("Payload: %j", event);
const { ParentId, Name, ImportOnDuplicate, RemovalPolicy } = event.ResourceProperties;
if (event.RequestType == "Create") {
try {
const organizationalUnit = await createOrganizationalUnit(organizationsClient, ParentId, Name);
return {
PhysicalResourceId: organizationalUnit.Id,
Data: {
...organizationalUnit,
},
};
}
catch (e) {
const error = e;
console.log(error);
// https://docs.aws.amazon.com/organizations/latest/APIReference/API_CreateOrganizationalUnit.html#API_CreateOrganizationalUnit_Errors
if (error.code == "DuplicateOrganizationalUnitException" && ImportOnDuplicate == "true") {
console.log(`Organizational unit already created, trying to find existing one in parent.`);
const organizationalUnit = await findOrganizationalUnitByParentAndName(organizationsClient, ParentId, Name);
return {
PhysicalResourceId: organizationalUnit.Id,
Data: {
...organizationalUnit,
},
};
}
else {
throw error;
}
}
}
if (event.RequestType == "Update") {
const organizationalUnit = await updateOrganizationalUnit(organizationsClient, event.PhysicalResourceId, Name);
return {
PhysicalResourceId: organizationalUnit.Id,
Data: {
...organizationalUnit,
},
};
}
if (event.RequestType == "Delete" && RemovalPolicy == "destroy") {
await deleteOrganizationalUnit(organizationsClient, event.PhysicalResourceId);
}
return {
PhysicalResourceId: event.PhysicalResourceId,
Data: {
...event.ResourceProperties,
},
};
};
exports.handler = handler;
const findOrganizationalUnitByParentAndName = async (client, parentId, name) => {
let response = await client
// https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Organizations.html#listOrganizationalUnitsForParent-property
.listOrganizationalUnitsForParent({ ParentId: parentId })
.promise();
for (const organizationalUnit of response.OrganizationalUnits ?? []) {
if (organizationalUnit.Name == name) {
return organizationalUnit;
}
}
while (response.NextToken) {
response = await client
.listOrganizationalUnitsForParent({ ParentId: parentId, NextToken: response.NextToken })
.promise();
for (const organizationalUnit of response.OrganizationalUnits ?? []) {
if (organizationalUnit.Name == name) {
return organizationalUnit;
}
}
}
throw new Error(`Organizational unit '${name}' not found in '${parentId}'`);
};
const createOrganizationalUnit = async (client, parentId, name) => {
const response = await client
// https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Organizations.html#createOrganizationalUnit-property
.createOrganizationalUnit({
ParentId: parentId,
Name: name,
})
.promise();
console.log("Creating organizational unit: %j", response);
if (!response.OrganizationalUnit) {
throw new Error("Could not create organizational unit, reason: empty response");
}
return response.OrganizationalUnit;
};
const updateOrganizationalUnit = async (client, id, name) => {
const response = await client
// https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Organizations.html#updateOrganizationalUnit-property
.updateOrganizationalUnit({
OrganizationalUnitId: id,
Name: name,
})
.promise();
console.log("Updating organizational unit: %j", response);
if (!response.OrganizationalUnit) {
throw new Error("Could not update organizational unit, reason: empty response");
}
return response.OrganizationalUnit;
};
const deleteOrganizationalUnit = async (client, id) => {
// https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Organizations.html#deleteOrganizationalUnit-property
await client
.deleteOrganizationalUnit({
OrganizationalUnitId: id,
})
.promise();
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib24tZXZlbnQtaGFuZGxlci5sYW1iZGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvb3JnYW5pemF0aW9uYWwtdW5pdC1wcm92aWRlci9vbi1ldmVudC1oYW5kbGVyLmxhbWJkYS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSxxQ0FBa0Q7QUFFbEQsSUFBSSxtQkFBa0MsQ0FBQztBQUN2QyxNQUFNLG1CQUFtQixHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsNkJBQTZCLElBQUksV0FBVyxDQUFDO0FBRXJGOzs7O0dBSUc7QUFDSSxNQUFNLE9BQU8sR0FBRyxLQUFLLEVBQUUsS0FBcUIsRUFBNEIsRUFBRTtJQUMvRSxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixLQUFLLENBQUMsV0FBVyxXQUFXLENBQUMsQ0FBQztJQUU3RCxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztRQUN6QixtQkFBbUIsR0FBRyxJQUFJLHVCQUFhLENBQUMsRUFBRSxNQUFNLEVBQUUsbUJBQW1CLEVBQUUsQ0FBQyxDQUFDO0lBQzNFLENBQUM7SUFFRCxPQUFPLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUVsQyxNQUFNLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxpQkFBaUIsRUFBRSxhQUFhLEVBQUUsR0FBRyxLQUFLLENBQUMsa0JBQWtCLENBQUM7SUFFdEYsSUFBSSxLQUFLLENBQUMsV0FBVyxJQUFJLFFBQVEsRUFBRSxDQUFDO1FBQ2xDLElBQUksQ0FBQztZQUNILE1BQU0sa0JBQWtCLEdBQUcsTUFBTSx3QkFBd0IsQ0FBQyxtQkFBbUIsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDL0YsT0FBTztnQkFDTCxrQkFBa0IsRUFBRSxrQkFBa0IsQ0FBQyxFQUFFO2dCQUN6QyxJQUFJLEVBQUU7b0JBQ0osR0FBRyxrQkFBa0I7aUJBQ3RCO2FBQ0YsQ0FBQztRQUNKLENBQUM7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ1gsTUFBTSxLQUFLLEdBQUcsQ0FBYSxDQUFDO1lBQzVCLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDbkIsc0lBQXNJO1lBQ3RJLElBQUksS0FBSyxDQUFDLElBQUksSUFBSSxzQ0FBc0MsSUFBSSxpQkFBaUIsSUFBSSxNQUFNLEVBQUUsQ0FBQztnQkFDeEYsT0FBTyxDQUFDLEdBQUcsQ0FBQyw2RUFBNkUsQ0FBQyxDQUFDO2dCQUMzRixNQUFNLGtCQUFrQixHQUFHLE1BQU0scUNBQXFDLENBQUMsbUJBQW1CLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUU1RyxPQUFPO29CQUNMLGtCQUFrQixFQUFFLGtCQUFrQixDQUFDLEVBQUU7b0JBQ3pDLElBQUksRUFBRTt3QkFDSixHQUFHLGtCQUFrQjtxQkFDdEI7aUJBQ0YsQ0FBQztZQUNKLENBQUM7aUJBQU0sQ0FBQztnQkFDTixNQUFNLEtBQUssQ0FBQztZQUNkLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVELElBQUksS0FBSyxDQUFDLFdBQVcsSUFBSSxRQUFRLEVBQUUsQ0FBQztRQUNsQyxNQUFNLGtCQUFrQixHQUFHLE1BQU0sd0JBQXdCLENBQUMsbUJBQW1CLEVBQUUsS0FBSyxDQUFDLGtCQUFtQixFQUFFLElBQUksQ0FBQyxDQUFDO1FBRWhILE9BQU87WUFDTCxrQkFBa0IsRUFBRSxrQkFBa0IsQ0FBQyxFQUFFO1lBQ3pDLElBQUksRUFBRTtnQkFDSixHQUFHLGtCQUFrQjthQUN0QjtTQUNGLENBQUM7SUFDSixDQUFDO0lBRUQsSUFBSSxLQUFLLENBQUMsV0FBVyxJQUFJLFFBQVEsSUFBSSxhQUFhLElBQUksU0FBUyxFQUFFLENBQUM7UUFDaEUsTUFBTSx3QkFBd0IsQ0FBQyxtQkFBbUIsRUFBRSxLQUFLLENBQUMsa0JBQW1CLENBQUMsQ0FBQztJQUNqRixDQUFDO0lBRUQsT0FBTztRQUNMLGtCQUFrQixFQUFFLEtBQUssQ0FBQyxrQkFBa0I7UUFDNUMsSUFBSSxFQUFFO1lBQ0osR0FBRyxLQUFLLENBQUMsa0JBQWtCO1NBQzVCO0tBQ0YsQ0FBQztBQUNKLENBQUMsQ0FBQztBQTdEVyxRQUFBLE9BQU8sV0E2RGxCO0FBRUYsTUFBTSxxQ0FBcUMsR0FBRyxLQUFLLEVBQ2pELE1BQXFCLEVBQ3JCLFFBQWdCLEVBQ2hCLElBQVksRUFDK0IsRUFBRTtJQUM3QyxJQUFJLFFBQVEsR0FBMkQsTUFBTSxNQUFNO1FBQ2pGLHVIQUF1SDtTQUN0SCxnQ0FBZ0MsQ0FBQyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsQ0FBQztTQUN4RCxPQUFPLEVBQUUsQ0FBQztJQUNiLEtBQUssTUFBTSxrQkFBa0IsSUFBSSxRQUFRLENBQUMsbUJBQW1CLElBQUksRUFBRSxFQUFFLENBQUM7UUFDcEUsSUFBSSxrQkFBa0IsQ0FBQyxJQUFJLElBQUksSUFBSSxFQUFFLENBQUM7WUFDcEMsT0FBTyxrQkFBa0IsQ0FBQztRQUM1QixDQUFDO0lBQ0gsQ0FBQztJQUVELE9BQU8sUUFBUSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQzFCLFFBQVEsR0FBRyxNQUFNLE1BQU07YUFDcEIsZ0NBQWdDLENBQUMsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxRQUFRLENBQUMsU0FBUyxFQUFFLENBQUM7YUFDdkYsT0FBTyxFQUFFLENBQUM7UUFDYixLQUFLLE1BQU0sa0JBQWtCLElBQUksUUFBUSxDQUFDLG1CQUFtQixJQUFJLEVBQUUsRUFBRSxDQUFDO1lBQ3BFLElBQUksa0JBQWtCLENBQUMsSUFBSSxJQUFJLElBQUksRUFBRSxDQUFDO2dCQUNwQyxPQUFPLGtCQUFrQixDQUFDO1lBQzVCLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVELE1BQU0sSUFBSSxLQUFLLENBQUMsd0JBQXdCLElBQUksbUJBQW1CLFFBQVEsR0FBRyxDQUFDLENBQUM7QUFDOUUsQ0FBQyxDQUFDO0FBRUYsTUFBTSx3QkFBd0IsR0FBRyxLQUFLLEVBQ3BDLE1BQXFCLEVBQ3JCLFFBQWdCLEVBQ2hCLElBQVksRUFDK0IsRUFBRTtJQUM3QyxNQUFNLFFBQVEsR0FBbUQsTUFBTSxNQUFNO1FBQzNFLCtHQUErRztTQUM5Ryx3QkFBd0IsQ0FBQztRQUN4QixRQUFRLEVBQUUsUUFBUTtRQUNsQixJQUFJLEVBQUUsSUFBSTtLQUNYLENBQUM7U0FDRCxPQUFPLEVBQUUsQ0FBQztJQUNiLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0NBQWtDLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFFMUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBQ2pDLE1BQU0sSUFBSSxLQUFLLENBQUMsOERBQThELENBQUMsQ0FBQztJQUNsRixDQUFDO0lBRUQsT0FBTyxRQUFRLENBQUMsa0JBQWtCLENBQUM7QUFDckMsQ0FBQyxDQUFDO0FBRUYsTUFBTSx3QkFBd0IsR0FBRyxLQUFLLEVBQ3BDLE1BQXFCLEVBQ3JCLEVBQVUsRUFDVixJQUFZLEVBQytCLEVBQUU7SUFDN0MsTUFBTSxRQUFRLEdBQW1ELE1BQU0sTUFBTTtRQUMzRSwrR0FBK0c7U0FDOUcsd0JBQXdCLENBQUM7UUFDeEIsb0JBQW9CLEVBQUUsRUFBRTtRQUN4QixJQUFJLEVBQUUsSUFBSTtLQUNYLENBQUM7U0FDRCxPQUFPLEVBQUUsQ0FBQztJQUNiLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0NBQWtDLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFFMUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBQ2pDLE1BQU0sSUFBSSxLQUFLLENBQUMsOERBQThELENBQUMsQ0FBQztJQUNsRixDQUFDO0lBRUQsT0FBTyxRQUFRLENBQUMsa0JBQWtCLENBQUM7QUFDckMsQ0FBQyxDQUFDO0FBRUYsTUFBTSx3QkFBd0IsR0FBRyxLQUFLLEVBQUUsTUFBcUIsRUFBRSxFQUFVLEVBQWlCLEVBQUU7SUFDMUYsK0dBQStHO0lBQy9HLE1BQU0sTUFBTTtTQUNULHdCQUF3QixDQUFDO1FBQ3hCLG9CQUFvQixFQUFFLEVBQUU7S0FDekIsQ0FBQztTQUNELE9BQU8sRUFBRSxDQUFDO0FBQ2YsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2RrQ3VzdG9tUmVzb3VyY2VFdmVudCBhcyBPbkV2ZW50UmVxdWVzdCwgQ2RrQ3VzdG9tUmVzb3VyY2VSZXNwb25zZSBhcyBPbkV2ZW50UmVzcG9uc2UgfSBmcm9tIFwiYXdzLWxhbWJkYVwiO1xuaW1wb3J0IHsgQVdTRXJyb3IsIE9yZ2FuaXphdGlvbnMgfSBmcm9tIFwiYXdzLXNka1wiO1xuXG5sZXQgb3JnYW5pemF0aW9uc0NsaWVudDogT3JnYW5pemF0aW9ucztcbmNvbnN0IG9yZ2FuaXphdGlvbnNSZWdpb24gPSBwcm9jZXNzLmVudi5PUkdBTklaQVRJT05TX0VORFBPSU5UX1JFR0lPTiA/PyBcInVzLWVhc3QtMVwiO1xuXG4vKipcbiAqIFRoZSBvbkV2ZW50IGhhbmRsZXIgaXMgaW52b2tlZCB3aGVuZXZlciBhIHJlc291cmNlIGxpZmVjeWNsZSBldmVudCBmb3IgYW4gb3JnYW5pemF0aW9uYWwgdW5pdCBvY2N1cnNcbiAqXG4gKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jZGsvYXBpL3YxL2RvY3MvY3VzdG9tLXJlc291cmNlcy1yZWFkbWUuaHRtbCNoYW5kbGluZy1saWZlY3ljbGUtZXZlbnRzLW9uZXZlbnRcbiAqL1xuZXhwb3J0IGNvbnN0IGhhbmRsZXIgPSBhc3luYyAoZXZlbnQ6IE9uRXZlbnRSZXF1ZXN0KTogUHJvbWlzZTxPbkV2ZW50UmVzcG9uc2U+ID0+IHtcbiAgY29uc29sZS5sb2coYFJlcXVlc3Qgb2YgdHlwZSAke2V2ZW50LlJlcXVlc3RUeXBlfSByZWNlaXZlZGApO1xuXG4gIGlmICghb3JnYW5pemF0aW9uc0NsaWVudCkge1xuICAgIG9yZ2FuaXphdGlvbnNDbGllbnQgPSBuZXcgT3JnYW5pemF0aW9ucyh7IHJlZ2lvbjogb3JnYW5pemF0aW9uc1JlZ2lvbiB9KTtcbiAgfVxuXG4gIGNvbnNvbGUubG9nKFwiUGF5bG9hZDogJWpcIiwgZXZlbnQpO1xuXG4gIGNvbnN0IHsgUGFyZW50SWQsIE5hbWUsIEltcG9ydE9uRHVwbGljYXRlLCBSZW1vdmFsUG9saWN5IH0gPSBldmVudC5SZXNvdXJjZVByb3BlcnRpZXM7XG5cbiAgaWYgKGV2ZW50LlJlcXVlc3RUeXBlID09IFwiQ3JlYXRlXCIpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgb3JnYW5pemF0aW9uYWxVbml0ID0gYXdhaXQgY3JlYXRlT3JnYW5pemF0aW9uYWxVbml0KG9yZ2FuaXphdGlvbnNDbGllbnQsIFBhcmVudElkLCBOYW1lKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIFBoeXNpY2FsUmVzb3VyY2VJZDogb3JnYW5pemF0aW9uYWxVbml0LklkLFxuICAgICAgICBEYXRhOiB7XG4gICAgICAgICAgLi4ub3JnYW5pemF0aW9uYWxVbml0LFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zdCBlcnJvciA9IGUgYXMgQVdTRXJyb3I7XG4gICAgICBjb25zb2xlLmxvZyhlcnJvcik7XG4gICAgICAvLyBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vb3JnYW5pemF0aW9ucy9sYXRlc3QvQVBJUmVmZXJlbmNlL0FQSV9DcmVhdGVPcmdhbml6YXRpb25hbFVuaXQuaHRtbCNBUElfQ3JlYXRlT3JnYW5pemF0aW9uYWxVbml0X0Vycm9yc1xuICAgICAgaWYgKGVycm9yLmNvZGUgPT0gXCJEdXBsaWNhdGVPcmdhbml6YXRpb25hbFVuaXRFeGNlcHRpb25cIiAmJiBJbXBvcnRPbkR1cGxpY2F0ZSA9PSBcInRydWVcIikge1xuICAgICAgICBjb25zb2xlLmxvZyhgT3JnYW5pemF0aW9uYWwgdW5pdCBhbHJlYWR5IGNyZWF0ZWQsIHRyeWluZyB0byBmaW5kIGV4aXN0aW5nIG9uZSBpbiBwYXJlbnQuYCk7XG4gICAgICAgIGNvbnN0IG9yZ2FuaXphdGlvbmFsVW5pdCA9IGF3YWl0IGZpbmRPcmdhbml6YXRpb25hbFVuaXRCeVBhcmVudEFuZE5hbWUob3JnYW5pemF0aW9uc0NsaWVudCwgUGFyZW50SWQsIE5hbWUpO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgUGh5c2ljYWxSZXNvdXJjZUlkOiBvcmdhbml6YXRpb25hbFVuaXQuSWQsXG4gICAgICAgICAgRGF0YToge1xuICAgICAgICAgICAgLi4ub3JnYW5pemF0aW9uYWxVbml0LFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAoZXZlbnQuUmVxdWVzdFR5cGUgPT0gXCJVcGRhdGVcIikge1xuICAgIGNvbnN0IG9yZ2FuaXphdGlvbmFsVW5pdCA9IGF3YWl0IHVwZGF0ZU9yZ2FuaXphdGlvbmFsVW5pdChvcmdhbml6YXRpb25zQ2xpZW50LCBldmVudC5QaHlzaWNhbFJlc291cmNlSWQhLCBOYW1lKTtcblxuICAgIHJldHVybiB7XG4gICAgICBQaHlzaWNhbFJlc291cmNlSWQ6IG9yZ2FuaXphdGlvbmFsVW5pdC5JZCxcbiAgICAgIERhdGE6IHtcbiAgICAgICAgLi4ub3JnYW5pemF0aW9uYWxVbml0LFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgaWYgKGV2ZW50LlJlcXVlc3RUeXBlID09IFwiRGVsZXRlXCIgJiYgUmVtb3ZhbFBvbGljeSA9PSBcImRlc3Ryb3lcIikge1xuICAgIGF3YWl0IGRlbGV0ZU9yZ2FuaXphdGlvbmFsVW5pdChvcmdhbml6YXRpb25zQ2xpZW50LCBldmVudC5QaHlzaWNhbFJlc291cmNlSWQhKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgUGh5c2ljYWxSZXNvdXJjZUlkOiBldmVudC5QaHlzaWNhbFJlc291cmNlSWQsXG4gICAgRGF0YToge1xuICAgICAgLi4uZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLFxuICAgIH0sXG4gIH07XG59O1xuXG5jb25zdCBmaW5kT3JnYW5pemF0aW9uYWxVbml0QnlQYXJlbnRBbmROYW1lID0gYXN5bmMgKFxuICBjbGllbnQ6IE9yZ2FuaXphdGlvbnMsXG4gIHBhcmVudElkOiBzdHJpbmcsXG4gIG5hbWU6IHN0cmluZ1xuKTogUHJvbWlzZTxPcmdhbml6YXRpb25zLk9yZ2FuaXphdGlvbmFsVW5pdD4gPT4ge1xuICBsZXQgcmVzcG9uc2U6IE9yZ2FuaXphdGlvbnMuTGlzdE9yZ2FuaXphdGlvbmFsVW5pdHNGb3JQYXJlbnRSZXNwb25zZSA9IGF3YWl0IGNsaWVudFxuICAgIC8vIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NKYXZhU2NyaXB0U0RLL2xhdGVzdC9BV1MvT3JnYW5pemF0aW9ucy5odG1sI2xpc3RPcmdhbml6YXRpb25hbFVuaXRzRm9yUGFyZW50LXByb3BlcnR5XG4gICAgLmxpc3RPcmdhbml6YXRpb25hbFVuaXRzRm9yUGFyZW50KHsgUGFyZW50SWQ6IHBhcmVudElkIH0pXG4gICAgLnByb21pc2UoKTtcbiAgZm9yIChjb25zdCBvcmdhbml6YXRpb25hbFVuaXQgb2YgcmVzcG9uc2UuT3JnYW5pemF0aW9uYWxVbml0cyA/PyBbXSkge1xuICAgIGlmIChvcmdhbml6YXRpb25hbFVuaXQuTmFtZSA9PSBuYW1lKSB7XG4gICAgICByZXR1cm4gb3JnYW5pemF0aW9uYWxVbml0O1xuICAgIH1cbiAgfVxuXG4gIHdoaWxlIChyZXNwb25zZS5OZXh0VG9rZW4pIHtcbiAgICByZXNwb25zZSA9IGF3YWl0IGNsaWVudFxuICAgICAgLmxpc3RPcmdhbml6YXRpb25hbFVuaXRzRm9yUGFyZW50KHsgUGFyZW50SWQ6IHBhcmVudElkLCBOZXh0VG9rZW46IHJlc3BvbnNlLk5leHRUb2tlbiB9KVxuICAgICAgLnByb21pc2UoKTtcbiAgICBmb3IgKGNvbnN0IG9yZ2FuaXphdGlvbmFsVW5pdCBvZiByZXNwb25zZS5Pcmdhbml6YXRpb25hbFVuaXRzID8/IFtdKSB7XG4gICAgICBpZiAob3JnYW5pemF0aW9uYWxVbml0Lk5hbWUgPT0gbmFtZSkge1xuICAgICAgICByZXR1cm4gb3JnYW5pemF0aW9uYWxVbml0O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcihgT3JnYW5pemF0aW9uYWwgdW5pdCAnJHtuYW1lfScgbm90IGZvdW5kIGluICcke3BhcmVudElkfSdgKTtcbn07XG5cbmNvbnN0IGNyZWF0ZU9yZ2FuaXphdGlvbmFsVW5pdCA9IGFzeW5jIChcbiAgY2xpZW50OiBPcmdhbml6YXRpb25zLFxuICBwYXJlbnRJZDogc3RyaW5nLFxuICBuYW1lOiBzdHJpbmdcbik6IFByb21pc2U8T3JnYW5pemF0aW9ucy5Pcmdhbml6YXRpb25hbFVuaXQ+ID0+IHtcbiAgY29uc3QgcmVzcG9uc2U6IE9yZ2FuaXphdGlvbnMuQ3JlYXRlT3JnYW5pemF0aW9uYWxVbml0UmVzcG9uc2UgPSBhd2FpdCBjbGllbnRcbiAgICAvLyBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTSmF2YVNjcmlwdFNESy9sYXRlc3QvQVdTL09yZ2FuaXphdGlvbnMuaHRtbCNjcmVhdGVPcmdhbml6YXRpb25hbFVuaXQtcHJvcGVydHlcbiAgICAuY3JlYXRlT3JnYW5pemF0aW9uYWxVbml0KHtcbiAgICAgIFBhcmVudElkOiBwYXJlbnRJZCxcbiAgICAgIE5hbWU6IG5hbWUsXG4gICAgfSlcbiAgICAucHJvbWlzZSgpO1xuICBjb25zb2xlLmxvZyhcIkNyZWF0aW5nIG9yZ2FuaXphdGlvbmFsIHVuaXQ6ICVqXCIsIHJlc3BvbnNlKTtcblxuICBpZiAoIXJlc3BvbnNlLk9yZ2FuaXphdGlvbmFsVW5pdCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkNvdWxkIG5vdCBjcmVhdGUgb3JnYW5pemF0aW9uYWwgdW5pdCwgcmVhc29uOiBlbXB0eSByZXNwb25zZVwiKTtcbiAgfVxuXG4gIHJldHVybiByZXNwb25zZS5Pcmdhbml6YXRpb25hbFVuaXQ7XG59O1xuXG5jb25zdCB1cGRhdGVPcmdhbml6YXRpb25hbFVuaXQgPSBhc3luYyAoXG4gIGNsaWVudDogT3JnYW5pemF0aW9ucyxcbiAgaWQ6IHN0cmluZyxcbiAgbmFtZTogc3RyaW5nXG4pOiBQcm9taXNlPE9yZ2FuaXphdGlvbnMuT3JnYW5pemF0aW9uYWxVbml0PiA9PiB7XG4gIGNvbnN0IHJlc3BvbnNlOiBPcmdhbml6YXRpb25zLlVwZGF0ZU9yZ2FuaXphdGlvbmFsVW5pdFJlc3BvbnNlID0gYXdhaXQgY2xpZW50XG4gICAgLy8gaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0phdmFTY3JpcHRTREsvbGF0ZXN0L0FXUy9Pcmdhbml6YXRpb25zLmh0bWwjdXBkYXRlT3JnYW5pemF0aW9uYWxVbml0LXByb3BlcnR5XG4gICAgLnVwZGF0ZU9yZ2FuaXphdGlvbmFsVW5pdCh7XG4gICAgICBPcmdhbml6YXRpb25hbFVuaXRJZDogaWQsXG4gICAgICBOYW1lOiBuYW1lLFxuICAgIH0pXG4gICAgLnByb21pc2UoKTtcbiAgY29uc29sZS5sb2coXCJVcGRhdGluZyBvcmdhbml6YXRpb25hbCB1bml0OiAlalwiLCByZXNwb25zZSk7XG5cbiAgaWYgKCFyZXNwb25zZS5Pcmdhbml6YXRpb25hbFVuaXQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb3VsZCBub3QgdXBkYXRlIG9yZ2FuaXphdGlvbmFsIHVuaXQsIHJlYXNvbjogZW1wdHkgcmVzcG9uc2VcIik7XG4gIH1cblxuICByZXR1cm4gcmVzcG9uc2UuT3JnYW5pemF0aW9uYWxVbml0O1xufTtcblxuY29uc3QgZGVsZXRlT3JnYW5pemF0aW9uYWxVbml0ID0gYXN5bmMgKGNsaWVudDogT3JnYW5pemF0aW9ucywgaWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAvLyBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTSmF2YVNjcmlwdFNESy9sYXRlc3QvQVdTL09yZ2FuaXphdGlvbnMuaHRtbCNkZWxldGVPcmdhbml6YXRpb25hbFVuaXQtcHJvcGVydHlcbiAgYXdhaXQgY2xpZW50XG4gICAgLmRlbGV0ZU9yZ2FuaXphdGlvbmFsVW5pdCh7XG4gICAgICBPcmdhbml6YXRpb25hbFVuaXRJZDogaWQsXG4gICAgfSlcbiAgICAucHJvbWlzZSgpO1xufTtcbiJdfQ==