Created
April 24, 2024 06:54
-
-
Save niski84/2a09e09f7477113d0866cabd445f84b2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
go get github.com/aws/aws-sdk-go-v2 | |
go get github.com/aws/aws-sdk-go-v2/config | |
go get github.com/aws/aws-sdk-go-v2/service/ec2 | |
package main | |
import ( | |
"context" | |
"fmt" | |
"time" | |
"github.com/aws/aws-sdk-go-v2/aws" | |
"github.com/aws/aws-sdk-go-v2/config" | |
"github.com/aws/aws-sdk-go-v2/service/ec2" | |
"github.com/aws/aws-sdk-go-v2/service/ec2/types" | |
) | |
// ReportRow defines a row in the report. | |
type ReportRow map[string]string | |
// DescribeSnapshotVolumes retrieves and describes EC2 snapshots and their volumes. | |
func DescribeSnapshotVolumes(ctx context.Context) ([][]ReportRow, error) { | |
cfg, err := config.LoadDefaultConfig(ctx) | |
if err != nil { | |
return nil, fmt.Errorf("failed to load AWS SDK config: %w", err) | |
} | |
ec2Client := ec2.NewFromConfig(cfg) | |
paginator := ec2.NewDescribeSnapshotsPaginator(ec2Client, &ec2.DescribeSnapshotsInput{ | |
OwnerIds: []string{"self"}, | |
}) | |
var report [][]ReportRow | |
for paginator.HasMorePages() { | |
fmt.Println("Fetching snapshots page...") | |
out, err := paginator.NextPage(ctx) | |
if err != nil { | |
return nil, fmt.Errorf("failed to fetch snapshots page: %w", err) | |
} | |
for _, snapshot := range out.Snapshots { | |
fmt.Printf("Processing snapshot %s...\n", *snapshot.SnapshotId) | |
volDesc, err := ec2Client.DescribeVolumes(ctx, &ec2.DescribeVolumesInput{ | |
VolumeIds: []string{*snapshot.VolumeId}, | |
}) | |
if err != nil { | |
return nil, fmt.Errorf("failed to describe volume %s: %w", *snapshot.VolumeId, err) | |
} | |
for _, volume := range volDesc.Volumes { | |
if *volume.State == types.VolumeStateInUse { | |
fmt.Printf("Volume %s is in-use, describing attached instance...\n", *volume.VolumeId) | |
var instanceID string | |
for _, attachment := range volume.Attachments { | |
instanceID = *attachment.InstanceId | |
break | |
} | |
instanceDesc, err := ec2Client.DescribeInstances(ctx, &ec2.DescribeInstancesInput{ | |
InstanceIds: []string{instanceID}, | |
}) | |
if err != nil { | |
return nil, fmt.Errorf("failed to describe instance %s: %w", instanceID, err) | |
} | |
instance := instanceDesc.Reservations[0].Instances[0] | |
lastRun := "never" | |
if instance.State.Name == types.InstanceStateNameRunning { | |
lastRun = time.Now().Format("2006-01-02") | |
} else if instance.LaunchTime != nil { | |
lastRun = instance.LaunchTime.Format("2006-01-02") | |
} | |
row := ReportRow{ | |
"SnapshotID": *snapshot.SnapshotId, | |
"VolumeID": *volume.VolumeId, | |
"InstanceID": instanceID, | |
"EC2_LastRun": lastRun, | |
"Volume_Status": string(volume.State), | |
} | |
report = append(report, []ReportRow{row}) | |
} | |
} | |
} | |
} | |
fmt.Println("Final report generated.") | |
return report, nil | |
} | |
func main() { | |
ctx := context.Background() | |
report, err := DescribeSnapshotVolumes(ctx) | |
if err != nil { | |
fmt.Printf("Error: %s\n", err) | |
} else { | |
fmt.Println("Report:") | |
for i, site := range report { | |
fmt.Printf("Site %d:\n", i+1) | |
for _, row := range site { | |
for field, value := range row { | |
fmt.Printf("%s: %s\n", field, value) | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment