UNPKG

@taimos/cdk-controltower

Version:

[![npm version](https://badge.fury.io/js/@taimos%2Fcdk-controltower.svg)](https://badge.fury.io/js/@taimos%2Fcdk-controltower)

91 lines (86 loc) 16 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.generateAccountFile = generateAccountFile; exports.generateSsoConfigFile = generateSsoConfigFile; const client_identitystore_1 = require("@aws-sdk/client-identitystore"); const client_organizations_1 = require("@aws-sdk/client-organizations"); const client_sso_admin_1 = require("@aws-sdk/client-sso-admin"); async function generateAccountFile() { var _a; const client = new client_organizations_1.OrganizationsClient({ region: 'eu-central-1' }); const accounts = {}; let NextToken; // Loop through all AWS accounts in the organization do { // Get the list of accounts from AWS Organizations API const res = await client.send(new client_organizations_1.ListAccountsCommand({ NextToken })); // Store the returned accounts in the `accounts` object (_a = res.Accounts) === null || _a === void 0 ? void 0 : _a.forEach(account => accounts[account.Name] = account); NextToken = res.NextToken; } while (NextToken); // Sort the accounts by name const orderedAccounts = Object.keys(accounts).sort().reduce((obj, key) => { obj[key] = accounts[key]; return obj; }, {}); // Return the generated file as a string return `// THIS FILE IS GENERATED; DO NOT MODIFY MANUALLY /* eslint-disable quotes */ /* eslint-disable quote-props */ /* eslint-disable comma-dangle */ import { AccountList } from '@taimos/cdk-controltower'; /** Type that represents the possible account names */ export type AccountName = ${Object.keys(orderedAccounts).map(name => `'${name}'`).join(' | ')}; /** Object that contains all the AWS accounts in the organization */ export const ACCOUNTS: AccountList<AccountName> = ${JSON.stringify(orderedAccounts, null, 2)}; `; } async function generateSsoConfigFile() { var _a, _b; const idClient = new client_identitystore_1.IdentitystoreClient({}); const ssoClient = new client_sso_admin_1.SSOAdminClient({}); // retrieve a list of SSO instances const instances = await ssoClient.send(new client_sso_admin_1.ListInstancesCommand({})); // check if there's only one instance of SSO, throw an error if there's more or less if (((_a = instances.Instances) === null || _a === void 0 ? void 0 : _a.length) !== 1) { throw new Error('Cannot find unique SSO instance'); } // store the first (and only) instance in the 'ssoInstance' variable const ssoInstance = instances.Instances[0]; const groups = {}; let NextToken; // keep retrieving the groups until there are no more do { // retrieve a list of groups using the IdentityStoreId of the SSO instance const res = await idClient.send(new client_identitystore_1.ListGroupsCommand({ IdentityStoreId: ssoInstance.IdentityStoreId, NextToken })); // add each group to the 'groups' object, using the display name as the key and removing the 'IdentityStoreId' property from each group (_b = res.Groups) === null || _b === void 0 ? void 0 : _b.forEach(grp => { delete grp.IdentityStoreId; groups[grp.DisplayName] = grp; }); NextToken = res.NextToken; } while (NextToken); // sort the group names and create an object where the keys are sorted group names and the values are the corresponding groups const orderedGroups = Object.keys(groups).sort().reduce((obj, key) => { obj[key] = groups[key]; return obj; }, {}); // return the generated file content as a string, including comments and import statements return `// THIS FILE IS GENERATED; DO NOT MODIFY MANUALLY /* eslint-disable quotes */ /* eslint-disable quote-props */ /* eslint-disable comma-dangle */ import { GroupList, SsoConfig } from '@taimos/cdk-controltower'; /** type for the group names, using a union of string literals */ export type GroupName = ${Object.keys(orderedGroups).map(name => `'${name}'`).join(' | ')}; /** object literal that maps group names to their corresponding group details */ export const GROUPS: GroupList<GroupName> = ${JSON.stringify(orderedGroups, null, 2)}; /** object literal that represents the SSO configuration, including the instance ARN, identity store ID, and groups */ export const SSO_CONFIG: SsoConfig<GroupName> = { instanceArn: '${ssoInstance.InstanceArn}', identityStoreId: '${ssoInstance.IdentityStoreId}', groups: GROUPS, }; `; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXdzLW9yZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9hd3Mtb3JnLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBb0VBLGtEQXNDQztBQUVELHNEQTREQztBQXhLRCx3RUFBdUg7QUFDdkgsd0VBQTZIO0FBQzdILGdFQUFpRjtBQWtFMUUsS0FBSyxVQUFVLG1CQUFtQjs7SUFDdkMsTUFBTSxNQUFNLEdBQUcsSUFBSSwwQ0FBbUIsQ0FBQyxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUUsQ0FBQyxDQUFDO0lBRW5FLE1BQU0sUUFBUSxHQUFnQyxFQUFFLENBQUM7SUFDakQsSUFBSSxTQUFTLENBQUM7SUFFZCxvREFBb0Q7SUFDcEQsR0FBRyxDQUFDO1FBQ0Ysc0RBQXNEO1FBQ3RELE1BQU0sR0FBRyxHQUFJLE1BQU0sTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLDBDQUFtQixDQUFDLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBK0IsQ0FBQztRQUVyRyx1REFBdUQ7UUFDdkQsTUFBQSxHQUFHLENBQUMsUUFBUSwwQ0FBRSxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLElBQUssQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDO1FBQ3BFLFNBQVMsR0FBRyxHQUFHLENBQUMsU0FBUyxDQUFDO0lBQzVCLENBQUMsUUFBUSxTQUFTLEVBQUU7SUFFcEIsNEJBQTRCO0lBQzVCLE1BQU0sZUFBZSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsTUFBTSxDQUN6RCxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRTtRQUNYLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDekIsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDLEVBQ0QsRUFBaUMsQ0FDbEMsQ0FBQztJQUVGLHdDQUF3QztJQUN4QyxPQUFPOzs7Ozs7OzRCQU9tQixNQUFNLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDOzs7b0RBR3pDLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7Q0FDM0YsQ0FBQztBQUNGLENBQUM7QUFFTSxLQUFLLFVBQVUscUJBQXFCOztJQUN6QyxNQUFNLFFBQVEsR0FBRyxJQUFJLDBDQUFtQixDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQzdDLE1BQU0sU0FBUyxHQUFHLElBQUksaUNBQWMsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUV6QyxtQ0FBbUM7SUFDbkMsTUFBTSxTQUFTLEdBQUcsTUFBTSxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksdUNBQW9CLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUVyRSxvRkFBb0Y7SUFDcEYsSUFBSSxDQUFBLE1BQUEsU0FBUyxDQUFDLFNBQVMsMENBQUUsTUFBTSxNQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3RDLE1BQU0sSUFBSSxLQUFLLENBQUMsaUNBQWlDLENBQUMsQ0FBQztJQUNyRCxDQUFDO0lBQ0Qsb0VBQW9FO0lBQ3BFLE1BQU0sV0FBVyxHQUFHLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFM0MsTUFBTSxNQUFNLEdBQThCLEVBQUUsQ0FBQztJQUM3QyxJQUFJLFNBQVMsQ0FBQztJQUVkLHFEQUFxRDtJQUNyRCxHQUFHLENBQUM7UUFDRiwwRUFBMEU7UUFDMUUsTUFBTSxHQUFHLEdBQUksTUFBTSxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksd0NBQWlCLENBQUMsRUFBRSxlQUFlLEVBQUUsV0FBVyxDQUFDLGVBQWdCLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBNkIsQ0FBQztRQUVsSix1SUFBdUk7UUFDdkksTUFBQSxHQUFHLENBQUMsTUFBTSwwQ0FBRSxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDeEIsT0FBTyxHQUFHLENBQUMsZUFBZSxDQUFDO1lBQzNCLE1BQU0sQ0FBQyxHQUFHLENBQUMsV0FBWSxDQUFDLEdBQUcsR0FBRyxDQUFDO1FBQ2pDLENBQUMsQ0FBQyxDQUFDO1FBRUgsU0FBUyxHQUFHLEdBQUcsQ0FBQyxTQUFTLENBQUM7SUFDNUIsQ0FBQyxRQUFRLFNBQVMsRUFBRTtJQUVwQiw4SEFBOEg7SUFDOUgsTUFBTSxhQUFhLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxNQUFNLENBQ3JELENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFO1FBQ1gsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN2QixPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUMsRUFDRCxFQUErQixDQUNoQyxDQUFDO0lBRUYsMEZBQTBGO0lBQzFGLE9BQU87Ozs7Ozs7MEJBT2lCLE1BQU0sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7Ozs4Q0FHM0MsSUFBSSxDQUFDLFNBQVMsQ0FBQyxhQUFhLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQzs7OztrQkFJbEUsV0FBVyxDQUFDLFdBQVc7c0JBQ25CLFdBQVcsQ0FBQyxlQUFlOzs7Q0FHaEQsQ0FBQztBQUNGLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBHcm91cCwgSWRlbnRpdHlzdG9yZUNsaWVudCwgTGlzdEdyb3Vwc0NvbW1hbmQsIExpc3RHcm91cHNDb21tYW5kT3V0cHV0IH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LWlkZW50aXR5c3RvcmUnO1xuaW1wb3J0IHsgQWNjb3VudCwgTGlzdEFjY291bnRzQ29tbWFuZCwgTGlzdEFjY291bnRzQ29tbWFuZE91dHB1dCwgT3JnYW5pemF0aW9uc0NsaWVudCB9IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1vcmdhbml6YXRpb25zJztcbmltcG9ydCB7IExpc3RJbnN0YW5jZXNDb21tYW5kLCBTU09BZG1pbkNsaWVudCB9IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1zc28tYWRtaW4nO1xuaW1wb3J0IHsgRW52aXJvbm1lbnQgfSBmcm9tICdhd3MtY2RrLWxpYic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQWNjb3VudEluZm8ge1xuICByZWFkb25seSBJZDogc3RyaW5nO1xuICByZWFkb25seSBOYW1lOiBzdHJpbmc7XG4gIHJlYWRvbmx5IEVtYWlsOiBzdHJpbmc7XG4gIHJlYWRvbmx5IEFybjogc3RyaW5nO1xuICByZWFkb25seSBKb2luZWRNZXRob2Q6IHN0cmluZztcbiAgcmVhZG9ubHkgSm9pbmVkVGltZXN0YW1wOiBzdHJpbmc7XG4gIHJlYWRvbmx5IFN0YXR1czogc3RyaW5nO1xufVxuXG5leHBvcnQgdHlwZSBBY2NvdW50TGlzdDxUIGV4dGVuZHMgc3RyaW5nPiA9IHsgW25hbWUgaW4gVF06IEFjY291bnRJbmZvIH07XG5leHBvcnQgdHlwZSBBY2NvdW50Q29uZmlnPFQgZXh0ZW5kcyBzdHJpbmcsIFY+ID0geyBbbmFtZSBpbiBUXT86IFYgfTtcbmV4cG9ydCB0eXBlIEdyb3VwQ29uZmlnPFQgZXh0ZW5kcyBzdHJpbmcsIFY+ID0geyBbbmFtZSBpbiBUXT86IFYgfTtcblxuZXhwb3J0IGludGVyZmFjZSBHcm91cEluZm8ge1xuICByZWFkb25seSBHcm91cElkOiBzdHJpbmc7XG4gIHJlYWRvbmx5IERpc3BsYXlOYW1lOiBzdHJpbmc7XG4gIHJlYWRvbmx5IEV4dGVybmFsSWRzPzogeyBJc3N1ZXI6IHN0cmluZzsgSWQ6IHN0cmluZyB9W107XG4gIHJlYWRvbmx5IERlc2NyaXB0aW9uPzogc3RyaW5nO1xufVxuZXhwb3J0IHR5cGUgR3JvdXBMaXN0PFQgZXh0ZW5kcyBzdHJpbmc+ID0geyBbbmFtZSBpbiBUXTogR3JvdXBJbmZvIH07XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3NvQ29uZmlnPFQgZXh0ZW5kcyBzdHJpbmc+IHtcbiAgcmVhZG9ubHkgaW5zdGFuY2VBcm46IHN0cmluZztcbiAgcmVhZG9ubHkgaWRlbnRpdHlTdG9yZUlkOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGdyb3VwczogR3JvdXBMaXN0PFQ+O1xufVxuXG4vKipcbiAqXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT3JnUHJpbmNpcGFsQXdhcmUge1xuICAvKipcbiAgICogVGhlIG9yZ2FuaXphdGlvbiBwcmluY2lwYWwgYWNjb3VudFxuICAgKi9cbiAgcmVhZG9ubHkgb3JnUHJpbmNpcGFsRW52OiBFbnZpcm9ubWVudDtcbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIG9mIGEgY2RrLWNvbnRyb2x0b3dlciBzdGFjayBzdGFja1xuICpcbiAqIEBwYXJhbSBUIC0gdGhlIEFjY291bnROYW1lIHR5cGUgb2YgdGhlIGdlbmVyYXRlZCBhY2NvdW50IGxpc3RcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb250cm9sVG93ZXJQcm9wczxUIGV4dGVuZHMgc3RyaW5nPiB7XG4gIC8qKlxuICAgKiBUaGUgbGlzdCBvZiBBV1MgYWNjb3VudHMuIENhbiBiZSBnZW5lcmF0ZWQgYnkgcnVubmluZyBgbnB4IGZldGNoLWFjY291bnRzYFxuICAgKi9cbiAgcmVhZG9ubHkgYWNjb3VudHM6IEFjY291bnRMaXN0PFQ+O1xufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgb2YgdGhlIFNTTyBzdGFja1xuICpcbiAqIEBwYXJhbSBUIC0gdGhlIEFjY291bnROYW1lIHR5cGUgb2YgdGhlIGdlbmVyYXRlZCBhY2NvdW50IGxpc3RcbiAqIEBwYXJhbSBTIC0gdGhlIEdyb3VwTmFtZSB0eXBlIG9mIHRoZSBnZW5lcmF0ZWQgc3NvIGNvbmZpZ1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFNzb1Byb3BzPFQgZXh0ZW5kcyBzdHJpbmcsIFMgZXh0ZW5kcyBzdHJpbmc+IGV4dGVuZHMgQ29udHJvbFRvd2VyUHJvcHM8VD4ge1xuICAvKipcbiAgICogVGhlIGNvbmZpZ3VyYXRpb24gb2YgdGhlIEFXUyBTU08gb3JnLiBDYW4gYmUgZ2VuZXJhdGVkIGJ5IHJ1bm5pbmcgYG5weCBmZXRjaC1zc28tY29uZmlnYFxuICAgKi9cbiAgcmVhZG9ubHkgc3NvQ29uZmlnOiBTc29Db25maWc8Uz47XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZW5lcmF0ZUFjY291bnRGaWxlKCk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IGNsaWVudCA9IG5ldyBPcmdhbml6YXRpb25zQ2xpZW50KHsgcmVnaW9uOiAnZXUtY2VudHJhbC0xJyB9KTtcblxuICBjb25zdCBhY2NvdW50czogeyBbbmFtZTogc3RyaW5nXTogQWNjb3VudCB9ID0ge307XG4gIGxldCBOZXh0VG9rZW47XG5cbiAgLy8gTG9vcCB0aHJvdWdoIGFsbCBBV1MgYWNjb3VudHMgaW4gdGhlIG9yZ2FuaXphdGlvblxuICBkbyB7XG4gICAgLy8gR2V0IHRoZSBsaXN0IG9mIGFjY291bnRzIGZyb20gQVdTIE9yZ2FuaXphdGlvbnMgQVBJXG4gICAgY29uc3QgcmVzID0gKGF3YWl0IGNsaWVudC5zZW5kKG5ldyBMaXN0QWNjb3VudHNDb21tYW5kKHsgTmV4dFRva2VuIH0pKSBhcyBMaXN0QWNjb3VudHNDb21tYW5kT3V0cHV0KTtcblxuICAgIC8vIFN0b3JlIHRoZSByZXR1cm5lZCBhY2NvdW50cyBpbiB0aGUgYGFjY291bnRzYCBvYmplY3RcbiAgICByZXMuQWNjb3VudHM/LmZvckVhY2goYWNjb3VudCA9PiBhY2NvdW50c1thY2NvdW50Lk5hbWUhXSA9IGFjY291bnQpO1xuICAgIE5leHRUb2tlbiA9IHJlcy5OZXh0VG9rZW47XG4gIH0gd2hpbGUgKE5leHRUb2tlbik7XG5cbiAgLy8gU29ydCB0aGUgYWNjb3VudHMgYnkgbmFtZVxuICBjb25zdCBvcmRlcmVkQWNjb3VudHMgPSBPYmplY3Qua2V5cyhhY2NvdW50cykuc29ydCgpLnJlZHVjZShcbiAgICAob2JqLCBrZXkpID0+IHtcbiAgICAgIG9ialtrZXldID0gYWNjb3VudHNba2V5XTtcbiAgICAgIHJldHVybiBvYmo7XG4gICAgfSxcbiAgICB7fSBhcyB7IFtuYW1lOiBzdHJpbmddOiBBY2NvdW50IH0sXG4gICk7XG5cbiAgLy8gUmV0dXJuIHRoZSBnZW5lcmF0ZWQgZmlsZSBhcyBhIHN0cmluZ1xuICByZXR1cm4gYC8vIFRISVMgRklMRSBJUyBHRU5FUkFURUQ7IERPIE5PVCBNT0RJRlkgTUFOVUFMTFlcbi8qIGVzbGludC1kaXNhYmxlIHF1b3RlcyAqL1xuLyogZXNsaW50LWRpc2FibGUgcXVvdGUtcHJvcHMgKi9cbi8qIGVzbGludC1kaXNhYmxlIGNvbW1hLWRhbmdsZSAqL1xuaW1wb3J0IHsgQWNjb3VudExpc3QgfSBmcm9tICdAdGFpbW9zL2Nkay1jb250cm9sdG93ZXInO1xuXG4vKiogVHlwZSB0aGF0IHJlcHJlc2VudHMgdGhlIHBvc3NpYmxlIGFjY291bnQgbmFtZXMgKi9cbmV4cG9ydCB0eXBlIEFjY291bnROYW1lID0gJHtPYmplY3Qua2V5cyhvcmRlcmVkQWNjb3VudHMpLm1hcChuYW1lID0+IGAnJHtuYW1lfSdgKS5qb2luKCcgfCAnKX07XG5cbi8qKiBPYmplY3QgdGhhdCBjb250YWlucyBhbGwgdGhlIEFXUyBhY2NvdW50cyBpbiB0aGUgb3JnYW5pemF0aW9uICovXG5leHBvcnQgY29uc3QgQUNDT1VOVFM6IEFjY291bnRMaXN0PEFjY291bnROYW1lPiA9ICR7SlNPTi5zdHJpbmdpZnkob3JkZXJlZEFjY291bnRzLCBudWxsLCAyKX07XG5gO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2VuZXJhdGVTc29Db25maWdGaWxlKCk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IGlkQ2xpZW50ID0gbmV3IElkZW50aXR5c3RvcmVDbGllbnQoe30pO1xuICBjb25zdCBzc29DbGllbnQgPSBuZXcgU1NPQWRtaW5DbGllbnQoe30pO1xuXG4gIC8vIHJldHJpZXZlIGEgbGlzdCBvZiBTU08gaW5zdGFuY2VzXG4gIGNvbnN0IGluc3RhbmNlcyA9IGF3YWl0IHNzb0NsaWVudC5zZW5kKG5ldyBMaXN0SW5zdGFuY2VzQ29tbWFuZCh7fSkpO1xuXG4gIC8vIGNoZWNrIGlmIHRoZXJlJ3Mgb25seSBvbmUgaW5zdGFuY2Ugb2YgU1NPLCB0aHJvdyBhbiBlcnJvciBpZiB0aGVyZSdzIG1vcmUgb3IgbGVzc1xuICBpZiAoaW5zdGFuY2VzLkluc3RhbmNlcz8ubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgZmluZCB1bmlxdWUgU1NPIGluc3RhbmNlJyk7XG4gIH1cbiAgLy8gc3RvcmUgdGhlIGZpcnN0IChhbmQgb25seSkgaW5zdGFuY2UgaW4gdGhlICdzc29JbnN0YW5jZScgdmFyaWFibGVcbiAgY29uc3Qgc3NvSW5zdGFuY2UgPSBpbnN0YW5jZXMuSW5zdGFuY2VzWzBdO1xuXG4gIGNvbnN0IGdyb3VwczogeyBbbmFtZTogc3RyaW5nXTogR3JvdXAgfSA9IHt9O1xuICBsZXQgTmV4dFRva2VuO1xuXG4gIC8vIGtlZXAgcmV0cmlldmluZyB0aGUgZ3JvdXBzIHVudGlsIHRoZXJlIGFyZSBubyBtb3JlXG4gIGRvIHtcbiAgICAvLyByZXRyaWV2ZSBhIGxpc3Qgb2YgZ3JvdXBzIHVzaW5nIHRoZSBJZGVudGl0eVN0b3JlSWQgb2YgdGhlIFNTTyBpbnN0YW5jZVxuICAgIGNvbnN0IHJlcyA9IChhd2FpdCBpZENsaWVudC5zZW5kKG5ldyBMaXN0R3JvdXBzQ29tbWFuZCh7IElkZW50aXR5U3RvcmVJZDogc3NvSW5zdGFuY2UuSWRlbnRpdHlTdG9yZUlkISwgTmV4dFRva2VuIH0pKSBhcyBMaXN0R3JvdXBzQ29tbWFuZE91dHB1dCk7XG5cbiAgICAvLyBhZGQgZWFjaCBncm91cCB0byB0aGUgJ2dyb3Vwcycgb2JqZWN0LCB1c2luZyB0aGUgZGlzcGxheSBuYW1lIGFzIHRoZSBrZXkgYW5kIHJlbW92aW5nIHRoZSAnSWRlbnRpdHlTdG9yZUlkJyBwcm9wZXJ0eSBmcm9tIGVhY2ggZ3JvdXBcbiAgICByZXMuR3JvdXBzPy5mb3JFYWNoKGdycCA9PiB7XG4gICAgICBkZWxldGUgZ3JwLklkZW50aXR5U3RvcmVJZDtcbiAgICAgIGdyb3Vwc1tncnAuRGlzcGxheU5hbWUhXSA9IGdycDtcbiAgICB9KTtcblxuICAgIE5leHRUb2tlbiA9IHJlcy5OZXh0VG9rZW47XG4gIH0gd2hpbGUgKE5leHRUb2tlbik7XG5cbiAgLy8gc29ydCB0aGUgZ3JvdXAgbmFtZXMgYW5kIGNyZWF0ZSBhbiBvYmplY3Qgd2hlcmUgdGhlIGtleXMgYXJlIHNvcnRlZCBncm91cCBuYW1lcyBhbmQgdGhlIHZhbHVlcyBhcmUgdGhlIGNvcnJlc3BvbmRpbmcgZ3JvdXBzXG4gIGNvbnN0IG9yZGVyZWRHcm91cHMgPSBPYmplY3Qua2V5cyhncm91cHMpLnNvcnQoKS5yZWR1Y2UoXG4gICAgKG9iaiwga2V5KSA9PiB7XG4gICAgICBvYmpba2V5XSA9IGdyb3Vwc1trZXldO1xuICAgICAgcmV0dXJuIG9iajtcbiAgICB9LFxuICAgIHt9IGFzIHsgW25hbWU6IHN0cmluZ106IEdyb3VwIH0sXG4gICk7XG5cbiAgLy8gcmV0dXJuIHRoZSBnZW5lcmF0ZWQgZmlsZSBjb250ZW50IGFzIGEgc3RyaW5nLCBpbmNsdWRpbmcgY29tbWVudHMgYW5kIGltcG9ydCBzdGF0ZW1lbnRzXG4gIHJldHVybiBgLy8gVEhJUyBGSUxFIElTIEdFTkVSQVRFRDsgRE8gTk9UIE1PRElGWSBNQU5VQUxMWVxuLyogZXNsaW50LWRpc2FibGUgcXVvdGVzICovXG4vKiBlc2xpbnQtZGlzYWJsZSBxdW90ZS1wcm9wcyAqL1xuLyogZXNsaW50LWRpc2FibGUgY29tbWEtZGFuZ2xlICovXG5pbXBvcnQgeyBHcm91cExpc3QsIFNzb0NvbmZpZyB9IGZyb20gJ0B0YWltb3MvY2RrLWNvbnRyb2x0b3dlcic7XG5cbi8qKiB0eXBlIGZvciB0aGUgZ3JvdXAgbmFtZXMsIHVzaW5nIGEgdW5pb24gb2Ygc3RyaW5nIGxpdGVyYWxzICovXG5leHBvcnQgdHlwZSBHcm91cE5hbWUgPSAke09iamVjdC5rZXlzKG9yZGVyZWRHcm91cHMpLm1hcChuYW1lID0+IGAnJHtuYW1lfSdgKS5qb2luKCcgfCAnKX07XG5cbi8qKiBvYmplY3QgbGl0ZXJhbCB0aGF0IG1hcHMgZ3JvdXAgbmFtZXMgdG8gdGhlaXIgY29ycmVzcG9uZGluZyBncm91cCBkZXRhaWxzICovXG5leHBvcnQgY29uc3QgR1JPVVBTOiBHcm91cExpc3Q8R3JvdXBOYW1lPiA9ICR7SlNPTi5zdHJpbmdpZnkob3JkZXJlZEdyb3VwcywgbnVsbCwgMil9O1xuXG4vKiogb2JqZWN0IGxpdGVyYWwgdGhhdCByZXByZXNlbnRzIHRoZSBTU08gY29uZmlndXJhdGlvbiwgaW5jbHVkaW5nIHRoZSBpbnN0YW5jZSBBUk4sIGlkZW50aXR5IHN0b3JlIElELCBhbmQgZ3JvdXBzICovXG5leHBvcnQgY29uc3QgU1NPX0NPTkZJRzogU3NvQ29uZmlnPEdyb3VwTmFtZT4gPSB7XG4gIGluc3RhbmNlQXJuOiAnJHtzc29JbnN0YW5jZS5JbnN0YW5jZUFybn0nLFxuICBpZGVudGl0eVN0b3JlSWQ6ICcke3Nzb0luc3RhbmNlLklkZW50aXR5U3RvcmVJZH0nLFxuICBncm91cHM6IEdST1VQUyxcbn07XG5gO1xufSJdfQ==