1// +build example
2
3package main
4
5import (
6	"flag"
7	"fmt"
8	"os"
9	"strings"
10
11	"github.com/aws/aws-sdk-go/aws"
12	"github.com/aws/aws-sdk-go/aws/session"
13	"github.com/aws/aws-sdk-go/service/ec2"
14)
15
16// Prints a list of instances for each region. If no regions are provided
17// all regions will be searched. The state is required.
18//
19// Will use the AWS SDK for Go's default credential chain and region. You can
20// specify the region with the AWS_REGION environment variable.
21//
22// Usage: instancesByRegion -state <value> [-state val...] [-region region...]
23func main() {
24	states, regions := parseArguments()
25
26	if len(states) == 0 {
27		fmt.Fprintf(os.Stderr, "error: %v\n", usage())
28		os.Exit(1)
29	}
30	instanceCriteria := " "
31	for _, state := range states {
32		instanceCriteria += "[" + state + "]"
33	}
34
35	if len(regions) == 0 {
36		var err error
37		regions, err = fetchRegion()
38		if err != nil {
39			fmt.Fprintf(os.Stderr, "error: %v\n", err)
40			os.Exit(1)
41		}
42	}
43
44	for _, region := range regions {
45		sess := session.Must(session.NewSession(&aws.Config{
46			Region: aws.String(region),
47		}))
48
49		ec2Svc := ec2.New(sess)
50		params := &ec2.DescribeInstancesInput{
51			Filters: []*ec2.Filter{
52				{
53					Name:   aws.String("instance-state-name"),
54					Values: aws.StringSlice(states),
55				},
56			},
57		}
58
59		result, err := ec2Svc.DescribeInstances(params)
60		if err != nil {
61			fmt.Println("Error", err)
62		} else {
63			fmt.Printf("\n\n\nFetching instance details for region: %s with criteria: %s**\n ", region, instanceCriteria)
64			if len(result.Reservations) == 0 {
65				fmt.Printf("There is no instance for the region: %s with the matching criteria:%s  \n", region, instanceCriteria)
66			}
67			for _, reservation := range result.Reservations {
68
69				fmt.Println("printing instance details.....")
70				for _, instance := range reservation.Instances {
71					fmt.Println("instance id " + *instance.InstanceId)
72					fmt.Println("current State " + *instance.State.Name)
73				}
74			}
75			fmt.Printf("done for region %s **** \n", region)
76		}
77	}
78}
79
80func fetchRegion() ([]string, error) {
81	awsSession := session.Must(session.NewSession(&aws.Config{}))
82
83	svc := ec2.New(awsSession)
84	awsRegions, err := svc.DescribeRegions(&ec2.DescribeRegionsInput{})
85	if err != nil {
86		return nil, err
87	}
88
89	regions := make([]string, 0, len(awsRegions.Regions))
90	for _, region := range awsRegions.Regions {
91		regions = append(regions, *region.RegionName)
92	}
93
94	return regions, nil
95}
96
97type flagArgs []string
98
99func (a flagArgs) String() string {
100	return strings.Join(a.Args(), ",")
101}
102
103func (a *flagArgs) Set(value string) error {
104	*a = append(*a, value)
105	return nil
106}
107func (a flagArgs) Args() []string {
108	return []string(a)
109}
110
111func parseArguments() (states []string, regions []string) {
112	var stateArgs, regionArgs flagArgs
113
114	flag.Var(&stateArgs, "state", "state list")
115	flag.Var(&regionArgs, "region", "region list")
116	flag.Parse()
117
118	if flag.NFlag() != 0 {
119		states = append([]string{}, stateArgs.Args()...)
120		regions = append([]string{}, regionArgs.Args()...)
121	}
122
123	return states, regions
124}
125
126func usage() string {
127	return `
128
129Missing mandatory flag 'state'. Please use like below  Example:
130
131To fetch the stopped instance of all region use below:
132	./filter_ec2_by_region -state running -state stopped
133
134To fetch the stopped and running instance  for  region us-west-1 and eu-west-1 use below:
135	./filter_ec2_by_region -state running -state stopped -region us-west-1 -region=eu-west-1
136`
137}
138