sport_ngin_aws_auditor 4.1.0 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5277289fe41b4b8e42e6f5cca63e4d18406cfcb6
4
- data.tar.gz: ac8c8938e68b0e7b1592cb633b3dc81628345180
3
+ metadata.gz: e6e2a11ed64e5f72238b80eb808015489df6a243
4
+ data.tar.gz: 1b09c49f16a8bf21db028a1be599ed09ff107526
5
5
  SHA512:
6
- metadata.gz: fd4073d93376063c9f21c1d9925cac0f86f01f6111291f2bf74c1d68d010fe97e6d056b4122904e91919f4f60b8a5f89fef8c73ad11c47648fd66754f37a6272
7
- data.tar.gz: 232c7a07934fe6c05757146fb626c91d15616fe963d4ed00158c2b075e74225027ca377322de0920dccd7b2f3826d0a114a51295cdd7639aa99a7a9160ab33de
6
+ metadata.gz: b3e794c240a871df8314544b34a2a065409cd83e5bd09f8842e6f5fd6a3a75ad1d9b1ce4f5c4ab5ca0c3bad72cdbcdbd55636b4f52021ff95f6a545ad12fb2ee
7
+ data.tar.gz: 4d845435e3ede6990360081c22a084545adc66dd76be55234ac1182945b77dca3967b541432da25f3d23601c4ae67d1fdde53aa2c44316f764beda3768037219
data/CHANGELOG.markdown CHANGED
@@ -1,142 +1 @@
1
- #### v4.1.0
2
- * Write a message reporting when the auditor fails for any reason
3
-
4
- > Emma Sax: Unknown User: https://github.com/sportngin/sport_ngin_aws_auditor/pull/36
5
-
6
- #### v4.0.2
7
- * Define availability zone as attribute for RDS object to avoid errors
8
-
9
- > Emma Sax: Unknown User: https://github.com/sportngin/sport_ngin_aws_auditor/pull/35
10
-
11
- #### v4.0.1
12
- * Concat all of the similar values into one value right before printing
13
-
14
- > Emma Sax: Unknown User: https://github.com/sportngin/sport_ngin_aws_auditor/pull/27
15
-
16
- #### v4.0.0
17
- * Adding abilities to audit cross account
18
-
19
- > Emma Sax: Unknown User: https://github.com/sportngin/sport_ngin_aws_auditor/pull/31
20
-
21
- #### v3.11.3
22
- * Missed this bug because I did not test previous bug's fix in Slack
23
-
24
- > Emma Sax: Unknown User: https://github.com/sportngin/sport_ngin_aws_auditor/pull/30
25
-
26
- #### v3.11.2
27
- * We actually do not want to cache the counts of instances and reserved instances between multiple runs
28
-
29
- > Emma Sax: Unknown User: https://github.com/sportngin/sport_ngin_aws_auditor/pull/29
30
-
31
- #### v3.11.1
32
- * Must merge this PR in to run the audit command correctly
33
-
34
- > Emma Sax: Unknown User: https://github.com/sportngin/sport_ngin_aws_auditor/pull/28
35
-
36
- #### v3.11.0
37
- * Automatically ignore instances based on a regex string
38
-
39
- > Emma Sax: Unknown User: https://github.com/sportngin/sport_ngin_aws_auditor/pull/26
40
-
41
- #### v3.10.1
42
- * Caching should not affect RI counts between runs
43
-
44
- > Emma Sax: Andy Fleener, Unknown User: https://github.com/sportngin/sport_ngin_aws_auditor/pull/25
45
-
46
- #### v3.10.0
47
- * Handling region-based RIs
48
-
49
- > Emma Sax: Andy Fleener, Luke Ludwig, Tim Sandquist, Unknown User: https://github.com/sportngin/sport_ngin_aws_auditor/pull/21
50
-
51
- #### v3.9.0
52
- * Add the ability to pass config data in as a flag
53
-
54
- > Emma Sax: Andy Fleener, Unknown User: https://github.com/sportngin/sport_ngin_aws_auditor/pull/24
55
-
56
- #### v3.8.3
57
- * Fixing bugs with outputs and counts
58
-
59
- > Emma Sax: Tim Sandquist, Unknown User: https://github.com/sportngin/sport_ngin_aws_auditor/pull/23
60
-
61
- #### v3.8.2
62
- * Fixing bugs so that counts are accurate again
63
-
64
- > Emma Sax: : https://github.com/sportngin/sport_ngin_aws_auditor/pull/20
65
-
66
- #### v3.8.1
67
- #### v3.8.0
68
- * Clarifying printout of audit command
69
-
70
- > Emma Sax: : https://github.com/sportngin/sport_ngin_aws_auditor/pull/18
71
-
72
- #### v3.7.0
73
- * Print retired tags into slack/terminal on audit
74
-
75
- > Emma Sax: Brian Bergstrom: https://github.com/sportngin/sport_ngin_aws_auditor/pull/17
76
-
77
- #### v3.6.0
78
- * Print reserved instances that have retired in past week
79
-
80
- > Emma Sax: Andy Fleener: https://github.com/sportngin/sport_ngin_aws_auditor/pull/16
81
-
82
- #### v3.5.0
83
- * Cleaning up slack printouts with the audit command
84
-
85
- > Emma Sax: Brian Bergstrom: https://github.com/sportngin/sport_ngin_aws_auditor/pull/15
86
-
87
- #### v3.4.1
88
- #### v3.4.0
89
- * Add other RDS engine types
90
-
91
- > matl33t: Emma Sax, Brian Bergstrom: https://github.com/sportngin/sport_ngin_aws_auditor/pull/11
92
-
93
- #### v3.3.1
94
- * Fixing bug where Slack will print discrepancies if there are *only* tagged instances
95
-
96
- > Emma Sax: : https://github.com/sportngin/sport_ngin_aws_auditor/pull/13
97
-
98
- #### v3.3.0
99
- * Slack should print instances that have tags
100
-
101
- > Emma Sax: Andy Fleener: https://github.com/sportngin/sport_ngin_aws_auditor/pull/12
102
-
103
- #### v3.2.0
104
- * Proper recognition of windows/linux/vpc instances
105
-
106
- > Emma Sax: Andy Fleener: https://github.com/sportngin/sport_ngin_aws_auditor/pull/8
107
-
108
- #### v3.1.2
109
- #### v3.1.0
110
- * Authentication with AWS roles instead of credentials file
111
-
112
- > Emma Sax: Brian Bergstrom: https://github.com/sportngin/sport_ngin_aws_auditor/pull/7
113
-
114
- #### v3.0.2
115
- #### v3.0.1
116
- #### v3.0.0
117
- * Rename gem directories and modules
118
-
119
- > Emma Sax: Brian Bergstrom: https://github.com/sportngin/sport_ngin_aws_auditor/pull/6
120
-
121
- #### v2.1.0
122
- * Adding option to print audit results to Slack channel
123
-
124
- > Emma Sax, Matt Krieger: Brian Bergstrom: https://github.com/sportngin/aws_auditor/pull/4
125
-
126
- * Adding option to print audit results to Slack channel
127
-
128
- > Emma Sax, Matt Krieger: Brian Bergstrom: https://github.com/sportngin/aws_auditor/pull/4
129
-
130
- #### v2.0.0
131
- * Adding enhancements for taking no-reserved-instance tag into consideration during audit
132
-
133
- > Emma Sax: Brian Bergstrom: https://github.com/sportngin/aws_auditor/pull/2
134
-
135
- #### v1.0.0
136
- * Upgrading aws-sdk version from v1 to v2
137
-
138
- > Emma Sax: Brian Bergstrom: https://github.com/sportngin/aws_auditor/pull/3
139
-
140
- * First tests, Travis CI, MFA support, and fog file compatibility
141
-
142
- > Brian Bergstrom: Emma Sax: https://github.com/sportngin/aws_auditor/pull/1
1
+ #### v4.2.0
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'rubygems'
3
3
  require 'gli'
4
- require_relative '../lib/sport_ngin_aws_auditor'
4
+ require 'sport_ngin_aws_auditor'
5
5
 
6
6
  include GLI::App
7
7
 
@@ -33,4 +33,13 @@ pre do |global,command,options,args|
33
33
  true
34
34
  end
35
35
 
36
+ on_error do |exception|
37
+ if ENV['GLI_DEBUG']
38
+ puts exception
39
+ puts exception.backtrace
40
+ else
41
+ true
42
+ end
43
+ end
44
+
36
45
  exit run(ARGV)
@@ -1,13 +1,7 @@
1
- require_relative './instance_helper'
2
- require_relative './convenience_wrappers'
3
-
4
1
  module SportNginAwsAuditor
5
2
  class AuditData
6
- extend EC2Wrapper
7
- extend RDSWrapper
8
- extend CacheWrapper
9
-
10
3
  attr_accessor :data, :retired_tags, :retired_ris, :selected_audit_type, :klass, :tag_name, :region, :ignore_instances_regexes, :client
4
+
11
5
  def initialize(info)
12
6
  self.selected_audit_type = (!info[:instances] && !info[:reserved]) ? "all" : (info[:instances] ? "instances" : "reserved")
13
7
  self.klass = SportNginAwsAuditor.const_get(info[:class])
@@ -16,11 +10,11 @@ module SportNginAwsAuditor
16
10
  self.region = info[:region].match(/(\w{2}-\w{4,})/)[0] if info[:region].match(/(\w{2}-\w{4,})/)
17
11
 
18
12
  if info[:class] == "EC2Instance"
19
- self.client = EC2Wrapper.ec2(info[:region])
13
+ self.client = AWS.ec2(info[:region])
20
14
  elsif info[:class] == "RDSInstance"
21
- self.client = RDSWrapper.rds(info[:region])
15
+ self.client = AWS.rds(info[:region])
22
16
  elsif info[:class] == "CacheInstance"
23
- self.client = CacheWrapper.cache(info[:region])
17
+ self.client = AWS.cache(info[:region])
24
18
  end
25
19
  end
26
20
 
@@ -1,61 +1,99 @@
1
1
  require 'aws-sdk'
2
- require 'yaml'
3
- require 'hashie'
4
2
 
5
3
  module SportNginAwsAuditor
6
- class AwsConfig < Hash
7
- include Hashie::Extensions::IndifferentAccess
8
- end
4
+ class AWS
5
+ DEFAULT_REGION = 'us-east-1'
6
+
7
+ @environment = nil
8
+ @aws_roles = false
9
+ @assume_roles = false
10
+ @credentials = nil
11
+
12
+ class << self
13
+ attr_reader :environment, :aws_roles, :assume_roles, :credentials
14
+ end
15
+
16
+ def self.configure(environment, global_options)
17
+ @environment = environment
18
+
19
+ if global_options[:aws_roles]
20
+ puts "Authenticating with AWS using server roles."
21
+ @credentials = nil # Auth using server role.
22
+ elsif global_options[:assume_roles]
23
+ puts "Authenticating with AWS by assuming roles."
24
+ auth_with_assumed_roles(global_options[:arn_id], global_options[:role_name])
25
+ else
26
+ puts "Authenticating with AWS using credentials file."
27
+ auth_with_iam
28
+ end
29
+ end
30
+
31
+ def self.reset
32
+ @environment = @credentials = nil
33
+ @aws_roles = @assume_roles = nil
34
+ end
35
+
36
+ def self.client_options(region=DEFAULT_REGION)
37
+ if @credentials.nil? && @aws_roles == false
38
+ raise "Unable to set AWS SDK client options because credentials not set and not flagged to use server role."
39
+ end
40
+ opts = { region: region }
41
+ opts[:credentials] = @credentials unless @credentials.nil?
42
+ opts
43
+ end
9
44
 
10
- class AWSSDK
11
- def self.authenticate_with_iam(environment)
12
- shared_credentials = Aws::SharedCredentials.new(profile_name: environment)
13
- update_aws_config({region: 'us-east-1', credentials: shared_credentials})
14
- iam = Aws::IAM::Client.new
45
+ def self.get_account_id
46
+ Aws::STS::Client.new(client_options).get_caller_identity.account
47
+ end
48
+
49
+ def self.sts_for_instance
50
+ Aws::STS::Client.new(region: DEFAULT_REGION, credentials: Aws::InstanceProfileCredentials.new)
51
+ end
52
+
53
+ def self.ec2(region=DEFAULT_REGION)
54
+ Aws::EC2::Client.new(client_options(region))
55
+ end
56
+
57
+ def self.rds(region=DEFAULT_REGION)
58
+ Aws::RDS::Client.new(client_options(region))
59
+ end
60
+
61
+ def self.cache(region=DEFAULT_REGION)
62
+ Aws::ElastiCache::Client.new(client_options(region))
63
+ end
64
+
65
+
66
+ def self.auth_with_iam
67
+ @credentials = Aws::SharedCredentials.new(profile_name: @environment)
68
+ iam = Aws::IAM::Client.new(client_options)
15
69
 
16
70
  # 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
71
  # if user doesn't have MFA enabled, then this loop won't even execute
18
72
  iam.list_mfa_devices.mfa_devices.each do |mfadevice|
19
- authenticate_with_mfa(mfadevice, shared_credentials)
73
+ auth_with_mfa(mfadevice)
20
74
  end
21
75
  end
22
76
 
23
- def self.authenticate_with_mfa(mfadevice, shared_credentials)
77
+ def self.auth_with_mfa(mfadevice)
24
78
  mfa_serial_number = mfadevice.serial_number
25
79
  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
80
+ session_credentials_hash = get_session(mfa_token, mfa_serial_number).credentials
30
81
 
31
- session_credentials = Aws::Credentials.new(session_credentials_hash.access_key_id,
82
+ @credentials = Aws::Credentials.new(session_credentials_hash.access_key_id,
32
83
  session_credentials_hash.secret_access_key,
33
84
  session_credentials_hash.session_token)
34
- update_aws_config({region: 'us-east-1', credentials: session_credentials})
35
85
  end
36
86
 
37
- def self.authenticate_with_assumed_roles(environment, arn_id, role_name, sts_client)
87
+ def self.auth_with_assumed_roles(arn_id, role_name)
38
88
  role_arn = "arn:aws:iam::#{arn_id}:role/#{role_name}"
39
89
  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
90
+ @credentials = Aws::AssumeRoleCredentials.new(client: sts_for_instance, role_arn: role_arn, role_session_name: session_name)
45
91
  end
46
92
 
47
- def self.get_session(mfa_token, mfa_serial_number, access_key_id, secret_access_key)
93
+ def self.get_session(mfa_token, mfa_serial_number)
48
94
  return @session if @session
49
- sts = Aws::STS::Client.new(access_key_id: access_key_id,
50
- secret_access_key: secret_access_key,
51
- region: 'us-east-1')
52
- @session = sts.get_session_token(duration_seconds: 3600,
53
- serial_number: mfa_serial_number,
54
- token_code: mfa_token)
55
- end
56
-
57
- def self.update_aws_config(options)
58
- Aws.config.update(options)
95
+ @session = sts_for_instance.get_session_token(duration_seconds: 3600, serial_number: mfa_serial_number, token_code: mfa_token)
59
96
  end
97
+
60
98
  end
61
99
  end
@@ -1,21 +1,19 @@
1
- require_relative './instance_helper'
1
+ require 'sport_ngin_aws_auditor/instance_helper'
2
2
 
3
3
  module SportNginAwsAuditor
4
4
  class CacheInstance
5
5
  extend InstanceHelper
6
- extend CacheWrapper
7
- extend AWSWrapper
8
6
 
9
7
  class << self
10
- def get_instances(client, tag_name=nil)
11
- account_id = get_account_id
8
+ def get_instances(client=AWS.cache, tag_name=nil)
9
+ account_id = AWS.get_account_id
12
10
  client.describe_cache_clusters.cache_clusters.map do |instance|
13
11
  next unless instance.cache_cluster_status.to_s == 'available'
14
12
  new(instance, account_id, tag_name, client)
15
13
  end.compact
16
14
  end
17
15
 
18
- def get_reserved_instances(client)
16
+ def get_reserved_instances(client=AWS.cache)
19
17
  client.describe_reserved_cache_nodes.reserved_cache_nodes.map do |instance|
20
18
  next unless instance.state.to_s == 'active'
21
19
  new(instance)
@@ -15,7 +15,7 @@ command 'audit' do |c|
15
15
  one of these strings in the name,
16
16
  pass in like: string1, string2, string3"
17
17
  c.action do |global_options, options, args|
18
- require_relative '../scripts/audit'
18
+ require 'sport_ngin_aws_auditor/scripts/audit'
19
19
  raise ArgumentError, 'You must specify an AWS account' unless args.first
20
20
  SportNginAwsAuditor::Scripts::Audit.execute(args.first, options, global_options)
21
21
  end
@@ -4,7 +4,7 @@ command 'export' do |c|
4
4
  c.switch [:c, :csv], :desc => "Exports to CSV"
5
5
  c.switch [:d, :drive], :desc => "Exports to Google Drive"
6
6
  c.action do |global_options, options, args|
7
- require_relative '../scripts/export'
7
+ require 'sport_ngin_aws_auditor/scripts/export'
8
8
  raise ArgumentError, 'You must specify an AWS account' unless args.first
9
9
  SportNginAwsAuditor::Scripts::Export.execute(args.first, options, global_options)
10
10
  end
@@ -5,7 +5,7 @@ command 'inspect' do |c|
5
5
  c.switch [:d, :rds], :desc => "Only inspect RDS instances"
6
6
  c.switch [:c, :cache], :desc => "Only inspect ElastiCache instances"
7
7
  c.action do |global_options, options, args|
8
- require_relative '../scripts/inspect'
8
+ require 'sport_ngin_aws_auditor/scripts/inspect'
9
9
  raise ArgumentError, 'You must specify an AWS account' unless args.first
10
10
  SportNginAwsAuditor::Scripts::Inspect.execute(args.first,options, global_options)
11
11
  end
@@ -1,92 +1,4 @@
1
- require_relative './aws'
2
- require 'aws-sdk'
3
- require_relative './google'
4
-
5
1
  module SportNginAwsAuditor
6
- attr_accessor :assume_role_creds
7
-
8
- module AWSWrapper
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))
17
- else
18
- SportNginAwsAuditor::AWSSDK.authenticate_with_iam(environment)
19
- end
20
- end
21
-
22
- def get_account_id
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})
32
- end
33
- end
34
-
35
- module EC2Wrapper
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
46
- end
47
- end
48
-
49
- module OpsWorksWrapper
50
- attr_accessor :opsworks
51
-
52
- def 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
59
- end
60
- end
61
-
62
- module RDSWrapper
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
73
- end
74
- end
75
-
76
- module CacheWrapper
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
87
- end
88
- end
89
-
90
2
  module GoogleWrapper
91
3
  attr_accessor :google
92
4
 
@@ -1,12 +1,9 @@
1
- require_relative './instance_helper'
2
-
3
1
  module SportNginAwsAuditor
4
2
  class EC2Instance
5
3
  extend InstanceHelper
6
- extend EC2Wrapper
7
4
 
8
5
  class << self
9
- def get_instances(client, tag_name=nil)
6
+ def get_instances(client=AWS.ec2, tag_name=nil)
10
7
  instances = client.describe_instances.reservations.map do |reservation|
11
8
  reservation.instances.map do |instance|
12
9
  next unless instance.state.name == 'running'
@@ -16,7 +13,7 @@ module SportNginAwsAuditor
16
13
  get_more_info(instances, client)
17
14
  end
18
15
 
19
- def get_reserved_instances(client)
16
+ def get_reserved_instances(client=AWS.ec2)
20
17
  client.describe_reserved_instances.reserved_instances.map do |instance|
21
18
  next unless instance.state == 'active'
22
19
  new(instance, nil, instance.instance_count)
@@ -1,5 +1,3 @@
1
- require_relative './instance_helper'
2
-
3
1
  module SportNginAwsAuditor
4
2
  class Instance
5
3
  extend InstanceHelper
@@ -1,6 +1,3 @@
1
- require_relative './recently_retired_tag'
2
- require_relative './audit_data'
3
-
4
1
  module SportNginAwsAuditor
5
2
  module InstanceHelper
6
3
 
@@ -9,5 +9,9 @@ module SportNginAwsAuditor
9
9
  def self.ask(*args, &block)
10
10
  terminal.ask(*args, &block)
11
11
  end
12
+
13
+ def self.say(msg)
14
+ terminal.say(msg)
15
+ end
12
16
  end
13
17
  end
@@ -1,21 +1,17 @@
1
- require_relative './instance_helper'
2
-
3
1
  module SportNginAwsAuditor
4
2
  class RDSInstance
5
3
  extend InstanceHelper
6
- extend RDSWrapper
7
- extend AWSWrapper
8
4
 
9
5
  class << self
10
- def get_instances(client, tag_name=nil)
11
- account_id = get_account_id
6
+ def get_instances(client=AWS.rds, tag_name=nil)
7
+ account_id = AWS.get_account_id
12
8
  client.describe_db_instances.db_instances.map do |instance|
13
9
  next unless instance.db_instance_status.to_s == 'available'
14
10
  new(instance, account_id, tag_name, client)
15
11
  end.compact
16
12
  end
17
13
 
18
- def get_reserved_instances(client)
14
+ def get_reserved_instances(client=AWS.rds)
19
15
  client.describe_reserved_db_instances.reserved_db_instances.map do |instance|
20
16
  next unless instance.state.to_s == 'active'
21
17
  new(instance)
@@ -1,5 +1,3 @@
1
- require_relative './instance_helper'
2
-
3
1
  module SportNginAwsAuditor
4
2
  class RecentlyRetiredTag
5
3
 
@@ -3,13 +3,9 @@ require 'colorize'
3
3
  require 'aws-sdk'
4
4
  require_relative "../notify_slack"
5
5
  require_relative "../instance"
6
- require_relative "../audit_data"
7
-
8
6
  module SportNginAwsAuditor
9
7
  module Scripts
10
8
  class Audit
11
- extend AWSWrapper
12
-
13
9
  class << self
14
10
  attr_accessor :options, :audit_results
15
11
  end
@@ -18,11 +14,10 @@ module SportNginAwsAuditor
18
14
 
19
15
  def self.execute(environment, options, global_options)
20
16
  begin
21
- aws(environment, global_options)
17
+ AWS.configure(environment, global_options)
22
18
  collect_options(environment, options, global_options)
23
19
  print_title
24
20
  @regions.each { |region| audit_region(region) }
25
- reset_credentials
26
21
  rescue StandardError => e
27
22
  if options[:slack]
28
23
  NotifySlack.new("Sorry, something seems to have gone wrong.", options[:config_json]).perform
@@ -232,8 +227,7 @@ module SportNginAwsAuditor
232
227
  #################### OTHER HELPFUL METHODS ####################
233
228
 
234
229
  def self.gather_regions
235
- ec2 = Aws::EC2::Client.new(region: 'us-east-1')
236
- regions = ec2.describe_regions[:regions]
230
+ regions = AWS.ec2.describe_regions[:regions]
237
231
  us_regions = regions.select { |region| region.region_name.include?("us") }
238
232
  us_regions.collect { |r| r.region_name }
239
233
  end
@@ -1,11 +1,9 @@
1
1
  require 'csv'
2
- require_relative "../google"
3
2
 
4
3
  module SportNginAwsAuditor
5
4
  module Scripts
6
5
  class Export
7
6
  extend GoogleWrapper
8
- extend AWSWrapper
9
7
 
10
8
  class << self
11
9
  attr_accessor :ec2_instances, :rds_instances, :cache_instances, :options, :file, :keys_hash, :environment
@@ -16,7 +14,7 @@ module SportNginAwsAuditor
16
14
  def self.execute(environment, options = nil, global_options = nil)
17
15
  @environment = environment
18
16
  (puts "Must specify either --drive or --csv"; exit) unless options[:csv] || options[:drive]
19
- aws(environment, global_options[:aws_roles])
17
+ AWS.configure(environment, global_options)
20
18
  print "Gathering info, please wait..."
21
19
  all_keys = get_all_keys
22
20
  all_info = prepare
@@ -78,7 +76,7 @@ module SportNginAwsAuditor
78
76
 
79
77
  def self.ec2_array
80
78
  instance_array = [{name: "OPSWORKS"}]
81
- EC2Instance.bucketize.map do |stack_name, stack_instances|
79
+ EC2Instance.bucketize(AWS.ec2).map do |stack_name, stack_instances|
82
80
  instance_array << {:name => stack_name}.merge(EC2Instance.instance_count_hash(stack_instances))
83
81
  end
84
82
  instance_array
@@ -112,33 +110,33 @@ module SportNginAwsAuditor
112
110
  klass = SportNginAwsAuditor.const_get(class_type)
113
111
  instances = klass.instance_count_hash(klass.get_instances) if options[:instance]
114
112
  instances = klass.instance_count_hash(klass.get_reserved_instances) if options[:reserved]
115
- instances = klass.compare if options[:compare]
113
+ instances = klass.compare if options[:compare] #TODO fix me
116
114
  instances
117
115
  end.inject(:merge)
118
116
  end
119
117
 
120
118
  def self.ec2_instances
121
- @ec2_instances ||= EC2Instance.instance_hash
119
+ @ec2_instances ||= EC2Instance.instance_hash(AWS.ec2)
122
120
  end
123
121
 
124
122
  def self.ec2_reserved_instances
125
- @ec2_reserved_instances ||= EC2Instance.reserved_instance_hash
123
+ @ec2_reserved_instances ||= EC2Instance.reserved_instance_hash(AWS.ec2)
126
124
  end
127
125
 
128
126
  def self.rds_instances
129
- @rds_instances ||= RDSInstance.instance_hash
127
+ @rds_instances ||= RDSInstance.instance_hash(AWS.rds)
130
128
  end
131
129
 
132
130
  def self.rds_reserved_instances
133
- @rds_reserved_instances ||= RDSInstance.reserved_instance_hash
131
+ @rds_reserved_instances ||= RDSInstance.reserved_instance_hash(AWS.rds)
134
132
  end
135
133
 
136
134
  def self.cache_instances
137
- @cache_instances ||= CacheInstance.instance_hash
135
+ @cache_instances ||= CacheInstance.instance_hash(AWS.cache)
138
136
  end
139
137
 
140
138
  def self.cache_reserved_instances
141
- @cache_reserved_instances ||= CacheInstance.reserved_instance_hash
139
+ @cache_reserved_instances ||= CacheInstance.reserved_instance_hash(AWS.cache)
142
140
  end
143
141
 
144
142
  end
@@ -1,14 +1,9 @@
1
1
  module SportNginAwsAuditor
2
2
  module Scripts
3
3
  class Inspect
4
- extend AWSWrapper
5
- extend OpsWorksWrapper
6
- extend EC2Wrapper
7
- extend RDSWrapper
8
- extend CacheWrapper
9
4
 
10
5
  def self.execute(environment, options=nil, global_options=nil)
11
- aws(environment, global_options)
6
+ AWS.configure(environment, global_options)
12
7
  region = (global_options[:region].split(', ') if global_options[:region]) || 'us-east-1'
13
8
  no_selection = options.values.uniq == [false]
14
9
  output("EC2Instance", region) if options[:ec2] || no_selection
@@ -20,16 +15,16 @@ module SportNginAwsAuditor
20
15
  klass = SportNginAwsAuditor.const_get(class_type)
21
16
 
22
17
  if class_type == "EC2Instance"
23
- client = EC2Wrapper.ec2(region)
18
+ client = AWS.ec2(region)
24
19
  elsif class_type == "RDSInstance"
25
- client = RDSWrapper.rds(region)
20
+ client = AWS.rds(region)
26
21
  elsif class_type == "CacheInstance"
27
- client = CacheWrapper.cache(region)
22
+ client = AWS.cache(region)
28
23
  end
29
24
 
30
25
  print "Gathering info, please wait..."; print "\r"
31
26
  instances = class_type == "EC2Instance" ? klass.bucketize(client) : klass.instance_hash(client)
32
- say "<%= color('#{header(class_type)}', :white) %>"
27
+ Output.say "<%= color('#{header(class_type)}', :white) %>"
33
28
  instances.each do |key, value|
34
29
  pretty_print(key, klass.instance_count_hash(Array(value)))
35
30
  end
@@ -49,7 +44,7 @@ module SportNginAwsAuditor
49
44
  puts "======================================="
50
45
  puts "#{title}"
51
46
  puts "======================================="
52
- body.each{ |key, value| say "<%= color('#{key}: #{value[:count]}', :white) %>" }
47
+ body.each{ |key, value| Output.say "<%= color('#{key}: #{value[:count]}', :white) %>" }
53
48
  puts "\n"
54
49
  end
55
50
  end
@@ -1,3 +1,3 @@
1
1
  module SportNginAwsAuditor
2
- VERSION = "4.1.0"
2
+ VERSION = "4.2.0"
3
3
  end
@@ -1,14 +1,18 @@
1
- require_relative 'sport_ngin_aws_auditor/version'
2
- require_relative 'sport_ngin_aws_auditor/convenience_wrappers'
3
- require_relative 'sport_ngin_aws_auditor/ec2_instance'
4
- require_relative 'sport_ngin_aws_auditor/rds_instance'
5
- require_relative 'sport_ngin_aws_auditor/cache_instance'
6
- require_relative 'sport_ngin_aws_auditor/instance'
7
- require_relative 'sport_ngin_aws_auditor/stack'
8
- require_relative 'sport_ngin_aws_auditor/google_sheet'
9
- require_relative 'sport_ngin_aws_auditor/output'
10
- require_relative 'sport_ngin_aws_auditor/config'
11
- require_relative 'sport_ngin_aws_auditor/notify_slack'
1
+ require 'sport_ngin_aws_auditor/audit_data'
2
+ require 'sport_ngin_aws_auditor/aws'
3
+ require 'sport_ngin_aws_auditor/cache_instance'
4
+ require 'sport_ngin_aws_auditor/config'
5
+ require 'sport_ngin_aws_auditor/convenience_wrappers'
6
+ require 'sport_ngin_aws_auditor/ec2_instance'
7
+ require 'sport_ngin_aws_auditor/google'
8
+ require 'sport_ngin_aws_auditor/google_sheet'
9
+ require 'sport_ngin_aws_auditor/instance'
10
+ require 'sport_ngin_aws_auditor/instance_helper'
11
+ require 'sport_ngin_aws_auditor/notify_slack'
12
+ require 'sport_ngin_aws_auditor/output'
13
+ require 'sport_ngin_aws_auditor/rds_instance'
14
+ require 'sport_ngin_aws_auditor/recently_retired_tag'
15
+ require 'sport_ngin_aws_auditor/version'
12
16
 
13
17
  module SportNginAwsAuditor
14
18
 
@@ -24,6 +24,7 @@ module SportNginAwsAuditor
24
24
  'instance2' => 1})
25
25
  allow(SportNginAwsAuditor::EC2Instance).to receive(:get_recent_retired_reserved_instances).and_return(@retired_ris)
26
26
  allow(Instance).to receive(:new).and_return(@instance)
27
+ allow(SportNginAwsAuditor::AWS).to receive(:client_options).and_return(region: 'us-east-1', credentials: {})
27
28
  end
28
29
 
29
30
  context '#initialization' do
@@ -1,29 +1,34 @@
1
1
  require "sport_ngin_aws_auditor"
2
2
 
3
3
  module SportNginAwsAuditor
4
- describe AWSSDK do
5
- context 'without mfa without roles' do
4
+ describe AWS do
5
+ before do
6
+ AWS.reset
7
+ end
8
+
9
+ context 'shared credentials file without mfa' do
6
10
  before :each do
7
11
  mfa_devices = double('mfa_devices', mfa_devices: [])
8
12
  iam_client = double('iam_client', list_mfa_devices: mfa_devices)
9
13
  allow(Aws::IAM::Client).to receive(:new).and_return(iam_client)
14
+ AWS.configure('staging', {})
10
15
  end
11
16
 
12
17
  it "should receive new Aws::SharedCredentials" do
13
- expect(Aws::SharedCredentials).to receive(:new).with(profile_name: 'staging')
14
- AWSSDK::authenticate_with_iam('staging')
18
+ expect(Aws::SharedCredentials).to receive(:new).with(profile_name: 'staging').and_call_original
19
+ AWS.auth_with_iam
15
20
  end
16
21
 
17
- it "should update configs" do
22
+ it "should set credentials" do
18
23
  coffee_types = {:coffee => "cappuccino", :beans => "arabica"}
19
24
  allow(Aws::SharedCredentials).to receive(:new).and_return(coffee_types)
20
- expect(Aws.config).to receive(:update).with({region: 'us-east-1', credentials: coffee_types})
21
- AWSSDK::authenticate_with_iam('staging')
25
+ AWS.auth_with_iam
26
+ expect(AWS.credentials).to_not be_nil
22
27
  end
23
28
  end
24
29
 
25
- context 'with mfa without roles' do
26
- it "should use MFA if it should" do
30
+ context 'shared credentials file with mfa' do
31
+ it "should use MFA when user has device configured" do
27
32
  shared_credentials = double('shared_credentials', access_key_id: 'access_key_id',
28
33
  secret_access_key: 'secret_access_key')
29
34
  shared_creds = double('shared_creds', credentials: shared_credentials)
@@ -41,18 +46,20 @@ module SportNginAwsAuditor
41
46
 
42
47
  expect(Aws::Credentials).to receive(:new).and_return(cred_double).at_least(:once)
43
48
  expect(Aws::SharedCredentials).to receive(:new).and_return(shared_creds)
44
- AWSSDK::authenticate_with_iam('staging')
49
+ AWS.auth_with_iam
45
50
  end
46
51
  end
47
52
 
48
- context 'without mfa with roles' do
49
- it "should update configs" do
50
- expect(Aws.config).to receive(:update).with({region: 'us-east-1'})
51
- AWSSDK::update_aws_config({region: 'us-east-1'})
53
+ context "using AWS server role" do
54
+ it "should configure SDK integration and return client" do
55
+ AWS.configure('staging', aws_roles: true)
56
+ expect(AWS.environment).to eq('staging')
57
+ expect(AWS.credentials).to be_nil
58
+ expect(AWS.ec2).to_not be_nil
52
59
  end
53
60
  end
54
61
 
55
- context 'without mfa with multiple accounts' do
62
+ context 'using cross account assumed roles' do
56
63
  before :each do
57
64
  cred_double = double('cred_hash', access_key_id: 'access_key_id',
58
65
  secret_access_key: 'secret_access_key',
@@ -63,14 +70,9 @@ module SportNginAwsAuditor
63
70
  allow(Aws::AssumeRoleCredentials).to receive(:new).and_return(cred_double)
64
71
  end
65
72
 
66
- it "should update config" do
67
- expect(Aws.config).to receive(:update)
68
- AWSSDK::authenticate_with_assumed_roles('staging', '999999999999', 'CrossAccountAuditorAccess', @sts)
69
- end
70
-
71
- it "should call for some credentials" do
72
- expect(Aws::AssumeRoleCredentials).to receive(:new)
73
- AWSSDK::authenticate_with_assumed_roles('staging', '999999999999', 'CrossAccountAuditorAccess', @sts)
73
+ it "should set credentials" do
74
+ AWS.auth_with_assumed_roles('999999999999', 'CrossAccountAuditorAccess')
75
+ expect(AWS.credentials).to_not be_nil
74
76
  end
75
77
  end
76
78
  end
@@ -8,6 +8,7 @@ module SportNginAwsAuditor
8
8
  client = double('client', get_caller_identity: identity)
9
9
  allow(Aws::STS::Client).to receive(:new).and_return(client)
10
10
  # @client = Aws::ElastiCache::Client.new(region: 'us-east-1')
11
+ allow(SportNginAwsAuditor::AWS).to receive(:client_options).and_return(region: 'us-east-1', credentials: {})
11
12
  end
12
13
 
13
14
  after :each do
@@ -7,6 +7,7 @@ module SportNginAwsAuditor
7
7
  identity = double('identity', account: 123456789)
8
8
  client = double('client', get_caller_identity: identity)
9
9
  allow(Aws::STS::Client).to receive(:new).and_return(client)
10
+ allow(SportNginAwsAuditor::AWS).to receive(:client_options).and_return(region: 'us-east-1', credentials: {})
10
11
  end
11
12
 
12
13
  after :each do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sport_ngin_aws_auditor
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.0
4
+ version: 4.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elliot Hursh
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2017-03-01 00:00:00.000000000 Z
13
+ date: 2017-03-07 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: aws-sdk
@@ -238,7 +238,6 @@ files:
238
238
  - lib/sport_ngin_aws_auditor/scripts/audit.rb
239
239
  - lib/sport_ngin_aws_auditor/scripts/export.rb
240
240
  - lib/sport_ngin_aws_auditor/scripts/inspect.rb
241
- - lib/sport_ngin_aws_auditor/stack.rb
242
241
  - lib/sport_ngin_aws_auditor/version.rb
243
242
  - spec/spec_helper.rb
244
243
  - spec/sport_ngin_aws_auditor/audit_data_spec.rb
@@ -1,63 +0,0 @@
1
- require 'highline/import'
2
-
3
- module SportNginAwsAuditor
4
- class Stack
5
- extend OpsWorksWrapper
6
- extend EC2Wrapper
7
-
8
- class << self
9
- attr_accessor :instances, :stacks
10
- end
11
-
12
- attr_accessor :id, :name, :instances
13
- def initialize(aws_stack)
14
- @id = aws_stack[:stack_id]
15
- @name = aws_stack[:name]
16
- @instances = get_instances.compact
17
- end
18
-
19
- def get_instances
20
- return @instances if @instances
21
- @instances = self.class.opsworks.describe_instances({stack_id: id})[:instances].map do |instance|
22
- next unless instance[:status].to_s == 'online'
23
- self.class.all_instances[instance[:ec2_instance_id]].stack_id = id
24
- self.class.all_instances[instance[:ec2_instance_id]]
25
- end
26
- end
27
-
28
- def print_instances
29
- EC2Instance.instance_count_hash(self.instances).each do |key,value|
30
- say "<%= color('#{key}: #{value}', :white) %>"
31
- end
32
- end
33
-
34
- def pretty_print
35
- puts "----------------------------------"
36
- puts "#{@name}"
37
- puts "----------------------------------"
38
- print_instances
39
- puts "\n"
40
- end
41
-
42
- def self.all
43
- return @stacks if @stacks
44
- @stacks = opsworks.describe_stacks.data[:stacks].map do |stack|
45
- new(stack)
46
- end.sort! { |a,b| a.name.downcase <=> b.name.downcase }
47
- end
48
-
49
- def self.all_instances
50
- @all_instances ||= EC2Instance.instance_hash
51
- end
52
-
53
- def self.instances_without_stack
54
- all #simply getting all stacks to make sure instance stack_ids is set
55
- all_instances.map do |id, instance|
56
- next if instance.stack_id
57
- instance
58
- end.compact
59
- end
60
-
61
- end
62
- end
63
-