aws_assume_role 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +31 -11
  4. data/Gemfile +7 -13
  5. data/LICENSE.md +201 -19
  6. data/README.md +176 -145
  7. data/aws_assume_role.gemspec +35 -21
  8. data/bin/aws-assume-role +1 -83
  9. data/i18n/en.yml +106 -0
  10. data/lib/aws_assume_role.rb +2 -3
  11. data/lib/aws_assume_role/cli.rb +15 -0
  12. data/lib/aws_assume_role/cli/actions/abstract_action.rb +53 -0
  13. data/lib/aws_assume_role/cli/actions/configure_profile.rb +21 -0
  14. data/lib/aws_assume_role/cli/actions/configure_role_assumption.rb +19 -0
  15. data/lib/aws_assume_role/cli/actions/console.rb +68 -0
  16. data/lib/aws_assume_role/cli/actions/delete_profile.rb +20 -0
  17. data/lib/aws_assume_role/cli/actions/includes.rb +18 -0
  18. data/lib/aws_assume_role/cli/actions/list_profiles.rb +10 -0
  19. data/lib/aws_assume_role/cli/actions/migrate_profile.rb +18 -0
  20. data/lib/aws_assume_role/cli/actions/reset_environment.rb +48 -0
  21. data/lib/aws_assume_role/cli/actions/run.rb +34 -0
  22. data/lib/aws_assume_role/cli/actions/set_environment.rb +60 -0
  23. data/lib/aws_assume_role/cli/actions/test.rb +31 -0
  24. data/lib/aws_assume_role/cli/commands/configure.rb +29 -0
  25. data/lib/aws_assume_role/cli/commands/console.rb +17 -0
  26. data/lib/aws_assume_role/cli/commands/delete.rb +11 -0
  27. data/lib/aws_assume_role/cli/commands/environment.rb +32 -0
  28. data/lib/aws_assume_role/cli/commands/list.rb +10 -0
  29. data/lib/aws_assume_role/cli/commands/migrate.rb +11 -0
  30. data/lib/aws_assume_role/cli/commands/run.rb +17 -0
  31. data/lib/aws_assume_role/cli/commands/test.rb +18 -0
  32. data/lib/aws_assume_role/configuration.rb +19 -0
  33. data/lib/aws_assume_role/core_ext/aws-sdk/credential_provider_chain.rb +2 -0
  34. data/lib/aws_assume_role/core_ext/aws-sdk/includes.rb +7 -0
  35. data/lib/aws_assume_role/credentials/factories.rb +9 -0
  36. data/lib/aws_assume_role/credentials/factories/abstract_factory.rb +31 -0
  37. data/lib/aws_assume_role/credentials/factories/assume_role.rb +38 -0
  38. data/lib/aws_assume_role/credentials/factories/default_chain_provider.rb +101 -0
  39. data/lib/aws_assume_role/credentials/factories/environment.rb +24 -0
  40. data/lib/aws_assume_role/credentials/factories/includes.rb +17 -0
  41. data/lib/aws_assume_role/credentials/factories/instance_profile.rb +17 -0
  42. data/lib/aws_assume_role/credentials/factories/repository.rb +35 -0
  43. data/lib/aws_assume_role/credentials/factories/shared.rb +15 -0
  44. data/lib/aws_assume_role/credentials/factories/shared_keyring.rb +16 -0
  45. data/lib/aws_assume_role/credentials/factories/static.rb +16 -0
  46. data/lib/aws_assume_role/credentials/providers/assume_role_credentials.rb +58 -0
  47. data/lib/aws_assume_role/credentials/providers/includes.rb +9 -0
  48. data/lib/aws_assume_role/credentials/providers/mfa_session_credentials.rb +102 -0
  49. data/lib/aws_assume_role/credentials/providers/shared_keyring_credentials.rb +22 -0
  50. data/lib/aws_assume_role/includes.rb +30 -0
  51. data/lib/aws_assume_role/logging.rb +16 -28
  52. data/lib/aws_assume_role/profile_configuration.rb +71 -0
  53. data/lib/aws_assume_role/runner.rb +39 -0
  54. data/lib/aws_assume_role/store/includes.rb +16 -0
  55. data/lib/aws_assume_role/store/keyring.rb +59 -0
  56. data/lib/aws_assume_role/store/serialization.rb +18 -0
  57. data/lib/aws_assume_role/store/shared_config_with_keyring.rb +175 -0
  58. data/lib/aws_assume_role/types.rb +30 -0
  59. data/lib/aws_assume_role/ui.rb +55 -0
  60. data/lib/aws_assume_role/vendored/aws.rb +4 -0
  61. data/lib/aws_assume_role/vendored/aws/README.md +2 -0
  62. data/lib/aws_assume_role/vendored/aws/assume_role_credentials.rb +68 -0
  63. data/lib/aws_assume_role/vendored/aws/includes.rb +9 -0
  64. data/lib/aws_assume_role/vendored/aws/refreshing_credentials.rb +60 -0
  65. data/lib/aws_assume_role/vendored/aws/shared_config.rb +220 -0
  66. data/lib/aws_assume_role/version.rb +3 -0
  67. metadata +264 -20
  68. data/.rspec +0 -2
  69. data/Rakefile +0 -2
  70. data/bin/test.rb +0 -39
  71. data/lib/aws_assume_role/credentials.rb +0 -92
  72. data/lib/aws_assume_role/profile.rb +0 -203
  73. data/lib/aws_assume_role/profile/assume_role.rb +0 -127
  74. data/lib/aws_assume_role/profile/basic.rb +0 -152
  75. data/lib/aws_assume_role/profile/list.rb +0 -57
@@ -1,203 +0,0 @@
1
- require 'keyring'
2
-
3
- module AWSAssumeRole
4
-
5
- # Base Profile superclass
6
- class Profile
7
-
8
- include Logging
9
-
10
- # Class methods for dispatch to individual Profile strategy
11
-
12
- @implementations = {}
13
- @named_profiles = {}
14
- @config_file = '-'
15
-
16
- class << self
17
-
18
- attr_accessor :implementations
19
- attr_accessor :named_profiles
20
- attr_accessor :config_file
21
-
22
- end
23
-
24
- def self.register_implementation(type, impl)
25
- logger.info('Registering implementation ' \
26
- "for type '#{type}': #{impl}")
27
- AWSAssumeRole::Profile.implementations[type] = impl
28
- end
29
-
30
- def self.load_profiles
31
- Dir.glob(
32
- File.expand_path('profile/*.rb', File.dirname(__FILE__)),
33
- ).each do |profile_class|
34
- require profile_class
35
- end
36
- end
37
-
38
- def self.create(name, options)
39
-
40
- options['type'] = 'basic' unless options.key?('type')
41
-
42
- if implementations.key?(options['type'])
43
- logger.info("Creating profile '#{name}' "\
44
- "with type #{options['type']}")
45
- i = implementations[options['type']].new(name, options)
46
- named_profiles[name] = i
47
- return i
48
- end
49
-
50
- STDERR.puts 'No implementation for profiles of type '\
51
- "'#{options['type']}'"
52
- exit -1 # rubocop:disable Lint/AmbiguousOperator
53
-
54
- end
55
-
56
- def self.get_by_name(name)
57
- unless named_profiles.key?(name)
58
- STDERR.puts "No profile '#{name}' found"
59
- exit -1 # rubocop:disable Lint/AmbiguousOperator
60
- end
61
- named_profiles[name]
62
- end
63
-
64
- def self.load_config_file(config_path)
65
- @config_file = config_path
66
- logger.info("Loading configuration from #{config_path}")
67
- parse_config(File.open(config_path))
68
- end
69
-
70
- def self.parse_config(yaml)
71
-
72
- require 'yaml'
73
-
74
- profiles = YAML.load(yaml)
75
- profiles.each do |name, options|
76
- options['config_file'] = config_file
77
- options['name'] = name
78
- AWSAssumeRole::Profile.create(name, options)
79
- end
80
-
81
- end
82
-
83
- # Superclass for Profile strategies
84
-
85
- def set_env(prefix = '') # rubocop:disable Style/AccessorMethodName
86
-
87
- logger.info("Setting environment with prefix '#{prefix}'")
88
-
89
- ENV["#{prefix}AWS_ACCESS_KEY_ID"] = access_key_id
90
- ENV["#{prefix}AWS_SECRET_ACCESS_KEY"] = secret_access_key
91
- ENV["#{prefix}AWS_DEFAULT_REGION"] = region
92
-
93
- return unless respond_to?(:session_token)
94
-
95
- logger.info(':session_token available, setting environment')
96
- ENV["#{prefix}AWS_SESSION_TOKEN"] = session_token
97
-
98
- end
99
-
100
- def access_key_id
101
- raise NotImplementedError
102
- end
103
-
104
- def secret_access_key
105
- raise NotImplementedError
106
- end
107
-
108
- def region
109
- raise NotImplementedError
110
- end
111
-
112
- def sts_client
113
- raise NotImplementedError
114
- end
115
-
116
- attr_reader :name
117
-
118
- def use
119
- raise NotImplementedError
120
- end
121
-
122
- def add
123
- raise NotImplementedError
124
- end
125
-
126
- def remove
127
- raise NotImplementedError
128
- end
129
-
130
- def token_code
131
- puts "Enter your MFA's time-based one time password: "
132
- token_code = STDIN.gets
133
- token_code.chomp!
134
- end
135
-
136
- def keyring_key
137
- "#{@options['config_file']}|#{@options['name']}"
138
- end
139
-
140
- def session(duration = 3600)
141
-
142
- # See if we already have a non-expired session cached in this
143
- # object.
144
-
145
- unless @session.nil?
146
-
147
- logger.info('Found session cached in object')
148
- return @session unless @session.expired?
149
- logger.info('Session expired, deleting keyring key '\
150
- "'#{keyring_key}'")
151
- @session.delete_from_keyring(keyring_key)
152
-
153
- end
154
-
155
- # See if there's a non-exipred session cached in the keyring
156
-
157
- @session = AWSAssumeRole::Credentials.load_from_keyring(keyring_key)
158
-
159
- unless @session.nil?
160
-
161
- logger.info("Found session in keyring for '#{keyring_key}'")
162
- return @session unless @session.expired?
163
- logger.info('Session expired, deleting keyring key '\
164
- "'#{keyring_key}'")
165
- @session.delete_from_keyring(keyring_key)
166
-
167
- end
168
-
169
- begin
170
- identity = sts_client.get_caller_identity
171
- rescue Aws::Errors::MissingCredentialsError
172
- STDERR.puts "No credentials found. Set one in the credentials file "\
173
- "or environment."
174
- exit -1 # rubocop:disable Lint/AmbiguousOperator
175
- end
176
- user_name = identity.arn.split('/')[1]
177
- mfa_arn = "arn:aws:iam::#{identity.account}:mfa/#{user_name}"
178
-
179
- mfa_token_code = token_code
180
-
181
- begin
182
- session = sts_client.get_session_token(
183
- duration_seconds: duration,
184
- serial_number: mfa_arn,
185
- token_code: mfa_token_code,
186
- )
187
- rescue Aws::STS::Errors::AccessDenied
188
- STDERR.puts 'MultiFactorAuthentication failed with invalid MFA ' \
189
- 'one time pass code.'
190
- exit -1 # rubocop:disable Lint/AmbiguousOperator
191
- end
192
-
193
- @session = Credentials.create_from_sdk(session.credentials)
194
- logger.info("Storing session in keyring '#{keyring_key}'")
195
- @session.store_in_keyring(keyring_key)
196
-
197
- @session
198
-
199
- end
200
-
201
- end
202
-
203
- end
@@ -1,127 +0,0 @@
1
- # AWSAssumeRole
2
- module AWSAssumeRole
3
-
4
- class Profile
5
-
6
- # A Profile implementation for assuming roles using STS
7
- class AssumeRole < Profile
8
-
9
- include Logging
10
-
11
- register_implementation('assume_role', self)
12
-
13
- @sts_client = nil
14
- @role = nil
15
- @options = nil
16
- @name = nil
17
-
18
- def default_options
19
- {
20
- 'parent' => 'default',
21
- 'duration' => 3600,
22
- }
23
- end
24
-
25
- def initialize(name, options = {})
26
-
27
- require 'aws-sdk'
28
-
29
- @options = default_options.merge(options)
30
- @name = name
31
-
32
- end
33
-
34
- def sts_client
35
-
36
- return @sts_client unless @sts_client.nil?
37
-
38
- parent = AWSAssumeRole::Profile.get_by_name(@options['parent'])
39
-
40
- @sts_client = Aws::STS::Client.new(
41
- access_key_id: parent.session.access_key_id,
42
- secret_access_key: parent.session.secret_access_key,
43
- session_token: parent.session.session_token,
44
- )
45
-
46
- @sts_client
47
-
48
- rescue Aws::Errors::MissingRegionError
49
-
50
- STDERR.puts 'No region was given. \
51
- Set one in the credentials file or environment'
52
- exit -1 # rubocop:disable Lint/AmbiguousOperator
53
-
54
- end
55
-
56
- def role_credentials
57
-
58
- # Check for non-expired session cached here
59
-
60
- unless @role_credentials.nil?
61
-
62
- return @role_credentials unless @role_credentials.expired?
63
- @role_credentials.delete_from_keyring(keyring_key)
64
-
65
- end
66
-
67
- # See if here's a non-exipred session in the keyring
68
-
69
- @role_credentials = Credentials.load_from_keyring(keyring_key)
70
-
71
- unless @role_credentials.nil?
72
-
73
- return @role_credentials unless @role_credentials.expired?
74
- @role_credentials.delete_from_keyring(keyring_key)
75
-
76
- end
77
-
78
- role = sts_client.assume_role(
79
- role_arn: @options['role_arn'],
80
- role_session_name: name, # use something else?
81
- duration_seconds: @options['duration'],
82
- )
83
-
84
- @role_credentials =
85
- Credentials.create_from_sdk(role.credentials)
86
-
87
- @role_credentials.store_in_keyring(keyring_key)
88
-
89
- @role_credentials
90
-
91
- end
92
-
93
- def access_key_id
94
- role_credentials.access_key_id
95
- end
96
-
97
- def secret_access_key
98
- role_credentials.secret_access_key
99
- end
100
-
101
- def session_token
102
- role_credentials.session_token
103
- end
104
-
105
- def region
106
- @options['region']
107
- end
108
-
109
- def use
110
- set_env if @options['set_environment']
111
- end
112
-
113
- def remove
114
- Credentials.new({}).delete_from_keyring(keyring_key)
115
- end
116
-
117
- def add
118
- STDERR.puts "You can't add credentials to an assume_role "\
119
- 'just basic/parent accounts.'
120
- exit -1 # rubocop:disable Lint/AmbiguousOperator
121
- end
122
-
123
- end
124
-
125
- end
126
-
127
- end
@@ -1,152 +0,0 @@
1
- # AWSAssumeRole
2
- module AWSAssumeRole
3
-
4
- class Profile
5
-
6
- # Profile implementation which takes credentials from either
7
- # passed options, from the environment, or from .aws/credentials
8
- # file (per the standard behaviour of Aws::STS::Client)
9
- class Basic < Profile
10
-
11
- include Logging
12
-
13
- register_implementation('basic', self)
14
-
15
- @sts_client = nil
16
- @options = nil
17
- @name = nil
18
-
19
- def initialize(name, options = {})
20
-
21
- require 'aws-sdk'
22
-
23
- @options = options
24
- @name = name
25
-
26
- end
27
-
28
- def sts_client
29
- logger.debug("Calling STS client")
30
-
31
- return @sts_client unless @sts_client.nil?
32
-
33
- if @options.key?('profile')
34
-
35
- logger.info("Loading profile #{@options['profile']} from ~/.aws/credentials")
36
- # Attempt to load with profile name suplied
37
- @sts_client = Aws::STS::Client.new(
38
- profile: @options['profile'],
39
- )
40
-
41
- elsif access_key_id && secret_access_key
42
-
43
- logger.debug("Access Key: #{access_key_id}")
44
- logger.debug("Secret Key: #{secret_access_key}")
45
- logger.debug("Region: #{region}")
46
-
47
- @sts_client = Aws::STS::Client.new(
48
- access_key_id: access_key_id,
49
- secret_access_key: secret_access_key,
50
- region: region,
51
- )
52
-
53
- else
54
-
55
- @sts_client = Aws::STS::Client.new
56
-
57
- end
58
-
59
- @sts_client
60
-
61
- rescue Aws::Errors::MissingRegionError
62
-
63
- STDERR.puts 'No region was given. \
64
- Set one in the credentials file or environment'
65
- exit -1 # rubocop:disable Lint/AmbiguousOperator
66
-
67
- end
68
-
69
- def basic_credentials
70
- logger.debug("Loading basic credentials")
71
- # Check for profile creds in keyring first
72
- @basic_credentials = Credentials.load_from_keyring("#{keyring_key}|basic")
73
-
74
- return @basic_credentials unless @basic_credentials.nil?
75
-
76
- creds = {
77
- :access_key_id => ENV['AWS_ACCESS_KEY_ID'],
78
- :secret_access_key => ENV['AWS_SECRET_ACCESS_KEY'],
79
- }
80
-
81
- if creds[:access_key_id].nil? or creds[:secret_access_key].nil?
82
- STDERR.puts 'No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY ' \
83
- 'found in the environment.'
84
- exit -1 # rubocop:disable Lint/AmbiguousOperator
85
- end
86
-
87
- unless @options['region'].nil?
88
- creds[:region] = @options['region']
89
- else
90
- creds[:region] = ENV['AWS_DEFAULT_REGION']
91
- end
92
-
93
- @basic_credentials = AWSAssumeRole::Credentials.new(creds)
94
-
95
- @basic_credentials
96
- end
97
-
98
- def access_key_id
99
- @options['access_key_id'] || basic_credentials.access_key_id
100
- end
101
-
102
- def secret_access_key
103
- @options['secret_access_key'] || basic_credentials.secret_access_key
104
- end
105
-
106
- def region
107
- @options['region'] || basic_credentials.region
108
- end
109
-
110
- def remove
111
- Credentials.new({}).delete_from_keyring(keyring_key)
112
- Credentials.new({}).delete_from_keyring("#{keyring_key}|basic")
113
- end
114
-
115
- def add
116
- if @options['profile']
117
- puts "WARNING: Storing credentials but a profile is specified and used for #{@name}"
118
- end
119
- if @options['access_key_id'] or @options['secret_access_key']
120
- puts "WARNING: Storing credentials but they are specified in config for #{@name}"
121
- end
122
-
123
- @basic_credentials = Credentials.load_from_keyring("#{keyring_key}|basic")
124
- new_creds = get_credentials
125
- @basic_credentials.delete_from_keyring(keyring_key) unless @basic_credentials.nil?
126
- @basic_credentials = AWSAssumeRole::Credentials.new(new_creds)
127
- @basic_credentials.store_in_keyring("#{keyring_key}|basic")
128
- end
129
-
130
- def get_credentials
131
- puts "Enter your AWS_ACCESS_KEY_ID: "
132
- id = STDIN.gets
133
- id.chomp!
134
- puts "Enter your AWS_SECRET_ACCESS_KEY: "
135
- secret = STDIN.gets
136
- secret.chomp!
137
- puts "Enter a AWS Region:"
138
- region = STDIN.gets
139
- region.chomp!
140
-
141
- creds = {
142
- :access_key_id => id,
143
- :secret_access_key => secret,
144
- :region => region,
145
- }
146
- creds
147
- end
148
- end
149
-
150
- end
151
-
152
- end