in addons/addon-base-raas/packages/base-raas-services/lib/environment/service-catalog/environment-config-vars-service.js [166:313]
async resolveEnvConfigVars(requestContext, { envId, envTypeId, envTypeConfigId }) {
const [
userService,
environmentScService,
environmentScKeypairService,
indexesService,
awsAccountsService,
environmentAmiService,
envTypeConfigService,
] = await this.service([
'userService',
'environmentScService',
'environmentScKeypairService',
'indexesService',
'awsAccountsService',
'environmentAmiService',
'envTypeConfigService',
]);
const environment = await environmentScService.mustFind(requestContext, { id: envId });
const { name, description, projectId, indexId, cidr, studyIds } = environment;
// // Get the aws account information
const { awsAccountId } = await indexesService.mustFind(requestContext, { id: indexId });
const {
xAccEnvMgmtRoleArn,
externalId,
accountId,
vpcId,
subnetId,
encryptionKeyArn,
} = await awsAccountsService.mustFind(requestContext, { id: awsAccountId });
// Check launch pre-requisites
if (!(xAccEnvMgmtRoleArn && externalId && accountId && vpcId && subnetId && encryptionKeyArn)) {
const cause = this.getConfigError(xAccEnvMgmtRoleArn, externalId, accountId, vpcId, subnetId, encryptionKeyArn);
throw this.boom.badRequest(`Index "${indexId}" has not been correctly configured: missing ${cause}.`, true);
}
// Get the environment type configuration and read params to find if any of the params
// require AMI ids (i.e., all param values that match ami naming pattern )
const envTypeConfig = await envTypeConfigService.mustFind(requestContext, envTypeId, { id: envTypeConfigId });
const amiRelatedParams = _.filter(
envTypeConfig.params,
// AMI IDs have values similar to "ami-abcd1234" or "ami-aabbccddee1234567"
p => _.startsWith(p.value, 'ami-'),
);
// TODO: Move this later in the workflow after all param expressions
// have been resolved
const amisToShare = _.map(amiRelatedParams, p => p.value);
if (!_.isEmpty(amisToShare)) {
// Share AMIs with the target account (process in batches of 5 at a time)
// if there are more than 5
await processInBatches(amisToShare, 5, async imageId => {
return environmentAmiService.ensurePermissions({ imageId, accountId });
});
}
const studies = await environmentScService.getStudies(requestContext, environment);
const iamPolicyDocument = await this.getEnvRolePolicy(requestContext, {
environment,
studies,
accountId,
});
const s3Mounts = await this.getS3Mounts(requestContext, {
environment,
studies,
accountId,
});
let egressStoreIamPolicyDocument = {};
const enableEgressStore = this.settings.getBoolean(settingKeys.enableEgressStore);
if (enableEgressStore) {
const egressStoreMount = await this.getEgressStoreMount(requestContext, environment);
s3Mounts.push(egressStoreMount);
egressStoreIamPolicyDocument = await this.getEnvEgressStorePolicy(requestContext, {
environmentId: envId,
});
}
// TODO: If the ami sharing gets moved (because it doesn't contribute to an env var)
// then move the update local resource policies too.
// Using the account root provides basically the same level of security because in either
// case we have to trust that the member account hasn't altered the role's assume role policy to allow other
// principals assume it
// if (s3Prefixes.length > 0) {
// await environmentMountService.addRoleArnToLocalResourcePolicies(`arn:aws:iam::${accountId}:root`, s3Prefixes);
// }
// Check if the environment being launched needs an admin key-pair to be created in the target account
// If the configuration being used has any parameter that uses the "adminKeyPairName" variable then it means
// we need to provision that key in the target account and provide the name of the generated key as the
// "adminKeyPairName" variable
// Disabling "no-template-curly-in-string" lint rule because we need to compare with the string literal "${adminKeyPairName}"
// i.e., without any string interpolation
// eslint-disable-next-line no-template-curly-in-string
const isAdminKeyPairRequired = !!_.find(envTypeConfig.params, p => p.value === '${adminKeyPairName}');
let adminKeyPairName = '';
if (isAdminKeyPairRequired) {
adminKeyPairName = await environmentScKeypairService.create(requestContext, envId);
}
const by = _.get(requestContext, 'principalIdentifier.uid');
const user = await userService.mustFindUser({ uid: by });
// This value is a string
const isAppStreamEnabled = this.settings.get(settingKeys.isAppStreamEnabled);
const result = {
envId,
envTypeId,
envTypeConfigId,
name,
description,
accountId,
projectId,
indexId,
studyIds,
cidr,
vpcId,
subnetId,
encryptionKeyArn,
xAccEnvMgmtRoleArn,
externalId,
s3Mounts: JSON.stringify(s3Mounts),
iamPolicyDocument: JSON.stringify(iamPolicyDocument),
environmentInstanceFiles: this.settings.get(settingKeys.environmentInstanceFiles),
isAppStreamEnabled,
solutionNamespace:
isAppStreamEnabled === 'true' ? await this.getSolutionNamespace(requestContext, awsAccountId) : '',
// s3Prefixes // This variable is no longer relevant it is being removed, the assumption is that
// this variable has not been used in any of the product templates.
uid: user.uid,
username: user.username,
userNamespace: user.ns,
adminKeyPairName,
};
result.egressStoreIamPolicyDocument = JSON.stringify(egressStoreIamPolicyDocument);
return result;
}