aws_account_utils 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.codeclimate.yml +50 -0
- data/.gitignore +9 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +4 -0
- data/README.md +415 -0
- data/Rakefile +1 -0
- data/aws_account_utils.gemspec +29 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/lib/aws_account_utils.rb +200 -0
- data/lib/aws_account_utils/account_logger.rb +26 -0
- data/lib/aws_account_utils/account_registration.rb +52 -0
- data/lib/aws_account_utils/alternate_contacts.rb +42 -0
- data/lib/aws_account_utils/base.rb +26 -0
- data/lib/aws_account_utils/challenge_questions.rb +49 -0
- data/lib/aws_account_utils/consolidated_billing.rb +80 -0
- data/lib/aws_account_utils/customer_information.rb +39 -0
- data/lib/aws_account_utils/customize_url.rb +36 -0
- data/lib/aws_account_utils/email_preferences.rb +30 -0
- data/lib/aws_account_utils/enterprise_support.rb +64 -0
- data/lib/aws_account_utils/iam_billing.rb +32 -0
- data/lib/aws_account_utils/login.rb +30 -0
- data/lib/aws_account_utils/logout.rb +29 -0
- data/lib/aws_account_utils/password.rb +53 -0
- data/lib/aws_account_utils/root_access_keys.rb +86 -0
- data/lib/aws_account_utils/settings.rb +10 -0
- data/lib/aws_account_utils/version.rb +3 -0
- data/lib/aws_account_utils/watir_browser.rb +49 -0
- metadata +228 -0
data/Rakefile
ADDED
@@ -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
|
data/bin/console
ADDED
@@ -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
|
data/bin/setup
ADDED
@@ -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
|