aws_account_utils 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'aws_account_utils/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "aws_account_utils"
8
+ spec.version = AwsAccountUtils::VERSION
9
+ spec.authors = ["keviny22"]
10
+ spec.email = ["kevin_young@intuit.com"]
11
+
12
+ spec.summary = %q{A set of helper methods for configuring aspects of AWS that do not have an API.}
13
+ spec.description = %q{A set of helper methods that are webdriven.}
14
+ spec.homepage = "https://github.com/intuit/aws_account_utils"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.9'
22
+ spec.add_development_dependency 'webmock', '~> 1.21', '>= 1.21.0'
23
+ spec.add_development_dependency 'guard-rspec', '~> 4.3', '>= 4.3.1'
24
+ spec.add_development_dependency 'simplecov', '~> 0.8', '>= 0.8.2'
25
+ spec.add_development_dependency 'fakefs', '~> 0.6', '>= 0.6.7'
26
+ spec.add_runtime_dependency 'rake', '~> 10.3.2', '~> 10.0'
27
+ spec.add_runtime_dependency 'watir-webdriver', '~> 0.8', '>= 0.8.0'
28
+ spec.add_runtime_dependency 'random-word', '~> 1.3', '>= 1.3.0'
29
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "aws_account_utils"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,200 @@
1
+ require 'aws_account_utils/base'
2
+ require 'aws_account_utils/version'
3
+ require 'aws_account_utils/account_logger'
4
+ require 'aws_account_utils/watir_browser'
5
+ require 'aws_account_utils/account_registration'
6
+ require 'aws_account_utils/customer_information'
7
+ require 'aws_account_utils/settings'
8
+ require 'aws_account_utils/iam_billing'
9
+ require 'aws_account_utils/email_preferences'
10
+ require 'aws_account_utils/enterprise_support'
11
+ require 'aws_account_utils/consolidated_billing'
12
+ require 'aws_account_utils/root_access_keys'
13
+ require 'aws_account_utils/password'
14
+ require 'aws_account_utils/alternate_contacts'
15
+ require 'aws_account_utils/logout'
16
+
17
+ module AwsAccountUtils
18
+ class AwsAccountUtils
19
+ attr_reader :options, :logger, :browser, :screenshots
20
+
21
+ def initialize(logger: nil, browser: nil, screenshots: nil)
22
+ @browser = browser
23
+ @logger = logger
24
+ @screenshots = screenshots
25
+
26
+ Settings.set_screenshot_dir screenshots if screenshots
27
+ end
28
+
29
+ def create_account(account_name:, account_email:, account_password:, account_details:)
30
+ raise ArgumentError, "account_detials: must be a hash." unless account_details.is_a?(Hash)
31
+ account_registration.signup account_name, account_email, account_password
32
+ resp = customer_information.submit account_email, account_password, account_details
33
+ logger.info 'Successfully created account.' if resp
34
+ resp
35
+ ensure
36
+ browser.close rescue nil
37
+ end
38
+
39
+ def check_enterprise_support(account_email:, account_password:)
40
+ resp = enterprise_support.existing_support? account_email, account_password
41
+ logger.info 'Enterprise support was already enabled' if resp
42
+ resp
43
+ ensure
44
+ browser.close rescue nil
45
+ end
46
+
47
+ def change_root_password(account_email:, account_password:, new_password:)
48
+ resp = password.change(account_email, account_password, new_password)
49
+ logger.info 'Changed root password.' if resp
50
+ resp
51
+ ensure
52
+ browser.close rescue nil
53
+ end
54
+
55
+ def confirm_consolidated_billing(account_email:, account_password:, confirmation_link:)
56
+ resp = consolidated_billing.confirm account_email, account_password, confirmation_link
57
+ logger.info 'Consolidated billing has been confirmed' if resp
58
+ resp
59
+ ensure
60
+ browser.close rescue nil
61
+ end
62
+
63
+ def create_root_access_keys(account_email:, account_password:)
64
+ resp = root_access_keys.create account_email, account_password
65
+ logger.info 'Created root access keys.' if resp
66
+ resp
67
+ ensure
68
+ browser.close rescue nil
69
+ end
70
+
71
+ def delete_root_access_keys(account_email:, account_password:)
72
+ resp = root_access_keys.delete account_email, account_password
73
+ logger.info 'Deleted all root access keys.' if resp
74
+ resp
75
+ ensure
76
+ browser.close rescue nil
77
+ end
78
+
79
+ def email_opt_out(account_email:, account_password:)
80
+ resp = email_preferences.opt_out account_email, account_password
81
+ logger.info 'Successfully opted out of all emails' if resp
82
+ resp
83
+ ensure
84
+ browser.close rescue nil
85
+ end
86
+
87
+ def enable_enterprise_support(account_email:, account_password:)
88
+ resp = enterprise_support.enable account_email, account_password
89
+ logger.info 'Enabled enterprise support' if resp
90
+ resp
91
+ ensure
92
+ browser.close rescue nil
93
+ end
94
+
95
+ def enable_iam_billing(account_email:, account_password:)
96
+ resp = iam_billing.enable account_email, account_password
97
+ logger.info 'Successfully enabled IAM billing' if resp
98
+ resp
99
+ ensure
100
+ browser.close rescue nil
101
+ end
102
+
103
+ def existing_consolidated_billing?(account_email:, account_password:)
104
+ resp = consolidated_billing.existing? account_email, account_password
105
+ logger.info 'Consolidated billing has already been setup' if resp
106
+ resp
107
+ ensure
108
+ browser.close rescue nil
109
+ end
110
+
111
+ def logout_from_console
112
+ resp = logout.execute
113
+ logger.info 'Logged out of console' if resp
114
+ resp
115
+ ensure
116
+ browser.close rescue nil
117
+ end
118
+
119
+ def request_consolidated_billing(master_account_email:, master_account_password:, account_email:)
120
+ resp = consolidated_billing.request master_account_email, master_account_password, account_email
121
+ logger.info 'Consolidated billing has been requested' if resp
122
+ resp
123
+ ensure
124
+ browser.close rescue nil
125
+ end
126
+
127
+ def set_challenge_questions(account_email:, account_password:, answers:)
128
+ raise ArgumentError, "answers: must be a hash." unless answers.is_a?(Hash)
129
+
130
+ resp = challenge_questions.create account_email, account_password, answers
131
+ logger.info 'Security Challenge Questions have been setup' if resp
132
+ resp
133
+ ensure
134
+ browser.close rescue nil
135
+ end
136
+
137
+ def set_alternate_contacts(account_email:, account_password:, contact_info:)
138
+ raise ArgumentError, "contact_info: must be a hash." unless contact_info.is_a?(Hash)
139
+
140
+ resp = alternate_contacts.set account_email, account_password, contact_info
141
+ logger.info 'Set alterante contacts.' if resp
142
+ resp
143
+ ensure
144
+ browser.close rescue nil
145
+ end
146
+
147
+ private
148
+ def account_registration
149
+ @account_registration ||= AccountRegistration.new logger, browser
150
+ end
151
+
152
+ def alternate_contacts
153
+ @alternate_contacts ||= AlternateContacts.new logger, browser
154
+ end
155
+
156
+ def browser
157
+ @browser ||= WatirBrowser.new(logger).create
158
+ end
159
+
160
+ def challenge_questions
161
+ @challenge_questions ||= ChallengeQuestions.new logger, browser
162
+ end
163
+
164
+ def consolidated_billing
165
+ @consolidated_billing ||= ConsolidatedBilling.new logger, browser
166
+ end
167
+
168
+ def customer_information
169
+ @customer_information ||= CustomerInformation.new logger, browser
170
+ end
171
+
172
+ def email_preferences
173
+ @email_preferences ||= EmailPreferences.new logger, browser
174
+ end
175
+
176
+ def enterprise_support
177
+ @enterprise_support ||= EnterpriseSupport.new logger, browser
178
+ end
179
+
180
+ def iam_billing
181
+ @iam_billing ||= IamBilling.new logger, browser
182
+ end
183
+
184
+ def logger
185
+ @logger ||= AccountLogger.new(options[:log_level])
186
+ end
187
+
188
+ def password
189
+ @password ||= Password.new logger, browser
190
+ end
191
+
192
+ def root_access_keys
193
+ @root_access_keys ||= RootAccessKeys.new logger, browser
194
+ end
195
+
196
+ def logout
197
+ @logout ||= Logout.new logger, browser
198
+ end
199
+ end
200
+ end
@@ -0,0 +1,26 @@
1
+ require 'logger'
2
+ require 'forwardable'
3
+
4
+ module AwsAccountUtils
5
+ class AccountLogger
6
+ extend Forwardable
7
+ def_delegators :@logger, :fatal, :debug, :error, :info, :warn, :debug?
8
+
9
+ def initialize(log_level = 'info')
10
+ @log_level = log_level
11
+ @logger = new_logger
12
+ end
13
+
14
+ private
15
+ def new_logger
16
+ STDOUT.sync = true
17
+ Logger.new(STDOUT).tap do |l|
18
+ l.datetime_format = '%Y-%m-%dT%H:%M:%S%z'
19
+ l.formatter = proc do |severity, datetime, progname, msg|
20
+ "#{datetime} #{severity} : #{msg}\n"
21
+ end
22
+ l.level = Logger.const_get @log_level.upcase
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,52 @@
1
+ require 'aws_account_utils/base'
2
+
3
+ module AwsAccountUtils
4
+ class AccountRegistration < Base
5
+ attr_reader :logger, :browser
6
+
7
+ def initialize(logger, browser)
8
+ @logger = logger
9
+ @browser = browser
10
+ end
11
+
12
+ def signup(account_name, account_email, account_password)
13
+ logger.debug "Signing up for a new account."
14
+ login_details = { 'ap_customer_name' => account_name,
15
+ 'ap_email' => account_email,
16
+ 'ap_email_check' => account_email,
17
+ 'ap_password' => account_password,
18
+ 'ap_password_check' => account_password }
19
+
20
+ browser.goto signup_url
21
+ browser.text_field(:id => 'ap_customer_name').wait_until_present
22
+ screenshot(browser, "1")
23
+ login_details.each do |k,v|
24
+ browser.text_field(:id => k).when_present.set v
25
+ end
26
+ screenshot(browser, "2")
27
+ browser.button(:id => 'continue-input').when_present.click
28
+ raise StandardError if browser.div(:id => /message_(error|warning)/).exist?
29
+ true
30
+ rescue StandardError
31
+ screenshot(browser, "error")
32
+ error_header = browser.div(:id => /message_(error|warning)/).h6.text
33
+ error_body = browser.div(:id => /message_(error|warning)/).p.text
34
+ raise StandardError, "AWS signup error: \"#{error_header}: #{error_body}\""
35
+
36
+ rescue Watir::Wait::TimeoutError, Net::ReadTimeout => e
37
+ screenshot(browser, "error")
38
+ raise StandardError, "#{self.class.name} - #{e}"
39
+ end
40
+
41
+ private
42
+ def signup_url
43
+ url = "https://www.amazon.com/ap/register?"
44
+ url << "&openid.claimed_id=http://specs.openid.net/auth/2.0/identifier_select"
45
+ url << "&create=1&openid.assoc_handle=aws&accountStatusPolicy=P1"
46
+ url << "&openid.ns=http://specs.openid.net/auth/2.0"
47
+ url << "&openid.identity=http://specs.openid.net/auth/2.0/identifier_select"
48
+ url << "&openid.mode=checkid_setup"
49
+ url << "&openid.return_to=https://console.aws.amazon.com/billing/signup"
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,42 @@
1
+ require 'aws_account_utils/base'
2
+
3
+ module AwsAccountUtils
4
+ class AlternateContacts < Base
5
+ attr_reader :logger, :browser
6
+
7
+ def initialize(logger, browser)
8
+ @logger = logger
9
+ @browser = browser
10
+ end
11
+
12
+ def set(account_email, account_password, contact_info = {})
13
+ logger.debug "Setting alternate account contacts."
14
+ Login.new(logger, browser).execute url,
15
+ account_email,
16
+ account_password
17
+ browser.a(:xpath => '//a[@ng-click="toggleEditingAlternateContactsInfoState()"]').when_present.click
18
+ form_inputs(contact_info)
19
+ screenshot(browser, "1")
20
+ browser.button(:xpath => '//button[@ng-click="updateAlternateContacts()"]').when_present.click
21
+ browser.div(:xpath => '//div[@ng-show="options.status == \'success\'"]').wait_until_present
22
+ true
23
+ rescue Watir::Wait::TimeoutError, Net::ReadTimeout => e
24
+ screenshot(browser, "error")
25
+ raise StandardError, "#{self.class.name} - #{e}"
26
+ end
27
+
28
+ private
29
+ def form_inputs(requestor_info)
30
+ requestor_info.each do |type, details|
31
+ details.each do |key, value|
32
+ browser.input(:xpath => "//input[@ng-model=\"alternateContacts.#{type}Contact.#{key}\"]").to_subtype.when_present.set value
33
+ end
34
+ end
35
+ end
36
+
37
+ def url
38
+ 'https://console.aws.amazon.com/billing/home?#/account'
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,26 @@
1
+ module AwsAccountUtils
2
+ class Base
3
+
4
+ def screenshot(browser, file)
5
+ return unless Settings.screenshot_dir
6
+ calling_method = /(?<=`)(.*)(?=')/.match(caller.first).to_s.gsub(" ",'-')
7
+ calling_class = self.class.to_s.gsub("::",'_')
8
+ browser.screenshot.save screenshot_file(file, calling_class, calling_method)
9
+ end
10
+
11
+ private
12
+ def increment(path)
13
+ _, filename, count, extension = *path.match(/(\A.*?)(?:_#(\d+))?(\.[^.]*)?\Z/)
14
+ count = (count || '0').to_i + 1
15
+ "#{filename}_##{count}#{extension}"
16
+ end
17
+
18
+ def screenshot_file(file, calling_class, calling_method)
19
+ file_path = File.join Settings.screenshot_dir, "#{calling_class}_#{calling_method}_#{file}_#1.png"
20
+ File.exists?(file_path) ? increment(file_path) : file_path
21
+ end
22
+
23
+ end
24
+ end
25
+
26
+
@@ -0,0 +1,49 @@
1
+ require 'aws_account_utils/base'
2
+ require 'random-word'
3
+
4
+ module AwsAccountUtils
5
+ class ChallengeQuestions < Base
6
+ attr_reader :logger, :browser
7
+
8
+ def initialize(logger, browser)
9
+ @logger = logger
10
+ @browser = browser
11
+ end
12
+
13
+ def create(account_email, account_password, challenge_words = {})
14
+ logger.debug "Entering customer details."
15
+ Login.new(logger, browser).execute url,
16
+ account_email,
17
+ account_password
18
+
19
+ browser.a(:xpath => '//a[@ng-click="toggleEditingSecurityQuestionsInfoState()"]').when_present.click
20
+
21
+ challenge_words.each do |num, word|
22
+ browser.input(:xpath => "//input[@ng-model=\"selectedSecurityQuestions.question#{num}.answer\"]").to_subtype.when_present.set word
23
+ end
24
+
25
+ screenshot(browser, "1")
26
+ browser.button(:xpath => '//button[@ng-click="updateSecurityQuestions()"]').when_present.click
27
+ browser.a(:xpath => '//a[@ng-click="toggleEditingSecurityQuestionsInfoState()"]').wait_until_present
28
+ challenge_words
29
+ rescue Watir::Wait::TimeoutError, Net::ReadTimeout => e
30
+ screenshot(browser, "error")
31
+ raise StandardError, "#{self.class.name} - #{e}"
32
+ end
33
+
34
+ private
35
+ def challenge_words
36
+ RandomWord.exclude_list << (/_/) if RandomWord.exclude_list.none?
37
+
38
+ @challenge_words ||= (1..3).inject({}) do |hash, num|
39
+ hash[num] = RandomWord.nouns.next
40
+ hash
41
+ end
42
+ end
43
+
44
+ def url
45
+ 'https://portal.aws.amazon.com/gp/aws/manageYourAccount'
46
+ end
47
+
48
+ end
49
+ end