From 694f723dec00c21d3a036acd44f9365c3aab06f6 Mon Sep 17 00:00:00 2001 From: qbart Date: Fri, 27 Oct 2023 16:50:53 +0200 Subject: [PATCH] feat: Add EC2 ls --- awscmd/ec2.go | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++ main.go | 40 ++++++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 awscmd/ec2.go diff --git a/awscmd/ec2.go b/awscmd/ec2.go new file mode 100644 index 0000000..df0081c --- /dev/null +++ b/awscmd/ec2.go @@ -0,0 +1,95 @@ +package awscmd + +import ( + "context" + "io" + "time" + + "github.com/aws/aws-sdk-go/service/ec2" +) + +type InputEc2List struct { + Region string +} + +type OutputEc2List struct { + Region string + Instances []*ec2Instance +} + +type ec2Instance struct { + ID string + Name string + IPv4 string + IPv4private string + Type string + State string + AMI string + Zone string + LaunchTime time.Time +} + +func Ec2List(ctx context.Context, input *InputEc2List, w io.Writer) (*OutputEc2List, error) { + sess, err := NewSession(input.Region) + if err != nil { + return nil, err + } + svc := ec2.New(sess) + response, err := svc.DescribeInstancesWithContext(ctx, &ec2.DescribeInstancesInput{}) + if err != nil { + return nil, err + } + ec2s := []*ec2Instance{} + + for _, reservation := range response.Reservations { + for _, instance := range reservation.Instances { + name := "" + for _, tag := range instance.Tags { + if *tag.Key == "Name" { + name = *tag.Value + } + } + row := &ec2Instance{ + ID: toS(instance.InstanceId), + Name: name, + IPv4: toS(instance.PublicIpAddress), + IPv4private: toS(instance.PrivateIpAddress), + Type: toS(instance.InstanceType), + State: ec2InstanceStatus(*instance.State.Code), + AMI: toS(instance.ImageId), + Zone: toS(instance.Placement.AvailabilityZone), + LaunchTime: *instance.LaunchTime, + } + ec2s = append(ec2s, row) + } + } + + return &OutputEc2List{ + Region: input.Region, + Instances: ec2s, + }, nil +} + +func toS(s *string) string { + if s == nil { + return "" + } + return *s +} + +func ec2InstanceStatus(state int64) string { + switch state { + case 16: + return "running" + case 32: + return "shutting-down" + case 48: + return "terminated" + case 64: + return "stopping" + case 80: + return "stopped" + default: // 0 + return "pending" + } +} diff --git a/main.go b/main.go index e62c6df..891572c 100644 --- a/main.go +++ b/main.go @@ -374,6 +374,46 @@ func main() { return nil }, }, + { + Name: "ec2", + Usage: "EC2 instances", + Subcommands: []*cli.Command{ + { + Name: "ls", + Usage: "List all EC2 instances in region.", + Flags: []cli.Flag{ + &cli.StringFlag{Name: "region", Usage: "AWS region", Required: true}, + }, + Action: func(c *cli.Context) error { + input := &awscmd.InputEc2List{ + Region: c.String("region"), + } + out, err := awscmd.Ec2List(context.Background(), input, c.App.Writer) + if out != nil { + for _, instance := range out.Instances { + fmt.Fprintf( + c.App.Writer, + "%s %s %s %s %s%15s%s %s %s %s\n", + instance.ID, + instance.Name, + instance.State, + instance.IPv4private, + ctc.ForegroundGreen, instance.IPv4, ctc.Reset, + instance.Type, + instance.Zone, + instance.LaunchTime.Format("2006-01-02"), + ) + } + } + if err != nil { + return err + } + + return nil + }, + }, + }, + }, { Name: "ecs", Usage: "Elastic Container Service",