export async function saveNetworkOutputs()

in src/core/runtime/src/save-outputs-to-ssm/network-outputs.ts [55:275]


export async function saveNetworkOutputs(props: SaveOutputsInput) {
  const {
    acceleratorPrefix,
    account,
    config,
    dynamodb,
    outputsTableName,
    assumeRoleName,
    region,
    outputUtilsTableName,
  } = props;
  const oldNetworkOutputUtils = await getIndexOutput(
    outputUtilsTableName,
    `${account.key}-${region}-network`,
    dynamodb,
  );
  // Existing index check happens on this variable
  let networkOutputUtils: OutputUtilNetwork;
  if (oldNetworkOutputUtils) {
    networkOutputUtils = oldNetworkOutputUtils;
  } else {
    networkOutputUtils = {
      vpcs: [],
    };
  }

  // Storing new resource index and updating DDB in this variable
  const newNetworkOutputs: OutputUtilNetwork = {
    vpcs: [],
  };
  if (!newNetworkOutputs.vpcs) {
    newNetworkOutputs.vpcs = [];
  }

  // Removal from SSM Parameter store happens on left over in this variable
  const removalObjects: OutputUtilNetwork = {
    vpcs: [...(networkOutputUtils.vpcs || [])],
  };

  const vpcConfigs = config.getVpcConfigs();
  const localVpcConfigs = vpcConfigs.filter(
    vc => vc.accountKey === account.key && vc.vpcConfig.region === region && !vc.ouKey,
  );
  const localOuVpcConfigs = vpcConfigs.filter(
    vc => vc.accountKey === account.key && vc.vpcConfig.region === region && vc.ouKey,
  );
  const sharedVpcConfigs = vpcConfigs.filter(
    vc =>
      vc.accountKey !== account.key &&
      vc.vpcConfig.region === region &&
      vc.ouKey === account.ou &&
      (vc.vpcConfig.subnets?.find(sc => sc['share-to-ou-accounts']) ||
        vc.vpcConfig.subnets?.find(sc => sc['share-to-specific-accounts']?.includes(account.key))),
  );

  let localOutputs: StackOutput[] = [];
  if (localVpcConfigs.length > 0 || localOuVpcConfigs.length > 0) {
    localOutputs = await getOutput(outputsTableName, `${account.key}-${region}-1`, dynamodb);
  }
  if (!networkOutputUtils.vpcs) {
    networkOutputUtils.vpcs = [];
  }
  const lvpcIndices = networkOutputUtils.vpcs.filter(lv => lv.type === 'lvpc').flatMap(v => v.index) || [];
  let lvpcMaxIndex = lvpcIndices.length === 0 ? 0 : Math.max(...lvpcIndices);

  const sts = new STS();
  const credentials = await sts.getCredentialsForAccountAndRole(account.id, assumeRoleName);
  const ssm = new SSM(credentials, region);

  for (const resolvedVpcConfig of localVpcConfigs) {
    let currentIndex: number;
    const previousIndex = networkOutputUtils.vpcs.findIndex(
      vpc => vpc.type === 'lvpc' && vpc.name === resolvedVpcConfig.vpcConfig.name,
    );
    if (previousIndex >= 0) {
      currentIndex = networkOutputUtils.vpcs[previousIndex].index;
    } else {
      currentIndex = ++lvpcMaxIndex;
    }

    const vpcResult = await saveVpcOutputs({
      index: currentIndex,
      resolvedVpcConfig,
      outputs: localOutputs,
      ssm,
      acceleratorPrefix,
      vpcPrefix: 'lvpc',
      account,
      vpcUtil: previousIndex >= 0 ? networkOutputUtils.vpcs[previousIndex] : undefined,
    });
    if (vpcResult) {
      newNetworkOutputs.vpcs.push(vpcResult);
    }

    const removalIndex = removalObjects.vpcs?.findIndex(
      vpc => vpc.type === 'lvpc' && vpc.name === resolvedVpcConfig.vpcConfig.name,
    );

    if (removalIndex! >= 0) {
      removalObjects.vpcs?.splice(removalIndex!, 1);
    }
  }

  const vpcIndices = networkOutputUtils.vpcs.filter(vpc => vpc.type === 'vpc').flatMap(v => v.index) || [];
  let vpcMaxIndex = vpcIndices.length === 0 ? 0 : Math.max(...vpcIndices);
  for (const resolvedVpcConfig of localOuVpcConfigs) {
    let currentIndex: number;
    const previousIndex = networkOutputUtils.vpcs.findIndex(
      vpc => vpc.type === 'vpc' && vpc.name === resolvedVpcConfig.vpcConfig.name,
    );
    if (previousIndex >= 0) {
      currentIndex = networkOutputUtils.vpcs[previousIndex].index;
    } else {
      currentIndex = ++vpcMaxIndex;
    }
    const vpcResult = await saveVpcOutputs({
      index: currentIndex,
      resolvedVpcConfig,
      outputs: localOutputs,
      ssm,
      acceleratorPrefix,
      vpcPrefix: 'vpc',
      account,
      vpcUtil: previousIndex >= 0 ? networkOutputUtils.vpcs[previousIndex] : undefined,
    });

    if (vpcResult) {
      newNetworkOutputs.vpcs.push(vpcResult);
    }

    const removalIndex = removalObjects.vpcs?.findIndex(
      vpc => vpc.type === 'vpc' && vpc.name === resolvedVpcConfig.vpcConfig.name,
    );
    if (removalIndex! >= 0) {
      removalObjects.vpcs?.splice(removalIndex!, 1);
    }
  }
  if (sharedVpcConfigs.length > 0) {
    const sharedSgOutputs: StackOutput[] = await getOutput(outputsTableName, `${account.key}-${region}-2`, dynamodb);
    const sgOutputs: SecurityGroupsOutput[] = getStackJsonOutput(sharedSgOutputs, {
      accountKey: account.key,
      outputType: 'SecurityGroupsOutput',
    });

    for (const resolvedVpcConfig of sharedVpcConfigs) {
      let currentIndex: number;
      const previousIndex = networkOutputUtils.vpcs.findIndex(
        vpc => vpc.type === 'vpc' && vpc.name === resolvedVpcConfig.vpcConfig.name,
      );
      if (previousIndex >= 0) {
        currentIndex = networkOutputUtils.vpcs[previousIndex].index;
      } else {
        currentIndex = ++vpcMaxIndex;
      }
      const rootOutputs: StackOutput[] = await getOutput(
        outputsTableName,
        `${resolvedVpcConfig.accountKey}-${region}-1`,
        dynamodb,
      );
      const vpcSgOutputs = sgOutputs.find(sg => sg.vpcName);
      const vpcResult = await saveVpcOutputs({
        index: currentIndex,
        resolvedVpcConfig,
        outputs: rootOutputs,
        ssm,
        acceleratorPrefix,
        vpcPrefix: 'vpc',
        account,
        sgOutputs: vpcSgOutputs?.securityGroupIds,
        sharedVpc: true,
        vpcUtil: previousIndex >= 0 ? networkOutputUtils.vpcs[previousIndex] : undefined,
      });

      if (vpcResult) {
        newNetworkOutputs.vpcs.push(vpcResult);
      }

      const removalIndex = removalObjects.vpcs?.findIndex(
        vpc => vpc.type === 'vpc' && vpc.name === resolvedVpcConfig.vpcConfig.name,
      );
      if (removalIndex! >= 0) {
        removalObjects.vpcs?.splice(removalIndex!, 1);
      }
    }
  }

  await saveIndexOutput(
    outputUtilsTableName,
    `${account.key}-${region}-network`,
    JSON.stringify(newNetworkOutputs),
    dynamodb,
  );
  for (const removeObject of removalObjects.vpcs || []) {
    const removalSgs = removeObject.securityGroups
      .map(sg => [
        `/${acceleratorPrefix}/network/${removeObject.type}/${removeObject.index}/sg/${sg.index}/name`,
        `/${acceleratorPrefix}/network/${removeObject.type}/${removeObject.index}/sg/${sg.index}/id`,
      ])
      .flatMap(s => s);
    const removalSns = removeObject.subnets
      .map(sn =>
        sn.azs.map(snz => [
          `/${acceleratorPrefix}/network/${removeObject.type}/${removeObject.index}/net/${sn.index}/az${snz}/name`,
          `/${acceleratorPrefix}/network/${removeObject.type}/${removeObject.index}/net/${sn.index}/az${snz}/id`,
          `/${acceleratorPrefix}/network/${removeObject.type}/${removeObject.index}/net/${sn.index}/az${snz}/cidr`,
        ]),
      )
      .flatMap(azSn => azSn)
      .flatMap(sn => sn);
    const removalVpc = [
      `/${acceleratorPrefix}/network/${removeObject.type}/${removeObject.index}/name`,
      `/${acceleratorPrefix}/network/${removeObject.type}/${removeObject.index}/id`,
      `/${acceleratorPrefix}/network/${removeObject.type}/${removeObject.index}/cidr`,
      `/${acceleratorPrefix}/network/${removeObject.type}/${removeObject.index}/cidr2`,
    ];
    const removeNames = [...removalSgs, ...removalSns, ...removalVpc];
    while (removeNames.length > 0) {
      await ssm.deleteParameters(removeNames.splice(0, 10));
    }
  }
}