async function lifeCycle()

in src/consumer.js [321:446]


async function lifeCycle(snapshot_type) {
  console.log(`Performing Lifecycle Management for: ${snapshot_type}`);
  let rsp = {};
  let snapshots = {};
  let sources = {};
  let identity = await sts.getCallerIdentity({}).promise();

  const start = Date.now();

  // Collect all current snapshots and determine their age

  let params = { };

  do {
    switch (snapshot_type) {
      case 'RDS Cluster':
        params.SnapshotType = 'manual';
        rsp = await rds.describeDBClusterSnapshots(params).promise();
        snapshots = rsp.DBClusterSnapshots;
        break;
      case 'RDS':
        params.SnapshotType = 'manual';
        rsp = await rds.describeDBSnapshots(params).promise();
        snapshots = rsp.DBSnapshots;
        break;
      case 'EBS': // Request all the snapshots owned by the DR account with Draco_Lifecycle tags (no pagination)
        params.OwnerIds = [ identity.Account ];
        params.Filters = [ { Name: 'tag-key', Values: [ 'Draco_Lifecycle' ] } ];
        rsp = await ec2.describeSnapshots(params).promise();
        snapshots = rsp.Snapshots;
        break;
      default:
        throw "Invalid Snapshot Type: "+snapshot_type;
    }
    if ('Marker' in rsp) params.Marker = rsp.Marker;
    else delete params.Marker;

    for (const snapshot of snapshots) {
      if (snapshot_type.startsWith('RDS') && snapshot.Status != "available") continue;
      if (snapshot_type.startsWith('EBS') && snapshot.State != "completed") continue;

      let source_id, snapshot_id, snapshot_arn, snapshot_date;
      switch(snapshot_type) {
        case 'RDS Cluster':
          source_id = snapshot.DBClusterIdentifier;
          snapshot_id = snapshot.DBClusterSnapshotIdentifier;
          snapshot_arn = snapshot.DBClusterSnapshotArn;
          snapshot_date = new Date(snapshot.SnapshotCreateTime);
          break;
        case 'RDS':
          source_id = snapshot.DBInstanceIdentifier;
          snapshot_id = snapshot.DBSnapshotIdentifier;
          snapshot_arn = snapshot.DBSnapshotArn;
          snapshot_date = new Date(snapshot.SnapshotCreateTime);
          break;
        case 'EBS':
          source_id = snapshot.Description.match(/\bvol-[0-9a-f]+\b/i)[0];
          snapshot_id = snapshot.SnapshotId;
          snapshot_date = new Date(snapshot.StartTime);
          break;
      }
      if (!(source_id in sources)) {
        sources[source_id] = new Array();
      }
      sources[source_id].push ({
        age: (start - snapshot_date.valueOf()) / (24  * 3600 * 1000.0),
        id:   snapshot_id,
        arn:  snapshot_arn,
        date: snapshot.SnapshotCreateTime,
      });
    }
  }
  while ('Marker' in params);


  for (const source in sources) {
    const snapshots = sources[source].sort((a,b) => a.age - b.age); // youngest first
    // Get the Tags on the most recent Snapshot
    let youngest = snapshots[0];
    let taglist;
    switch (snapshot_type) {
      case 'RDS Cluster':
      case 'RDS':
        rsp = await rds.listTagsForResource({"ResourceName": youngest.arn}).promise();
        taglist = rsp.TagList;
        break;
      case 'EBS': {
        let p = {
          Filters: [ { Name: "resource-id", Values: [ youngest.id ] } ],
          MaxResults: 500
        }
        let rsp = await ec2.describeTags(p).promise();
        taglist = rsp.Tags.filter(t => !t.Key.startsWith('aws:')).map(e => ({ Key: e.Key, Value: e.Value } ))
        break;
      }
    }
    let tags = {};
    for (let tag of taglist) {
      tags[tag.Key] = tag.Value;
    }
    if (typeof tags.Draco_Lifecycle === 'undefined') {
      console.warn(`Source: ${source} has no Draco_Lifecycle tag. Skipped`);
      continue;
    }
    const lifecycle = tags["Draco_Lifecycle"];
    console.log(`Source: ${source} has lifecycle '${lifecycle}' with ${snapshots.length} snapshots. Youngest: ${JSON.stringify(youngest)}`);
    let dry_run = (typeof process.env.DRY_RUN !== 'undefined' && process.env.DRY_RUN != "false")
    let deletions = retention.implementPolicy(snapshots, lifecycle).filter(f => f.retain == false);
    for (const snap of deletions) {
      console.log(`${dry_run ? "Dry Run - Not ":""}Deleting: ${snap.id}`);
      if (!dry_run) {
          switch(snapshot_type) {
            case 'RDS Cluster':
              rsp = await rds.deleteDBClusterSnapshot({ DBClusterSnapshotIdentifier: snap.id }).promise();
              break;
            case 'RDS':
              rsp =await rds.deleteDBSnapshot({ DBSnapshotIdentifier: snap.id }).promise();
              break;
            case 'EBS':
              rsp =await ec2.deleteSnapshot({ SnapshotId: snap.id }).promise();
              break;
          }
      }
    }
  }
}