// findLatestSnap finds the source snapshot to copy func (c *config) findLatestSnap() error { cli := rds.New(session.New(), &aws.Config{Region: aws.String(c.src)}) c.debug(fmt.Sprintf("Searching for snapshots for: %s", c.dbid)) q := rds.DescribeDBSnapshotsInput{} q.DBInstanceIdentifier = aws.String(c.dbid) resp, err := cli.DescribeDBSnapshots(&q) if err != nil { return err } newest := time.Unix(0, 0) newestId := "" if len(resp.DBSnapshots) < 1 { return fmt.Errorf("No snapshots found") } c.debug(fmt.Sprintf("Found %d snapshots for: %s", len(resp.DBSnapshots), c.dbid)) for _, r := range resp.DBSnapshots { if r.SnapshotCreateTime.After(newest) { newestId = *r.DBSnapshotIdentifier newest = *r.SnapshotCreateTime } } if len(newestId) < 1 { return fmt.Errorf("No usable snapshot found") } c.arn = fmt.Sprintf("arn:aws:rds:%s:%s:snapshot:%s", c.src, c.awsAcctId, newestId) c.debug(fmt.Sprintf("Found latest snapshot: %s: %s", newestId, newest.String())) return nil }
// checkSnapCopied returns true if the source snapshot has already been copied to the destination region func (c *config) checkSnapCopied() bool { cli := rds.New(session.New(), &aws.Config{Region: aws.String(c.dst)}) q := rds.DescribeDBSnapshotsInput{} q.DBInstanceIdentifier = aws.String(c.dbid) resp, err := cli.DescribeDBSnapshots(&q) if err != nil { return false } for _, s := range resp.DBSnapshots { q := rds.ListTagsForResourceInput{ResourceName: aws.String(fmt.Sprintf("arn:aws:rds:%s:%s:snapshot:%s", c.dst, c.awsAcctId, *s.DBSnapshotIdentifier))} tags, err := cli.ListTagsForResource(&q) if err != nil { continue } managedByUs := false matchedSource := false for _, t := range tags.TagList { if *t.Key == "managedby" && *t.Value == "rdsbackup" { managedByUs = true } else if *t.Key == "sourcearn" && *t.Value == c.arn { matchedSource = true } } if managedByUs && matchedSource { return true } } return false }
// cleanupSnaps func (c *config) cleanupSnaps() error { if c.purge <= 0 { return nil } c.debug(fmt.Sprintf("Cleaning up old snapshots in dest region %s...", c.dst)) cli := rds.New(session.New(), &aws.Config{Region: aws.String(c.dst)}) q := rds.DescribeDBSnapshotsInput{} q.DBInstanceIdentifier = aws.String(c.dbid) resp, err := cli.DescribeDBSnapshots(&q) if err != nil { return err } snaps := map[int64]string{} keys := int64arr{} for _, s := range resp.DBSnapshots { q := rds.ListTagsForResourceInput{ResourceName: aws.String(fmt.Sprintf("arn:aws:rds:%s:%s:snapshot:%s", c.dst, c.awsAcctId, *s.DBSnapshotIdentifier))} tags, err := cli.ListTagsForResource(&q) if err != nil { continue } for _, t := range tags.TagList { if *t.Key == "managedby" && *t.Value == "rdsbackup" { if s.SnapshotCreateTime.Unix() > 0 { snaps[s.SnapshotCreateTime.Unix()] = *s.DBSnapshotIdentifier keys = append(keys, s.SnapshotCreateTime.Unix()) } } } } if len(snaps) <= c.purge { c.debug(fmt.Sprintf("Found %d snapshots. Purge flag is %d, so nothing will be purged.", len(snaps), c.purge)) } else { c.debug(fmt.Sprintf("Found %d snapshots. Purge flag is %d, so the oldest %d snapshots will be purged.", len(snaps), c.purge, len(snaps)-c.purge)) sort.Sort(keys) for i := 0; i < len(snaps)-c.purge; i++ { c.debug(fmt.Sprintf("Purging snapshot %s.", snaps[keys[i]])) q := rds.DeleteDBSnapshotInput{DBSnapshotIdentifier: aws.String(snaps[keys[i]])} resp, err := cli.DeleteDBSnapshot(&q) if err != nil { return err } if *resp.DBSnapshot.Status != "deleted" { c.debug(fmt.Sprintf("Warning: snapshot was not deleted successfully: %s", snaps[keys[i]])) } } c.debug("Done purging shapshots.") } return nil }