async resolveEnvConfigVars()

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;
  }