UNPKG

@cloud-copilot/iam-collect

Version:

Collect IAM information from AWS Accounts

346 lines 13.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getDefaultAuthConfig = getDefaultAuthConfig; exports.servicesForAccount = servicesForAccount; exports.customConfigForSync = customConfigForSync; exports.configuredRegionListForAccount = configuredRegionListForAccount; exports.regionsForService = regionsForService; exports.accountServiceRegionConfig = accountServiceRegionConfig; exports.getAccountAuthConfig = getAccountAuthConfig; exports.getStorageConfig = getStorageConfig; exports.syncEnabledForRegion = syncEnabledForRegion; exports.getConfiguredAccounts = getConfiguredAccounts; exports.getConfiguredDataSource = getConfiguredDataSource; /** * Get the default auth config from the provided configs. * * @param configs the configs to search for the default auth config * @returns the default auth config, or an empty object if none found */ function getDefaultAuthConfig(configs) { // Return the last config with an auth config, or an empty object if none found for (let i = configs.length - 1; i >= 0; i--) { const configAuth = configs[i].auth; if (configAuth) { return configAuth; } } return {}; } function servicesForAccount(account, configs, allServices) { let services = allServices; for (const config of configs) { if (config.services?.included) { services = intersection(allServices, config.services.included); } if (config.services?.excluded) { services = difference(services, config.services.excluded); } const accountServices = config.accountConfigs?.[account]?.services; if (accountServices) { if (accountServices.included) { for (const service of accountServices.included) { if (!services.includes(service) && allServices.includes(service)) { services.push(service); } } } if (accountServices.excluded) { services = difference(services, accountServices.excluded); } } } return services; } /** * Look up the custom config for a specific sync for a service in an account and region. * * @param service the service to look up the sync for * @param syncName the name of the sync to look up * @param account the account to look up the sync for * @param region the region to look up the sync for * @param configs the configs to search * @returns the custom config for the sync, or undefined if not found */ function customConfigForSync(service, syncName, account, region, configs) { // Look up the custom config for the specified service and sync name for (const config of [...configs].reverse()) { const accountServiceConfig = config.accountConfigs?.[account]?.serviceConfigs?.[service]; const accountServiceRegionConfig = accountServiceConfig?.regionConfigs?.[region]?.syncConfigs?.[syncName]; if (accountServiceRegionConfig?.custom) { return accountServiceRegionConfig.custom; } if (accountServiceConfig?.syncConfigs?.[syncName]?.custom) { return accountServiceConfig.syncConfigs[syncName].custom; } const serviceRegionConfig = config.serviceConfigs?.[service]?.regionConfigs?.[region]; if (serviceRegionConfig?.syncConfigs?.[syncName]?.custom) { return serviceRegionConfig.syncConfigs[syncName].custom; } const serviceConfig = config.serviceConfigs?.[service]; if (serviceConfig?.syncConfigs?.[syncName]?.custom) { return serviceConfig.syncConfigs[syncName].custom; } } return undefined; } /** * Look up the region list from the provided configs, if any. * * @param configs the configs to search * @param accountId the account id to look up the region list for * @returns the configured region list for the account, or undefined if none found */ function configuredRegionListForAccount(configs, accountId) { let accountRegionList = undefined; let masterRegionList = undefined; for (const config of configs) { if (config.accountConfigs?.[accountId]?.regions?.included) { accountRegionList = config.accountConfigs[accountId].regions.included; } if (config.regions?.included) { masterRegionList = config.regions.included; } } return accountRegionList || masterRegionList; } /** * Get the regions for a specific service and account. * * @param service the service to get the regions for * @param account the account to get the regions for * @param configs the configs to search * @param allRegions the list of all regions to filter from * @returns the regions for the service and account */ function regionsForService(service, account, configs, allRegions) { let regions = allRegions; for (const config of configs) { if (config.regions?.included) { regions = intersection(allRegions, config.regions.included); } if (config.regions?.excluded) { regions = difference(regions, config.regions.excluded); } const serviceConfig = config.serviceConfigs?.[service]; if (serviceConfig) { if (serviceConfig.regions?.included) { regions = intersection(allRegions, serviceConfig.regions.included); } if (serviceConfig.regions?.excluded) { regions = difference(regions, serviceConfig.regions.excluded); } } const accountConfig = config.accountConfigs?.[account]; if (accountConfig) { if (accountConfig.regions?.included) { regions = intersection(allRegions, accountConfig.regions.included); } if (accountConfig.regions?.excluded) { regions = difference(regions, accountConfig.regions.excluded); } const accountServices = accountConfig.serviceConfigs?.[service]; if (accountServices) { if (accountServices.regions?.included) { regions = intersection(allRegions, accountServices.regions.included); } if (accountServices.regions?.excluded) { regions = difference(regions, accountServices.regions.excluded); } } } } return regions; } function accountServiceRegionConfig(service, accountId, region, configs) { let result = { accountId: accountId, service, region }; for (const config of configs) { if (config.auth) { result.auth = config.auth; } const serviceConfig = config.serviceConfigs?.[service]; if (serviceConfig) { if (serviceConfig.auth) { result.auth = mergeAuthConfigs(result.auth, serviceConfig.auth); } if (serviceConfig.endpoint) { result.endpoint = serviceConfig.endpoint; } const regionConfig = serviceConfig.regionConfigs?.[region]; if (regionConfig) { if (regionConfig.auth) { result.auth = mergeAuthConfigs(result.auth, regionConfig.auth); } if (regionConfig.endpoint) { result.endpoint = regionConfig.endpoint; } } } const accountConfig = config.accountConfigs?.[accountId]; if (accountConfig) { if (accountConfig.auth) { result.auth = mergeAuthConfigs(result.auth, accountConfig.auth); } const accountServiceConfig = accountConfig.serviceConfigs?.[service]; if (accountServiceConfig) { if (accountServiceConfig.auth) { result.auth = mergeAuthConfigs(result.auth, accountServiceConfig.auth); } if (accountServiceConfig.endpoint) { result.endpoint = accountServiceConfig.endpoint; } const accountRegionConfig = accountServiceConfig.regionConfigs?.[region]; if (accountRegionConfig) { if (accountRegionConfig.auth) { result.auth = mergeAuthConfigs(result.auth, accountRegionConfig.auth); } if (accountRegionConfig.endpoint) { result.endpoint = accountRegionConfig.endpoint; } } } } } return result; } /** * Get the auth config for a specific account * * @param accountId the account id to get the auth config for * @param configs the configs to search * @returns the auth config for the account, or undefined if not found */ function getAccountAuthConfig(accountId, configs) { let result = undefined; for (const config of configs) { if (config.auth) { result = config.auth; } const accountConfig = config.accountConfigs?.[accountId]; if (accountConfig?.auth) { result = mergeAuthConfigs(result, accountConfig.auth); } } return result; } function getStorageConfig(configs) { const reverseConfigs = [...configs].reverse(); // Iterate through the configs to find the first storage config for (const config of reverseConfigs) { if (config.storage) { return config.storage; } } // Return undefined if no storage config is found return undefined; } /** * Check if a specific sync is enabled for given region. This checks the specific sync config within the service. * * This should only be used after the sync has been validated to be enabled for the account and service. * * @param accountId the account id to check * @param service the service to check * @param syncName the specific name of the sync to check * @param configs the configs to check * @param region the region being tested * @returns true if the sync is enabled for the region, false otherwise */ function syncEnabledForRegion(accountId, service, syncName, configs, region) { // go through the configs in reverse order, // If any have the sync enabled return true, // If any have the sync disabled return false // If none are found, return true for (const config of [...configs].reverse()) { const accountServiceConfig = config.accountConfigs?.[accountId]?.serviceConfigs?.[service]?.syncConfigs?.[syncName]; if (accountServiceConfig) { if (accountServiceConfig.regions?.excluded?.includes(region)) { return false; } if (accountServiceConfig.regions?.included) { return accountServiceConfig.regions.included.includes(region); } } const serviceConfig = config.serviceConfigs?.[service]?.syncConfigs?.[syncName]; if (serviceConfig) { if (serviceConfig.regions?.excluded?.includes(region)) { return false; } if (serviceConfig.regions?.included) { return serviceConfig.regions.included.includes(region); } } } return true; } /** * Get the default accounts from the provided configs. * * @param configs the configs to search for the default accounts * @returns the default accounts, or an empty array if none found */ function getConfiguredAccounts(configs) { const reverseConfigs = [...configs].reverse(); for (const config of reverseConfigs) { if (config.accounts?.included) { return config.accounts.included; } } return []; } /** * Get the data source configuration from the provided configs. * * @param configs the configs to search for the data source configuration * @returns the data source configuration, or undefined if none found */ function getConfiguredDataSource(configs) { const reverseConfigs = [...configs].reverse(); for (const config of reverseConfigs) { if (config.dataSource) { return config.dataSource; } } return undefined; } function mergeAuthConfigs(initialConfig, newConfig) { if (!initialConfig) { initialConfig = {}; } if (!newConfig) { return initialConfig; } initialConfig = structuredClone(initialConfig); if ('profile' in newConfig) { initialConfig.profile = newConfig.profile; } if ('initialRole' in newConfig) { if (newConfig.initialRole === null) { delete initialConfig.initialRole; } else { initialConfig.initialRole = { ...(initialConfig.initialRole || {}), ...newConfig.initialRole }; } } if ('role' in newConfig) { initialConfig.role = { ...(initialConfig.role || {}), ...newConfig.role }; } return initialConfig; } function intersection(a, b) { return a.filter((value) => b.includes(value)); } function difference(a, b) { return a.filter((value) => !b.includes(value)); } //# sourceMappingURL=config.js.map