-
Notifications
You must be signed in to change notification settings - Fork 19
/
describeInstances.py
141 lines (121 loc) · 5.37 KB
/
describeInstances.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/bin/env python3
# Original Author @elitest
# This script is part of Redboto
# https://github.com/elitest/Redboto
# This script uses boto3 and texttable to print
# information about EC2 instances
# Wishlist:
# Add information such as networking, tags, etc.
# Add control over which attributes are printed
# Add the ability to specify profile and region
import boto3, json, argparse, botocore.exceptions, sys
from texttable import Texttable
# Sets up the argument parser
argparser = argparse.ArgumentParser(description='Describe instances in EC2 in a table')
argparser.add_argument('--profile', default='default', help='The profile name in ~/.aws/credentials')
argparser.add_argument('--region', help='The region you want to describe instances of. If not used, then all are listed.')
argparser.add_argument('--network', action='store_true', help='Includes IP addresses in the output.')
argparser.add_argument('--volume', action='store_true', help='Include volume information in the output.')
args = argparser.parse_args()
if args.profile:
boto3.setup_default_session(profile_name=args.profile)
# This function pulls the information out of the EC2 instance and builds the table
def generate_table(region):
ec2 = boto3.client(service_name='ec2', region_name=region)
response = ec2.describe_instances()
# Initialize the table unlimited width
table = Texttable(max_width=0)
# This is basically a builder for the width of the array used to build the table.
tableWidth = 3
if args.network:
tableWidth +=2
if args.volume:
tableWidth +=2
table.set_cols_align(tableWidth*["c"])
table.set_cols_valign(tableWidth*["m"])
# This is a builder for the names of the head of the table
headerList = ["Instance ID", "Name", "State"]
if args.volume:
headerList += ["VolumeId","DeviceName"]
if args.network:
headerList += ["Private IPs", "Public IPs"]
table.header(headerList)
# If we get reservations iterate through them
if response['Reservations']:
for r in response['Reservations']:
for i in r['Instances']:
instanceid = i['InstanceId']
# We actually need some information not accessible by the client
ec2Resource = boto3.resource('ec2', region)
Instance = ec2Resource.Instance(i['InstanceId'])
# Name of the instance otherwise blank
if Instance.tags:
for tag in Instance.tags:
if tag['Key'] == 'Name':
name = tag['Value']
# There may be another condition here
else:
name = ''
# State of the instance
state = i['State']['Name']
# This is the builder for the add_row function
rowList = [instanceid, name, state]
if args.volume:
vs = ''
dn = ''
# Pull the device names
for d in i['BlockDeviceMappings']:
vs = vs + d['Ebs']['VolumeId'] + '\n'
dn = dn + d['DeviceName'] + '\n'
rowList += [vs,dn]
if args.network:
# This pulls the IP addresses
# There are instances which may not have IPs
try:
public = i['PublicIpAddress']
except KeyError:
public = ''
try:
private = i['PrivateIpAddress']
except KeyError:
private = ''
rowList += [public,private]
# This adds the row
table.add_row(rowList)
# This draws the table
print(table.draw() + "\n")
else:
print(' No instances found in this region\n')
# This is if a region is specified in args
if args.region is not None:
regions = {}
regions = [{'RegionName': '%s' % args.region}]
else:
#connection stricly to get regions
client = boto3.client(service_name='ec2', region_name='us-east-1')
regions = client.describe_regions()['Regions']
#Iterate through the regions
#for region in regions:
for region in regions:
print("checking region: "+region['RegionName'] + "\n")
try:
generate_table(region['RegionName'])
except botocore.exceptions.ClientError as error:
if error.response['Error']['Code'] == 'UnauthorizedOperation':
print('Are you sure you have the right permissions? Check IAM.')
elif error.response['Error']['Code'] == 'AuthFailure':
print('Your keys may be invalid. Perhaps they have been rotated?')
#Something else happened here print the error code for inclusion above
else:
print(error.response['Error']['Code'])
except botocore.exceptions.EndpointConnectionError as error:
# Attempted to reach out to an invalid S3 endpoint
print('Invalid region. Check that you have specified a region that exists')
except TypeError as error:
# This is the case where no instances were found.
# Too broad of an excaption perhaps?
print('exception is' +error)
pass
except:
# catch all exception
print("I'm not sure what happened here. Something else went wrong.",sys.exc_info())