speculate 0.0.1 → 0.0.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 34c067c32dad1620b96437cf3daceb9161be8c16
4
- data.tar.gz: 89bba6d1e2a5e77dcfbeef174ddca5ebc427ebec
3
+ metadata.gz: 4c4246f0306b5f4623c563247067fa0a81314d19
4
+ data.tar.gz: 3224578dc4726ac6658de9484838b0b9716126c7
5
5
  SHA512:
6
- metadata.gz: d0450bb9b0c9ab16eb8075adbb508b6424eb6a1412c835df57f30103fc5ee1258dca7ca4ce3f84b7619b672d0410116aaa1e83057efb1dacd1ecd8786ba1b59c
7
- data.tar.gz: 42cda06e782a40816c533c5eb032ca19a87d7df0026b139a344fc8cb60515bcd08fe7443e14560662b1b36b039b26ea58e1bc16e611312d3dfc795f49984fb35
6
+ metadata.gz: 145a15fb717abbf5be7b0642ff18447fe32a80875fd9aa022c39f01341e060de69eed5a509cf4ff23757140cccacc26df058c94e41038c10198d8872071a5bef
7
+ data.tar.gz: 8faaceb19e5d1e64121a3a3daf5e0b055910c55f77cb1959670c3d7d0f95682e15fa61de4f52b38c711a340c1d653b3b52e7036cfbc4e59ab48fd2bf72810e87
data/.circle-ruby CHANGED
@@ -1,3 +1,4 @@
1
- 2.3.1
2
- 2.2.5
1
+ 2.4.0
2
+ 2.3.3
3
+ 2.2.6
3
4
  2.1.10
data/README.md CHANGED
@@ -5,7 +5,7 @@ speculate
5
5
  [![Dependency Status](https://img.shields.io/gemnasium/akerl/speculate.svg)](https://gemnasium.com/akerl/speculate)
6
6
  [![Build Status](https://img.shields.io/circleci/project/akerl/speculate.svg)](https://circleci.com/gh/akerl/speculate)
7
7
  [![Coverage Status](https://img.shields.io/codecov/c/github/akerl/speculate.svg)](https://codecov.io/github/akerl/speculate)
8
- [![Code Quality](https://img.shields.io/codacy/.svg)](https://www.codacy.com/app/akerl/speculate)
8
+ [![Code Quality](https://img.shields.io/codacy/1a0888d1510f4e39b62db9c8699c4946.svg)](https://www.codacy.com/app/akerl/speculate)
9
9
  [![MIT Licensed](https://img.shields.io/badge/license-MIT-green.svg)](https://tldrlegal.com/license/mit-license)
10
10
 
11
11
  Tool for assuming roles in AWS accounts
data/Rakefile CHANGED
@@ -7,7 +7,7 @@ RSpec::Core::RakeTask.new(:spec)
7
7
 
8
8
  desc 'Run Rubocop on the gem'
9
9
  RuboCop::RakeTask.new(:rubocop) do |task|
10
- task.patterns = ['lib/**/*.rb', 'spec/**/*.rb']
10
+ task.patterns = ['lib/**/*.rb', 'spec/**/*.rb', 'bin/*']
11
11
  task.fail_on_error = true
12
12
  end
13
13
 
data/bin/speculate CHANGED
@@ -1,20 +1,38 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'speculate'
4
+ require 'userinput'
4
5
  require 'mercenary'
5
6
 
6
- # rubocop:disable Metrics/BlockLength
7
+ MFA_ASKER = UserInput.new(validation: /\d{6}/, message: 'MFA code')
8
+
7
9
  Mercenary.program(:speculate) do |p|
8
10
  p.version Speculate::VERSION
9
11
  p.description 'Tool for assuming roles in AWS accounts'
10
- p.syntax 'speculate [options] account-id role-name'
12
+ p.syntax 'speculate [options] role-name'
13
+
14
+ # rubocop:disable Metrics/LineLength
15
+ p.option :account_id, '-a ACCOUNT_ID', '--accountid ACCOUNT_ID', 'Account ID to assume role on'
16
+ p.option :browser, '-b', '--browser', 'Open console URL in browser'
17
+ p.option :logout, '-l', '--logout', 'Log out of existing console browser session first'
18
+ p.option :mfa, '-m [TOKEN]', '--mfa [TOKEN]', 'Use MFA when assuming role'
19
+ # rubocop:enable Metrics/LineLength
11
20
 
12
21
  p.action do |_, options|
13
- account_id, role_name = ARGV.shift 2
14
- if !account_id || !role_name
22
+ options[:role_name] = ARGV.shift
23
+ unless options[:role_name]
15
24
  puts p
16
25
  exit 1
17
26
  end
18
- Speculate.new(account_id: account_id, role_name: role_name).print!
27
+ options[:mfa] = MFA_ASKER.ask if options.fetch(:mfa, 0).nil?
28
+ session = Speculate.new(options)
29
+ puts session.to_envvars, "\n# #{session.url}"
30
+ if options[:browser]
31
+ if options[:logout]
32
+ system('open', session.logout_url)
33
+ sleep 1
34
+ end
35
+ system('open', session.url)
36
+ end
19
37
  end
20
38
  end
data/circle.yml CHANGED
@@ -1,5 +1,6 @@
1
1
  dependencies:
2
2
  override:
3
+ - 'for i in $(cat .circle-ruby) ; do rvm-exec $i gem update --system --no-doc || exit 1 ; done'
3
4
  - 'for i in $(cat .circle-ruby) ; do rvm-exec $i bundle install || exit 1 ; done'
4
5
  test:
5
6
  override:
data/lib/speculate.rb CHANGED
@@ -1,5 +1,3 @@
1
- require 'aws-sdk'
2
-
3
1
  ##
4
2
  # Base module for Speculate
5
3
  module Speculate
@@ -14,4 +12,6 @@ module Speculate
14
12
  end
15
13
 
16
14
  require 'speculate/version'
15
+ require 'speculate/formatters'
16
+ require 'speculate/console'
17
17
  require 'speculate/assumption'
@@ -1,6 +1,88 @@
1
- ##
2
- # Base class for assumptions
1
+ require 'aws-sdk'
2
+
3
3
  module Speculate
4
+ ##
5
+ # Base class for assumptions
4
6
  class Assumption
7
+ include Speculate::Formatters
8
+
9
+ def initialize(params = {})
10
+ @options = params
11
+ end
12
+
13
+ def creds
14
+ @creds ||= assumed_role.credentials
15
+ end
16
+
17
+ def url
18
+ @url ||= console.url
19
+ end
20
+
21
+ def logout_url
22
+ @logout_url ||= console.logout_url
23
+ end
24
+
25
+ private
26
+
27
+ def assumed_role
28
+ @assumed_role ||= client.assume_role(
29
+ role_arn: role_arn,
30
+ role_session_name: role_session_name,
31
+ **mfa_args
32
+ )
33
+ end
34
+
35
+ def client
36
+ @client ||= Aws::STS::Client.new(local_config)
37
+ end
38
+
39
+ def console
40
+ @console ||= Speculate::Console.new(creds: creds)
41
+ end
42
+
43
+ def mfa
44
+ @mfa ||= @options[:mfa]
45
+ end
46
+
47
+ def mfa_device
48
+ @mfa_device ||= local_identity.arn.sub('user/', 'mfa/')
49
+ end
50
+
51
+ def mfa_args
52
+ return {} unless mfa
53
+ { serial_number: mfa_device, token_code: mfa }
54
+ end
55
+
56
+ def role_name
57
+ @role ||= @options[:role_name] || raise('No role_name supplied')
58
+ end
59
+
60
+ def role_arn
61
+ @role_arn ||= "arn:aws:iam::#{target_account_id}:role/#{role_name}"
62
+ end
63
+
64
+ def role_session_name
65
+ @role_session_name ||= local_user_name
66
+ end
67
+
68
+ def target_account_id
69
+ @target_account_id ||= @options[:account_id] || local_account_id
70
+ end
71
+
72
+ def local_account_id
73
+ @local_account_id ||= local_identity.account
74
+ end
75
+
76
+ def local_user_name
77
+ @local_user_name ||= local_identity.arn.split(':').last.tr('/', '_')
78
+ end
79
+
80
+ def local_identity
81
+ @local_identity ||= client.get_caller_identity
82
+ end
83
+
84
+ def local_config
85
+ @local_config ||= @options[:creds] || {}
86
+ end
5
87
  end
6
88
  end
@@ -0,0 +1,52 @@
1
+ require 'cgi'
2
+ require 'open-uri'
3
+ require 'json'
4
+
5
+ module Speculate
6
+ ##
7
+ # Define console URL class
8
+ class Console
9
+ def initialize(params = {})
10
+ @options = params
11
+ end
12
+
13
+ def url
14
+ @url ||= [
15
+ 'https://signin.aws.amazon.com/federation',
16
+ '?Action=login',
17
+ '&Issuer=',
18
+ '&Destination=',
19
+ CGI.escape('https://console.aws.amazon.com/'),
20
+ '&SigninToken=',
21
+ signin_token
22
+ ].join
23
+ end
24
+
25
+ def logout_url
26
+ @logout_url ||= 'https://console.aws.amazon.com/ec2/logout!doLogout'.freeze
27
+ end
28
+
29
+ private
30
+
31
+ def signin_token
32
+ @signin_token ||= JSON.parse(open(signin_token_url).read)['SigninToken']
33
+ end
34
+
35
+ def signin_token_url
36
+ @signin_token_url ||= [
37
+ 'https://signin.aws.amazon.com/federation',
38
+ '?Action=getSigninToken',
39
+ '&Session=',
40
+ CGI.escape(signin_token_creds.to_json)
41
+ ].join
42
+ end
43
+
44
+ def signin_token_creds
45
+ @signin_token_creds ||= {
46
+ 'sessionId' => @options[:creds].access_key_id,
47
+ 'sessionKey' => @options[:creds].secret_access_key,
48
+ 'sessionToken' => @options[:creds].session_token
49
+ }
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,14 @@
1
+ module Speculate
2
+ ##
3
+ # Formatter module for printing creds to terminal
4
+ module Formatters
5
+ def to_envvars
6
+ @to_envvars ||= {
7
+ AWS_ACCESS_KEY_ID: creds.access_key_id,
8
+ AWS_SECRET_ACCESS_KEY: creds.secret_access_key,
9
+ AWS_SECURITY_TOKEN: creds.session_token,
10
+ AWS_SESSION_TOKEN: creds.session_token
11
+ }.map { |k, v| "export #{k}=#{v}" }.join("\n")
12
+ end
13
+ end
14
+ end
@@ -1,5 +1,5 @@
1
1
  ##
2
2
  # Set version for module
3
3
  module Speculate
4
- VERSION = '0.0.0'.freeze
4
+ VERSION = '0.0.3'.freeze
5
5
  end
data/speculate.gemspec CHANGED
@@ -1,6 +1,9 @@
1
+ $:.unshift File.expand_path('../lib/', __FILE__)
2
+ require 'speculate/version'
3
+
1
4
  Gem::Specification.new do |s|
2
5
  s.name = 'speculate'
3
- s.version = '0.0.1'
6
+ s.version = Speculate::VERSION
4
7
  s.date = Time.now.strftime('%Y-%m-%d')
5
8
 
6
9
  s.summary = 'Tool for assuming roles in AWS accounts'
@@ -12,12 +15,15 @@ Gem::Specification.new do |s|
12
15
 
13
16
  s.files = `git ls-files`.split
14
17
  s.test_files = `git ls-files spec/*`.split
18
+ s.executables = ['speculate']
15
19
 
16
- s.add_dependency 'aws-sdk', '~> 2.6.0'
20
+ s.add_dependency 'aws-sdk', '~> 2.8.0'
21
+ s.add_dependency 'mercenary', '~> 0.3.4'
22
+ s.add_dependency 'userinput', '~> 1.0.0'
17
23
 
18
- s.add_development_dependency 'rubocop', '~> 0.42.0'
19
- s.add_development_dependency 'rake', '~> 11.2.0'
24
+ s.add_development_dependency 'rubocop', '~> 0.47.0'
25
+ s.add_development_dependency 'rake', '~> 12.0.0'
20
26
  s.add_development_dependency 'codecov', '~> 0.1.1'
21
27
  s.add_development_dependency 'rspec', '~> 3.5.0'
22
- s.add_development_dependency 'fuubar', '~> 2.1.0'
28
+ s.add_development_dependency 'fuubar', '~> 2.2.0'
23
29
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: speculate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Les Aker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-01 00:00:00.000000000 Z
11
+ date: 2017-03-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk
@@ -16,42 +16,70 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 2.6.0
19
+ version: 2.8.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 2.6.0
26
+ version: 2.8.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: mercenary
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.3.4
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.3.4
41
+ - !ruby/object:Gem::Dependency
42
+ name: userinput
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 1.0.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 1.0.0
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: rubocop
29
57
  requirement: !ruby/object:Gem::Requirement
30
58
  requirements:
31
59
  - - "~>"
32
60
  - !ruby/object:Gem::Version
33
- version: 0.42.0
61
+ version: 0.47.0
34
62
  type: :development
35
63
  prerelease: false
36
64
  version_requirements: !ruby/object:Gem::Requirement
37
65
  requirements:
38
66
  - - "~>"
39
67
  - !ruby/object:Gem::Version
40
- version: 0.42.0
68
+ version: 0.47.0
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: rake
43
71
  requirement: !ruby/object:Gem::Requirement
44
72
  requirements:
45
73
  - - "~>"
46
74
  - !ruby/object:Gem::Version
47
- version: 11.2.0
75
+ version: 12.0.0
48
76
  type: :development
49
77
  prerelease: false
50
78
  version_requirements: !ruby/object:Gem::Requirement
51
79
  requirements:
52
80
  - - "~>"
53
81
  - !ruby/object:Gem::Version
54
- version: 11.2.0
82
+ version: 12.0.0
55
83
  - !ruby/object:Gem::Dependency
56
84
  name: codecov
57
85
  requirement: !ruby/object:Gem::Requirement
@@ -86,17 +114,18 @@ dependencies:
86
114
  requirements:
87
115
  - - "~>"
88
116
  - !ruby/object:Gem::Version
89
- version: 2.1.0
117
+ version: 2.2.0
90
118
  type: :development
91
119
  prerelease: false
92
120
  version_requirements: !ruby/object:Gem::Requirement
93
121
  requirements:
94
122
  - - "~>"
95
123
  - !ruby/object:Gem::Version
96
- version: 2.1.0
124
+ version: 2.2.0
97
125
  description: Tool for assuming roles in AWS accounts
98
126
  email: me@lesaker.org
99
- executables: []
127
+ executables:
128
+ - speculate
100
129
  extensions: []
101
130
  extra_rdoc_files: []
102
131
  files:
@@ -113,6 +142,8 @@ files:
113
142
  - circle.yml
114
143
  - lib/speculate.rb
115
144
  - lib/speculate/assumption.rb
145
+ - lib/speculate/console.rb
146
+ - lib/speculate/formatters.rb
116
147
  - lib/speculate/version.rb
117
148
  - spec/spec_helper.rb
118
149
  - spec/speculate_spec.rb