Skip to content

Instantly share code, notes, and snippets.

@rochacon
Created August 11, 2022 04:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rochacon/6d352bf25d3913715836cfeed94b454e to your computer and use it in GitHub Desktop.
Save rochacon/6d352bf25d3913715836cfeed94b454e to your computer and use it in GitHub Desktop.
package main
import (
"flag"
"fmt"
"log"
"os"
"sort"
"strings"
"text/tabwriter"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
)
// Maximum column length
const MAX_COLUMN_LENGTH = 32
func main() {
app := flag.String("a", "", "Filter by tag:App")
env := flag.String("e", "", "Filter by tag:Env")
id := flag.String("i", "", "Filter by instance ID")
process := flag.String("p", "", "Filter by tag:Process")
product := flag.String("P", "", "Filter by tag:Product")
region := flag.String("r", os.Getenv("AWS_DEFAULT_REGION"), "AWS Region")
state := flag.String("s", "", "Filter by instance state")
flag.Parse()
awsSession := session.Must(session.NewSession(&aws.Config{
Region: region,
}))
ec2Svc := ec2.New(awsSession)
input := &ec2.DescribeInstancesInput{}
filters := []*ec2.Filter{}
if *app != "" {
filters = append(filters, &ec2.Filter{Name: aws.String("tag:App"), Values: []*string{app}})
}
if *env != "" {
filters = append(filters, &ec2.Filter{Name: aws.String("tag:Env"), Values: []*string{env}})
}
if *id != "" {
input.InstanceIds = []*string{id}
}
if *process != "" {
filters = append(filters, &ec2.Filter{Name: aws.String("tag:Process"), Values: []*string{process}})
}
if *product != "" {
filters = append(filters, &ec2.Filter{Name: aws.String("tag:Product"), Values: []*string{product}})
}
if *state != "" {
filters = append(filters, &ec2.Filter{Name: aws.String("instance-state-name"), Values: []*string{state}})
}
if len(filters) > 0 {
input.Filters = filters
}
result, err := ec2Svc.DescribeInstances(input)
if err != nil {
log.Fatal(err)
}
w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', tabwriter.DiscardEmptyColumns)
fmt.Fprintf(w, "ID\tNAME\tSTATE\tZONE\tPRIVATE_IP\tPUBLIC_IP\tTYPE\tLIFECYCLE\tAGE\n")
instances := []*ec2.Instance{}
for _, reservation := range result.Reservations {
for _, instance := range reservation.Instances {
instances = append(instances, instance)
}
}
sort.Sort(sortInstances(instances))
for _, instance := range instances {
fmt.Fprintf(w,
"%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
valueOrDash(instance.InstanceId),
getTagValue("Name", instance.Tags),
valueOrDash(instance.State.Name),
valueOrDash(instance.Placement.AvailabilityZone),
valueOrDash(instance.PrivateIpAddress),
valueOrDash(instance.PublicIpAddress),
valueOrDash(instance.InstanceType),
fmt.Sprintf("%s (%s)", valueOrDash(instance.InstanceLifecycle), valueOrDash(instance.SpotInstanceRequestId)),
time.Since(*instance.LaunchTime),
)
}
w.Flush()
}
func getTagValue(key string, tags []*ec2.Tag) string {
for _, tag := range tags {
if *tag.Key == key {
v := valueOrDash(tag.Value)
if len(v) > MAX_COLUMN_LENGTH {
return v[:MAX_COLUMN_LENGTH]
}
return v
}
}
return "-"
}
func valueOrDash(s *string) string {
if s == nil {
return "-"
}
return *s
}
type sortInstances []*ec2.Instance
func (s sortInstances) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s sortInstances) Len() int { return len(s) }
func (s sortInstances) Less(i, j int) bool {
name1 := getTagValue("Name", s[i].Tags)
name2 := getTagValue("Name", s[j].Tags)
return strings.Compare(name1, name2) == -1
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment