sport_ngin_aws_auditor 3.11.3 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/CHANGELOG.markdown +0 -122
- data/bin/sport-ngin-aws-auditor +8 -0
- data/lib/sport_ngin_aws_auditor/audit_data.rb +24 -23
- data/lib/sport_ngin_aws_auditor/aws.rb +32 -19
- data/lib/sport_ngin_aws_auditor/cache_instance.rb +9 -9
- data/lib/sport_ngin_aws_auditor/convenience_wrappers.rb +56 -21
- data/lib/sport_ngin_aws_auditor/ec2_instance.rb +11 -11
- data/lib/sport_ngin_aws_auditor/instance_helper.rb +10 -10
- data/lib/sport_ngin_aws_auditor/rds_instance.rb +9 -9
- data/lib/sport_ngin_aws_auditor/scripts/audit.rb +207 -168
- data/lib/sport_ngin_aws_auditor/scripts/inspect.rb +20 -7
- data/lib/sport_ngin_aws_auditor/version.rb +1 -1
- data/spec/sport_ngin_aws_auditor/audit_data_spec.rb +40 -25
- data/spec/sport_ngin_aws_auditor/aws_spec.rb +26 -4
- data/spec/sport_ngin_aws_auditor/cache_instance_spec.rb +15 -18
- data/spec/sport_ngin_aws_auditor/ec2_instance_spec.rb +24 -29
- data/spec/sport_ngin_aws_auditor/rds_instance_spec.rb +16 -21
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 426f863fd847de5399249f6e81575fcdef99ae29
|
4
|
+
data.tar.gz: 8ad69c1ef79d4e0b3b92c59264655c28b719c001
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 52a07a51a83b4229dc3df8ce7bac6685f0b19b369ea01f100a637ae35876c06e2b4a1044a69f4d15bf7913c6114519db72144a420790bf8efa32a396cdb5a81b
|
7
|
+
data.tar.gz: bb2bbf9806d201085f611f18c6cff3439b71dcb32a6397d2bb8a059a6fca3925442b2aa522d0f1f5f74b81b3f96ee36e93207ee233648c33e70cb6a53160fa0a
|
data/.travis.yml
CHANGED
data/CHANGELOG.markdown
CHANGED
@@ -1,122 +0,0 @@
|
|
1
|
-
#### v3.11.3
|
2
|
-
* Missed this bug because I did not test previous bug's fix in Slack
|
3
|
-
|
4
|
-
> Emma Sax: Unknown User: https://github.com/sportngin/sport_ngin_aws_auditor/pull/30
|
5
|
-
|
6
|
-
#### v3.11.2
|
7
|
-
* We actually do not want to cache the counts of instances and reserved instances between multiple runs
|
8
|
-
|
9
|
-
> Emma Sax: Unknown User: https://github.com/sportngin/sport_ngin_aws_auditor/pull/29
|
10
|
-
|
11
|
-
#### v3.11.1
|
12
|
-
* Must merge this PR in to run the audit command correctly
|
13
|
-
|
14
|
-
> Emma Sax: Unknown User: https://github.com/sportngin/sport_ngin_aws_auditor/pull/28
|
15
|
-
|
16
|
-
#### v3.11.0
|
17
|
-
* Automatically ignore instances based on a regex string
|
18
|
-
|
19
|
-
> Emma Sax: Unknown User: https://github.com/sportngin/sport_ngin_aws_auditor/pull/26
|
20
|
-
|
21
|
-
#### v3.10.1
|
22
|
-
* Caching should not affect RI counts between runs
|
23
|
-
|
24
|
-
> Emma Sax: Andy Fleener, Unknown User: https://github.com/sportngin/sport_ngin_aws_auditor/pull/25
|
25
|
-
|
26
|
-
#### v3.10.0
|
27
|
-
* Handling region-based RIs
|
28
|
-
|
29
|
-
> Emma Sax: Andy Fleener, Luke Ludwig, Tim Sandquist, Unknown User: https://github.com/sportngin/sport_ngin_aws_auditor/pull/21
|
30
|
-
|
31
|
-
#### v3.9.0
|
32
|
-
* Add the ability to pass config data in as a flag
|
33
|
-
|
34
|
-
> Emma Sax: Andy Fleener, Unknown User: https://github.com/sportngin/sport_ngin_aws_auditor/pull/24
|
35
|
-
|
36
|
-
#### v3.8.3
|
37
|
-
* Fixing bugs with outputs and counts
|
38
|
-
|
39
|
-
> Emma Sax: Tim Sandquist, Unknown User: https://github.com/sportngin/sport_ngin_aws_auditor/pull/23
|
40
|
-
|
41
|
-
#### v3.8.2
|
42
|
-
* Fixing bugs so that counts are accurate again
|
43
|
-
|
44
|
-
> Emma Sax: : https://github.com/sportngin/sport_ngin_aws_auditor/pull/20
|
45
|
-
|
46
|
-
#### v3.8.1
|
47
|
-
#### v3.8.0
|
48
|
-
* Clarifying printout of audit command
|
49
|
-
|
50
|
-
> Emma Sax: : https://github.com/sportngin/sport_ngin_aws_auditor/pull/18
|
51
|
-
|
52
|
-
#### v3.7.0
|
53
|
-
* Print retired tags into slack/terminal on audit
|
54
|
-
|
55
|
-
> Emma Sax: Brian Bergstrom: https://github.com/sportngin/sport_ngin_aws_auditor/pull/17
|
56
|
-
|
57
|
-
#### v3.6.0
|
58
|
-
* Print reserved instances that have retired in past week
|
59
|
-
|
60
|
-
> Emma Sax: Andy Fleener: https://github.com/sportngin/sport_ngin_aws_auditor/pull/16
|
61
|
-
|
62
|
-
#### v3.5.0
|
63
|
-
* Cleaning up slack printouts with the audit command
|
64
|
-
|
65
|
-
> Emma Sax: Brian Bergstrom: https://github.com/sportngin/sport_ngin_aws_auditor/pull/15
|
66
|
-
|
67
|
-
#### v3.4.1
|
68
|
-
#### v3.4.0
|
69
|
-
* Add other RDS engine types
|
70
|
-
|
71
|
-
> matl33t: Emma Sax, Brian Bergstrom: https://github.com/sportngin/sport_ngin_aws_auditor/pull/11
|
72
|
-
|
73
|
-
#### v3.3.1
|
74
|
-
* Fixing bug where Slack will print discrepancies if there are *only* tagged instances
|
75
|
-
|
76
|
-
> Emma Sax: : https://github.com/sportngin/sport_ngin_aws_auditor/pull/13
|
77
|
-
|
78
|
-
#### v3.3.0
|
79
|
-
* Slack should print instances that have tags
|
80
|
-
|
81
|
-
> Emma Sax: Andy Fleener: https://github.com/sportngin/sport_ngin_aws_auditor/pull/12
|
82
|
-
|
83
|
-
#### v3.2.0
|
84
|
-
* Proper recognition of windows/linux/vpc instances
|
85
|
-
|
86
|
-
> Emma Sax: Andy Fleener: https://github.com/sportngin/sport_ngin_aws_auditor/pull/8
|
87
|
-
|
88
|
-
#### v3.1.2
|
89
|
-
#### v3.1.0
|
90
|
-
* Authentication with AWS roles instead of credentials file
|
91
|
-
|
92
|
-
> Emma Sax: Brian Bergstrom: https://github.com/sportngin/sport_ngin_aws_auditor/pull/7
|
93
|
-
|
94
|
-
#### v3.0.2
|
95
|
-
#### v3.0.1
|
96
|
-
#### v3.0.0
|
97
|
-
* Rename gem directories and modules
|
98
|
-
|
99
|
-
> Emma Sax: Brian Bergstrom: https://github.com/sportngin/sport_ngin_aws_auditor/pull/6
|
100
|
-
|
101
|
-
#### v2.1.0
|
102
|
-
* Adding option to print audit results to Slack channel
|
103
|
-
|
104
|
-
> Emma Sax, Matt Krieger: Brian Bergstrom: https://github.com/sportngin/aws_auditor/pull/4
|
105
|
-
|
106
|
-
* Adding option to print audit results to Slack channel
|
107
|
-
|
108
|
-
> Emma Sax, Matt Krieger: Brian Bergstrom: https://github.com/sportngin/aws_auditor/pull/4
|
109
|
-
|
110
|
-
#### v2.0.0
|
111
|
-
* Adding enhancements for taking no-reserved-instance tag into consideration during audit
|
112
|
-
|
113
|
-
> Emma Sax: Brian Bergstrom: https://github.com/sportngin/aws_auditor/pull/2
|
114
|
-
|
115
|
-
#### v1.0.0
|
116
|
-
* Upgrading aws-sdk version from v1 to v2
|
117
|
-
|
118
|
-
> Emma Sax: Brian Bergstrom: https://github.com/sportngin/aws_auditor/pull/3
|
119
|
-
|
120
|
-
* First tests, Travis CI, MFA support, and fog file compatibility
|
121
|
-
|
122
|
-
> Brian Bergstrom: Emma Sax: https://github.com/sportngin/aws_auditor/pull/1
|
data/bin/sport-ngin-aws-auditor
CHANGED
@@ -11,7 +11,15 @@ version SportNginAwsAuditor::VERSION
|
|
11
11
|
wrap_help_text :verbatim
|
12
12
|
|
13
13
|
flag [:config], :desc => 'SportNginAwsAuditor config file path', :default_value => SportNginAwsAuditor::DefaultPaths.config
|
14
|
+
flag [:display], :desc => 'The name that should be printed in the output'
|
14
15
|
switch [:aws_roles], :desc => 'Use AWS roles instead of an ~/.aws/credentials file'
|
16
|
+
switch [:assume_roles], :desc => 'Assume roles to audit cross accounts; should have roles/policies already set up'
|
17
|
+
flag [:role_name], :desc => 'The name of the role that is giving cross account access', :default_value => 'CrossAccountAuditorAccess'
|
18
|
+
flag [:arn_id], :desc => 'The identifying digits of the AWS arn if using assume_roles;
|
19
|
+
should be the numerical part of the example:
|
20
|
+
arn:aws:iam::999999999999:role/#{role_name}'
|
21
|
+
flag [:region], :desc => 'The region(s) the audit should occur in; if no region is specified, then the auditor will be run in every
|
22
|
+
U.S. region. To run multiple regions, the input should be a string like: us-east-1, us-east-2'
|
15
23
|
|
16
24
|
program_long_desc """
|
17
25
|
DOCUMENTATION
|
@@ -1,14 +1,27 @@
|
|
1
1
|
require_relative './instance_helper'
|
2
|
+
require_relative './convenience_wrappers'
|
2
3
|
|
3
4
|
module SportNginAwsAuditor
|
4
5
|
class AuditData
|
6
|
+
extend EC2Wrapper
|
7
|
+
extend RDSWrapper
|
8
|
+
extend CacheWrapper
|
5
9
|
|
6
|
-
attr_accessor :data, :retired_tags, :retired_ris, :selected_audit_type, :klass, :tag_name, :region, :ignore_instances_regexes
|
7
|
-
def initialize(
|
8
|
-
self.selected_audit_type = (!instances && !reserved) ? "all" : (instances ? "instances" : "reserved")
|
9
|
-
self.klass = SportNginAwsAuditor.const_get(
|
10
|
-
self.tag_name = tag_name
|
11
|
-
self.ignore_instances_regexes =
|
10
|
+
attr_accessor :data, :retired_tags, :retired_ris, :selected_audit_type, :klass, :tag_name, :region, :ignore_instances_regexes, :client
|
11
|
+
def initialize(info)
|
12
|
+
self.selected_audit_type = (!info[:instances] && !info[:reserved]) ? "all" : (info[:instances] ? "instances" : "reserved")
|
13
|
+
self.klass = SportNginAwsAuditor.const_get(info[:class])
|
14
|
+
self.tag_name = info[:tag_name]
|
15
|
+
self.ignore_instances_regexes = info[:regexes]
|
16
|
+
self.region = info[:region].match(/(\w{2}-\w{4,})/)[0] if info[:region].match(/(\w{2}-\w{4,})/)
|
17
|
+
|
18
|
+
if info[:class] == "EC2Instance"
|
19
|
+
self.client = EC2Wrapper.ec2(info[:region])
|
20
|
+
elsif info[:class] == "RDSInstance"
|
21
|
+
self.client = RDSWrapper.rds(info[:region])
|
22
|
+
elsif info[:class] == "CacheInstance"
|
23
|
+
self.client = CacheWrapper.cache(info[:region])
|
24
|
+
end
|
12
25
|
end
|
13
26
|
|
14
27
|
def instances?
|
@@ -28,7 +41,7 @@ module SportNginAwsAuditor
|
|
28
41
|
instance_hash, retired_tags = gather_instances_data
|
29
42
|
retired_ris = nil
|
30
43
|
elsif reserved?
|
31
|
-
instance_hash = self.klass.instance_count_hash(self.klass.get_reserved_instances)
|
44
|
+
instance_hash = self.klass.instance_count_hash(self.klass.get_reserved_instances(self.client))
|
32
45
|
retired_tags, retired_ris = nil
|
33
46
|
elsif all?
|
34
47
|
instance_hash, retired_tags, retired_ris = gather_all_data
|
@@ -45,8 +58,7 @@ module SportNginAwsAuditor
|
|
45
58
|
end
|
46
59
|
|
47
60
|
def gather_instances_data
|
48
|
-
instances = self.klass.get_instances(tag_name)
|
49
|
-
gather_region(instances)
|
61
|
+
instances = self.klass.get_instances(self.client, tag_name)
|
50
62
|
retired_tags = self.klass.get_retired_tags(instances)
|
51
63
|
instances_with_tag = self.klass.filter_instances_with_tags(instances)
|
52
64
|
instances_without_tag = self.klass.filter_instances_without_tags(instances)
|
@@ -57,23 +69,12 @@ module SportNginAwsAuditor
|
|
57
69
|
end
|
58
70
|
|
59
71
|
def gather_all_data
|
60
|
-
instances = self.klass.get_instances(tag_name)
|
61
|
-
gather_region(instances)
|
72
|
+
instances = self.klass.get_instances(self.client, tag_name)
|
62
73
|
retired_tags = self.klass.get_retired_tags(instances)
|
63
|
-
instance_hash = self.klass.compare(instances, ignore_instances_regexes)
|
64
|
-
retired_ris = self.klass.get_recent_retired_reserved_instances
|
74
|
+
instance_hash = self.klass.compare(instances, ignore_instances_regexes, self.client)
|
75
|
+
retired_ris = self.klass.get_recent_retired_reserved_instances(self.client)
|
65
76
|
|
66
77
|
return instance_hash, retired_tags, retired_ris
|
67
78
|
end
|
68
|
-
|
69
|
-
def gather_region(instances)
|
70
|
-
if self.klass == SportNginAwsAuditor::EC2Instance
|
71
|
-
# if instances.first.availability_zone = 'us-east-1a'...
|
72
|
-
match = instances.first.availability_zone.match(/(\w{2}-\w{4,})/)
|
73
|
-
|
74
|
-
# then region = 'us-east'
|
75
|
-
self.region = match[0] unless match.nil?
|
76
|
-
end
|
77
|
-
end
|
78
79
|
end
|
79
80
|
end
|
@@ -8,29 +8,42 @@ module SportNginAwsAuditor
|
|
8
8
|
end
|
9
9
|
|
10
10
|
class AWSSDK
|
11
|
-
def self.
|
11
|
+
def self.authenticate_with_iam(environment)
|
12
12
|
shared_credentials = Aws::SharedCredentials.new(profile_name: environment)
|
13
|
-
|
14
|
-
|
13
|
+
update_aws_config({region: 'us-east-1', credentials: shared_credentials})
|
15
14
|
iam = Aws::IAM::Client.new
|
16
15
|
|
17
|
-
|
18
|
-
|
16
|
+
# this will be an array of 0 or 1 because iam.list_mfa_devices.mfa_devices will only return 0 or 1 device per user;
|
17
|
+
# if user doesn't have MFA enabled, then this loop won't even execute
|
19
18
|
iam.list_mfa_devices.mfa_devices.each do |mfadevice|
|
20
|
-
|
21
|
-
mfa_token = Output.ask("Enter MFA token: "){ |q| q.validate = /^\d{6}$/ }
|
22
|
-
session_credentials_hash = get_session(mfa_token,
|
23
|
-
mfa_serial_number,
|
24
|
-
shared_credentials.credentials.access_key_id,
|
25
|
-
shared_credentials.credentials.secret_access_key).credentials
|
26
|
-
|
27
|
-
session_credentials = Aws::Credentials.new(session_credentials_hash.access_key_id,
|
28
|
-
session_credentials_hash.secret_access_key,
|
29
|
-
session_credentials_hash.session_token)
|
30
|
-
Aws.config.update({region: 'us-east-1', credentials: session_credentials})
|
19
|
+
authenticate_with_mfa(mfadevice, shared_credentials)
|
31
20
|
end
|
32
21
|
end
|
33
22
|
|
23
|
+
def self.authenticate_with_mfa(mfadevice, shared_credentials)
|
24
|
+
mfa_serial_number = mfadevice.serial_number
|
25
|
+
mfa_token = Output.ask("Enter MFA token: "){ |q| q.validate = /^\d{6}$/ }
|
26
|
+
session_credentials_hash = get_session(mfa_token,
|
27
|
+
mfa_serial_number,
|
28
|
+
shared_credentials.credentials.access_key_id,
|
29
|
+
shared_credentials.credentials.secret_access_key).credentials
|
30
|
+
|
31
|
+
session_credentials = Aws::Credentials.new(session_credentials_hash.access_key_id,
|
32
|
+
session_credentials_hash.secret_access_key,
|
33
|
+
session_credentials_hash.session_token)
|
34
|
+
update_aws_config({region: 'us-east-1', credentials: session_credentials})
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.authenticate_with_assumed_roles(environment, arn_id, role_name, sts_client)
|
38
|
+
role_arn = "arn:aws:iam::#{arn_id}:role/#{role_name}"
|
39
|
+
session_name = "auditor#{Time.now.to_i}"
|
40
|
+
assumed_role_credentials = Aws::AssumeRoleCredentials.new(client: sts_client,
|
41
|
+
role_arn: role_arn,
|
42
|
+
role_session_name: session_name)
|
43
|
+
update_aws_config({region: 'us-east-1', credentials: assumed_role_credentials})
|
44
|
+
return assumed_role_credentials
|
45
|
+
end
|
46
|
+
|
34
47
|
def self.get_session(mfa_token, mfa_serial_number, access_key_id, secret_access_key)
|
35
48
|
return @session if @session
|
36
49
|
sts = Aws::STS::Client.new(access_key_id: access_key_id,
|
@@ -39,10 +52,10 @@ module SportNginAwsAuditor
|
|
39
52
|
@session = sts.get_session_token(duration_seconds: 3600,
|
40
53
|
serial_number: mfa_serial_number,
|
41
54
|
token_code: mfa_token)
|
42
|
-
end
|
55
|
+
end
|
43
56
|
|
44
|
-
def self.
|
45
|
-
Aws.config.update(
|
57
|
+
def self.update_aws_config(options)
|
58
|
+
Aws.config.update(options)
|
46
59
|
end
|
47
60
|
end
|
48
61
|
end
|
@@ -7,23 +7,23 @@ module SportNginAwsAuditor
|
|
7
7
|
extend AWSWrapper
|
8
8
|
|
9
9
|
class << self
|
10
|
-
def get_instances(tag_name=nil)
|
10
|
+
def get_instances(client, tag_name=nil)
|
11
11
|
account_id = get_account_id
|
12
|
-
|
12
|
+
client.describe_cache_clusters.cache_clusters.map do |instance|
|
13
13
|
next unless instance.cache_cluster_status.to_s == 'available'
|
14
|
-
new(instance, account_id, tag_name,
|
14
|
+
new(instance, account_id, tag_name, client)
|
15
15
|
end.compact
|
16
16
|
end
|
17
17
|
|
18
|
-
def get_reserved_instances
|
19
|
-
|
18
|
+
def get_reserved_instances(client)
|
19
|
+
client.describe_reserved_cache_nodes.reserved_cache_nodes.map do |instance|
|
20
20
|
next unless instance.state.to_s == 'active'
|
21
21
|
new(instance)
|
22
22
|
end.compact
|
23
23
|
end
|
24
24
|
|
25
|
-
def get_retired_reserved_instances
|
26
|
-
|
25
|
+
def get_retired_reserved_instances(client)
|
26
|
+
client.describe_reserved_cache_nodes.reserved_cache_nodes.map do |instance|
|
27
27
|
next unless instance.state == 'retired'
|
28
28
|
new(instance)
|
29
29
|
end.compact
|
@@ -31,7 +31,7 @@ module SportNginAwsAuditor
|
|
31
31
|
end
|
32
32
|
|
33
33
|
attr_accessor :id, :name, :instance_type, :scope, :engine, :count, :tag_value, :tag_reason, :expiration_date, :availability_zone
|
34
|
-
def initialize(cache_instance, account_id=nil, tag_name=nil,
|
34
|
+
def initialize(cache_instance, account_id=nil, tag_name=nil, client=nil)
|
35
35
|
if cache_instance.class.to_s == "Aws::ElastiCache::Types::ReservedCacheNode"
|
36
36
|
self.id = cache_instance.reserved_cache_node_id
|
37
37
|
self.name = cache_instance.reserved_cache_node_id
|
@@ -56,7 +56,7 @@ module SportNginAwsAuditor
|
|
56
56
|
arn = "arn:aws:elasticache:#{region}:#{account_id}:cluster:#{self.id}"
|
57
57
|
|
58
58
|
# go through to see if the tag we're looking for is one of them
|
59
|
-
|
59
|
+
client.list_tags_for_resource(resource_name: arn).tag_list.each do |tag|
|
60
60
|
if tag.key == tag_name
|
61
61
|
self.tag_value = tag.value
|
62
62
|
elsif tag.key == 'no-reserved-instance-reason'
|
@@ -1,30 +1,48 @@
|
|
1
1
|
require_relative './aws'
|
2
|
+
require 'aws-sdk'
|
2
3
|
require_relative './google'
|
3
4
|
|
4
5
|
module SportNginAwsAuditor
|
5
|
-
attr_accessor :
|
6
|
+
attr_accessor :assume_role_creds
|
6
7
|
|
7
8
|
module AWSWrapper
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
SportNginAwsAuditor::AWSSDK.
|
9
|
+
def aws(environment, global_options)
|
10
|
+
if global_options[:aws_roles]
|
11
|
+
SportNginAwsAuditor::AWSSDK.update_aws_config({region: 'us-east-1'})
|
12
|
+
elsif global_options[:assume_roles]
|
13
|
+
@assume_role_creds = SportNginAwsAuditor::AWSSDK.authenticate_with_assumed_roles(environment,
|
14
|
+
global_options[:arn_id],
|
15
|
+
global_options[:role_name],
|
16
|
+
get_sts_client(environment))
|
13
17
|
else
|
14
|
-
SportNginAwsAuditor::AWSSDK.
|
18
|
+
SportNginAwsAuditor::AWSSDK.authenticate_with_iam(environment)
|
15
19
|
end
|
16
20
|
end
|
17
21
|
|
18
22
|
def get_account_id
|
19
|
-
|
23
|
+
Aws::STS::Client.new.get_caller_identity.account
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_sts_client(environment)
|
27
|
+
@sts_client ||= Aws::STS::Client.new(profile: environment, region: 'us-east-1')
|
28
|
+
end
|
29
|
+
|
30
|
+
def reset_credentials
|
31
|
+
SportNginAwsAuditor::AWSSDK.update_aws_config({credentials: Aws::InstanceProfileCredentials.new})
|
20
32
|
end
|
21
33
|
end
|
22
34
|
|
23
35
|
module EC2Wrapper
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
@
|
36
|
+
def self.ec2(region=nil)
|
37
|
+
if @assume_role_creds && region
|
38
|
+
@ec2 = Aws::EC2::Client.new(credentials: @assume_role_creds, region: region)
|
39
|
+
elsif @assume_role_creds && !region
|
40
|
+
@ec2 = Aws::EC2::Client.new(credentials: @assume_role_creds)
|
41
|
+
elsif @assume_role_creds.nil? && region
|
42
|
+
@ec2 = Aws::EC2::Client.new(region: region)
|
43
|
+
else
|
44
|
+
@ec2 = Aws::EC2::Client.new
|
45
|
+
end
|
28
46
|
end
|
29
47
|
end
|
30
48
|
|
@@ -32,23 +50,40 @@ module SportNginAwsAuditor
|
|
32
50
|
attr_accessor :opsworks
|
33
51
|
|
34
52
|
def opsworks
|
35
|
-
@opsworks
|
53
|
+
return @opsworks if @opsworks
|
54
|
+
if @assume_role_creds
|
55
|
+
@opsworks = Aws::Opsworks::Client.new(credentials: @assume_role_creds)
|
56
|
+
else
|
57
|
+
@opsworks = Aws::OpsWorks::Client.new
|
58
|
+
end
|
36
59
|
end
|
37
60
|
end
|
38
61
|
|
39
62
|
module RDSWrapper
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
@
|
63
|
+
def self.rds(region=nil)
|
64
|
+
if @assume_role_creds && region
|
65
|
+
@rds = Aws::RDS::Client.new(credentials: @assume_role_creds, region: region)
|
66
|
+
elsif @assume_role_creds && !region
|
67
|
+
@rds = Aws::RDS::Client.new(credentials: @assume_role_creds)
|
68
|
+
elsif @assume_role_creds.nil? && region
|
69
|
+
@rds = Aws::RDS::Client.new(region: region)
|
70
|
+
else
|
71
|
+
@rds = Aws::RDS::Client.new
|
72
|
+
end
|
44
73
|
end
|
45
74
|
end
|
46
75
|
|
47
76
|
module CacheWrapper
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
@
|
77
|
+
def self.cache(region=nil)
|
78
|
+
if @assume_role_creds && region
|
79
|
+
@cache = Aws::ElastiCache::Client.new(credentials: @assume_role_creds, region: region)
|
80
|
+
elsif @assume_role_creds && !region
|
81
|
+
@cache = Aws::ElastiCache::Client.new(credentials: @assume_role_creds)
|
82
|
+
elsif @assume_role_creds.nil? && region
|
83
|
+
@cache = Aws::ElastiCache::Client.new(region: region)
|
84
|
+
else
|
85
|
+
@cache = Aws::ElastiCache::Client.new
|
86
|
+
end
|
52
87
|
end
|
53
88
|
end
|
54
89
|
|
@@ -6,33 +6,33 @@ module SportNginAwsAuditor
|
|
6
6
|
extend EC2Wrapper
|
7
7
|
|
8
8
|
class << self
|
9
|
-
def get_instances(tag_name=nil)
|
10
|
-
instances =
|
9
|
+
def get_instances(client, tag_name=nil)
|
10
|
+
instances = client.describe_instances.reservations.map do |reservation|
|
11
11
|
reservation.instances.map do |instance|
|
12
12
|
next unless instance.state.name == 'running'
|
13
13
|
new(instance, tag_name)
|
14
14
|
end.compact
|
15
15
|
end.flatten.compact
|
16
|
-
get_more_info(instances)
|
16
|
+
get_more_info(instances, client)
|
17
17
|
end
|
18
18
|
|
19
|
-
def get_reserved_instances
|
20
|
-
|
19
|
+
def get_reserved_instances(client)
|
20
|
+
client.describe_reserved_instances.reserved_instances.map do |instance|
|
21
21
|
next unless instance.state == 'active'
|
22
22
|
new(instance, nil, instance.instance_count)
|
23
23
|
end.compact
|
24
24
|
end
|
25
25
|
|
26
|
-
def get_retired_reserved_instances
|
27
|
-
|
26
|
+
def get_retired_reserved_instances(client)
|
27
|
+
client.describe_reserved_instances.reserved_instances.map do |instance|
|
28
28
|
next unless instance.state == 'retired'
|
29
29
|
new(instance, nil, instance.instance_count)
|
30
30
|
end.compact
|
31
31
|
end
|
32
32
|
|
33
|
-
def bucketize
|
33
|
+
def bucketize(client)
|
34
34
|
buckets = {}
|
35
|
-
get_instances.map do |instance|
|
35
|
+
get_instances(client).map do |instance|
|
36
36
|
name = instance.stack_name || instance.name
|
37
37
|
if name
|
38
38
|
buckets[name] = [] unless buckets.has_key? name
|
@@ -44,9 +44,9 @@ module SportNginAwsAuditor
|
|
44
44
|
buckets.sort_by{|k,v| k }
|
45
45
|
end
|
46
46
|
|
47
|
-
def get_more_info(instances)
|
47
|
+
def get_more_info(instances, client)
|
48
48
|
instances.each do |instance|
|
49
|
-
tags =
|
49
|
+
tags = client.describe_tags(:filters => [{:name => "resource-id", :values => [instance.id]}]).tags
|
50
50
|
tags = Hash[tags.map { |tag| [tag[:key], tag[:value]]}.compact]
|
51
51
|
instance.name = tags["Name"]
|
52
52
|
instance.stack_name = tags["opsworks:stack"]
|
@@ -4,12 +4,12 @@ require_relative './audit_data'
|
|
4
4
|
module SportNginAwsAuditor
|
5
5
|
module InstanceHelper
|
6
6
|
|
7
|
-
def instance_hash
|
8
|
-
Hash[get_instances.map { |instance| instance.nil? ? next : [instance.id, instance]}.compact]
|
7
|
+
def instance_hash(client)
|
8
|
+
Hash[get_instances(client).map { |instance| instance.nil? ? next : [instance.id, instance]}.compact]
|
9
9
|
end
|
10
10
|
|
11
|
-
def reserved_instance_hash
|
12
|
-
Hash[get_reserved_instances.map { |instance| instance.nil? ? next : [instance.id, instance]}.compact]
|
11
|
+
def reserved_instance_hash(client)
|
12
|
+
Hash[get_reserved_instances(client).map { |instance| instance.nil? ? next : [instance.id, instance]}.compact]
|
13
13
|
end
|
14
14
|
|
15
15
|
#################### ADDING DATA TO HASH ####################
|
@@ -102,8 +102,8 @@ module SportNginAwsAuditor
|
|
102
102
|
return ignored_instances, instances_with_tag, instance_hash
|
103
103
|
end
|
104
104
|
|
105
|
-
def sort_through_RIs
|
106
|
-
ris = get_reserved_instances
|
105
|
+
def sort_through_RIs(client)
|
106
|
+
ris = get_reserved_instances(client)
|
107
107
|
ris_availability = filter_ris_availability_zone(ris)
|
108
108
|
ris_region = filter_ris_region_based(ris)
|
109
109
|
ris_hash = instance_count_hash(ris_availability)
|
@@ -127,9 +127,9 @@ module SportNginAwsAuditor
|
|
127
127
|
return differences
|
128
128
|
end
|
129
129
|
|
130
|
-
def compare(instances, ignore_instances_regexes)
|
130
|
+
def compare(instances, ignore_instances_regexes, client)
|
131
131
|
ignored_instances, instances_with_tag, instance_hash = sort_through_instances(instances, ignore_instances_regexes)
|
132
|
-
ris_region, ris_hash = sort_through_RIs
|
132
|
+
ris_region, ris_hash = sort_through_RIs(client)
|
133
133
|
differences = measure_differences(instance_hash, ris_hash)
|
134
134
|
add_additional_data(ris_region, instances_with_tag, ignored_instances, differences)
|
135
135
|
differences
|
@@ -177,8 +177,8 @@ module SportNginAwsAuditor
|
|
177
177
|
|
178
178
|
# this gets all retired reserved instances and filters out only the ones that have expired
|
179
179
|
# within the past week
|
180
|
-
def get_recent_retired_reserved_instances
|
181
|
-
get_retired_reserved_instances.select do |ri|
|
180
|
+
def get_recent_retired_reserved_instances(client)
|
181
|
+
get_retired_reserved_instances(client).select do |ri|
|
182
182
|
ri.expiration_date > (Time.now - 604800)
|
183
183
|
end
|
184
184
|
end
|
@@ -7,23 +7,23 @@ module SportNginAwsAuditor
|
|
7
7
|
extend AWSWrapper
|
8
8
|
|
9
9
|
class << self
|
10
|
-
def get_instances(tag_name=nil)
|
10
|
+
def get_instances(client, tag_name=nil)
|
11
11
|
account_id = get_account_id
|
12
|
-
|
12
|
+
client.describe_db_instances.db_instances.map do |instance|
|
13
13
|
next unless instance.db_instance_status.to_s == 'available'
|
14
|
-
new(instance, account_id, tag_name,
|
14
|
+
new(instance, account_id, tag_name, client)
|
15
15
|
end.compact
|
16
16
|
end
|
17
17
|
|
18
|
-
def get_reserved_instances
|
19
|
-
|
18
|
+
def get_reserved_instances(client)
|
19
|
+
client.describe_reserved_db_instances.reserved_db_instances.map do |instance|
|
20
20
|
next unless instance.state.to_s == 'active'
|
21
21
|
new(instance)
|
22
22
|
end.compact
|
23
23
|
end
|
24
24
|
|
25
|
-
def get_retired_reserved_instances
|
26
|
-
|
25
|
+
def get_retired_reserved_instances(client)
|
26
|
+
client.describe_reserved_db_instances.reserved_db_instances.map do |instance|
|
27
27
|
next unless instance.state == 'retired'
|
28
28
|
new(instance)
|
29
29
|
end.compact
|
@@ -31,7 +31,7 @@ module SportNginAwsAuditor
|
|
31
31
|
end
|
32
32
|
|
33
33
|
attr_accessor :id, :name, :multi_az, :scope, :instance_type, :engine, :count, :tag_value, :tag_reason, :expiration_date
|
34
|
-
def initialize(rds_instance, account_id=nil, tag_name=nil,
|
34
|
+
def initialize(rds_instance, account_id=nil, tag_name=nil, client=nil)
|
35
35
|
if rds_instance.class.to_s == "Aws::RDS::Types::ReservedDBInstance"
|
36
36
|
self.id = rds_instance.reserved_db_instances_offering_id
|
37
37
|
self.scope = nil
|
@@ -55,7 +55,7 @@ module SportNginAwsAuditor
|
|
55
55
|
arn = "arn:aws:rds:#{region}:#{account_id}:db:#{self.id}"
|
56
56
|
|
57
57
|
# go through to see if the tag we're looking for is one of them
|
58
|
-
|
58
|
+
client.list_tags_for_resource(resource_name: arn).tag_list.each do |tag|
|
59
59
|
if tag.key == tag_name
|
60
60
|
self.tag_value = tag.value
|
61
61
|
elsif tag.key == 'no-reserved-instance-reason'
|