aws_su 0.1.0 → 0.1.1
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 +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +8 -1
- data/README.md +28 -17
- data/Rakefile +7 -5
- data/aws_su.gemspec +4 -3
- data/bin/console +3 -3
- data/lib/aws_su/version.rb +1 -1
- data/lib/aws_su.rb +78 -44
- data/lib/matches_aws_access_key_id.rb +1 -0
- data/lib/matches_aws_profile.rb +1 -0
- data/lib/matches_aws_secret_access_key.rb +1 -0
- data/lib/matches_aws_security_token.rb +1 -0
- data/lib/matches_aws_session_token.rb +1 -0
- data/lib/matches_aws_token_etl.rb +1 -0
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ced5b07379bc4a4e9f0f3d316e575886367f0cca
|
4
|
+
data.tar.gz: 14ab789e98f42ad0790d43d1d72020c65514db48
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c2eeaa96c2b04eb60d6ed82d5d7b76c4f9c0cc1d5d24aa881754f4581d5bd142ac8321f3e0a905ec4fc35d49b6c2c7820a255806fc04cebe043b6ced7dbabd58
|
7
|
+
data.tar.gz: 10253e4ab496fc1924807d6f22b32d6c271b7c634a671a1813b929e6c433066040c8b9afd5e99348109df32abd36f783b7db43dc1c7266306f72a203b280e93c
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -8,4 +8,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
8
8
|
## [0.1.0] - 01-12-2018
|
9
9
|
### Added
|
10
10
|
- Ability to authenticate and switch role via a single authenticate() method
|
11
|
-
- Gemspec file updated to enable push to Rubygems.org
|
11
|
+
- Gemspec file updated to enable push to Rubygems.org
|
12
|
+
|
13
|
+
## [0.1.1] - 02-12-2018
|
14
|
+
### Added
|
15
|
+
- Required ruby version in gemspec
|
16
|
+
- Housekeeping now that gem is on both github and rubygems
|
17
|
+
- Changed authenticate() method to accept options hash
|
18
|
+
- Added detailed header to AwsSu module
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# AwsSu
|
2
2
|
|
3
|
-
AwsSu is a gem developed for a specific use case, where the user has an ID
|
3
|
+
AwsSu is a gem developed for a specific use case, where the user has an ID setup in an AWS master account and wants to
|
4
4
|
assume a role in another account that they have permission to assume.
|
5
5
|
|
6
6
|
## Installation
|
@@ -8,7 +8,7 @@ assume a role in another account that they have permission to assume.
|
|
8
8
|
Add this line to your application's Gemfile:
|
9
9
|
|
10
10
|
```ruby
|
11
|
-
gem 'aws_su'
|
11
|
+
gem 'aws_su'
|
12
12
|
```
|
13
13
|
|
14
14
|
And then execute:
|
@@ -25,15 +25,19 @@ Implemented as a Ruby Module, the gem can be included into any class that needs
|
|
25
25
|
a role prior to calling one of the aws client methods like so:
|
26
26
|
|
27
27
|
```ruby
|
28
|
-
require 'aws_su'
|
29
|
-
|
30
|
-
class
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
28
|
+
require 'aws_su'
|
29
|
+
|
30
|
+
class RunAwsSu
|
31
|
+
include AwsSu
|
32
|
+
end
|
33
|
+
|
34
|
+
run_aws_su = RunAwsSu.new
|
35
|
+
run_aws_su.authenticate(
|
36
|
+
profile: 'ds-nonprod',
|
37
|
+
duration: '28800',
|
38
|
+
region: 'eu-west-2'
|
39
|
+
)
|
40
|
+
run_aws_su.ec2_client.describe_vpcs
|
37
41
|
```
|
38
42
|
|
39
43
|
The gem expects to find the standard aws secrets files:
|
@@ -51,19 +55,26 @@ With the former containing the master account secrets:
|
|
51
55
|
And the latter containing the details of the role to be assumed:
|
52
56
|
|
53
57
|
```
|
54
|
-
[profile my-profile]
|
55
|
-
source_profile=master
|
56
|
-
mfa_serial=arn:aws:iam::1234567890:mfa/bradley.atkins@bjss.com
|
57
|
-
role_arn=arn:aws:iam::1234567890:role/MY-NONPROD-TESTER-ROLE
|
58
|
+
[profile my-profile]
|
59
|
+
source_profile=master
|
60
|
+
mfa_serial=arn:aws:iam::1234567890:mfa/bradley.atkins@bjss.com
|
61
|
+
role_arn=arn:aws:iam::1234567890:role/MY-NONPROD-TESTER-ROLE
|
58
62
|
```
|
59
63
|
|
60
64
|
AwsSu also configures the current shell with the necessary environment variables to allow system calls to
|
61
65
|
be made without further authentication:
|
62
66
|
|
63
67
|
```ruby
|
64
|
-
system('aws ec2 describe-vpcs --region eu-west-2')
|
68
|
+
system('aws ec2 describe-vpcs --region eu-west-2')
|
65
69
|
```
|
66
70
|
|
71
|
+
Clients currently supported are:
|
72
|
+
|
73
|
+
- ec2_client
|
74
|
+
- elb_client
|
75
|
+
- iam_client
|
76
|
+
- sqs_client
|
77
|
+
|
67
78
|
## Development
|
68
79
|
|
69
80
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -72,7 +83,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
72
83
|
|
73
84
|
## Contributing
|
74
85
|
|
75
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
86
|
+
Bug reports and pull requests are welcome on GitHub at [The Github Repository](https://github.com/museadmin/aws_su). This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
76
87
|
|
77
88
|
## License
|
78
89
|
|
data/Rakefile
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rake/testtask'
|
3
5
|
|
4
6
|
Rake::TestTask.new(:test) do |t|
|
5
|
-
t.libs <<
|
6
|
-
t.libs <<
|
7
|
+
t.libs << 'test'
|
8
|
+
t.libs << 'lib'
|
7
9
|
t.test_files = FileList["test/**/*_test.rb"]
|
8
10
|
end
|
9
11
|
|
10
|
-
task :
|
12
|
+
task default: :test
|
data/aws_su.gemspec
CHANGED
@@ -12,8 +12,8 @@ Gem::Specification.new do |spec|
|
|
12
12
|
|
13
13
|
spec.summary = 'Gem to wrap helper methods around AWS authentication API'
|
14
14
|
spec.description = 'Developed for a specific use case: ' \
|
15
|
-
'User has an AWS id in a master account and wants to assume'\
|
16
|
-
'
|
15
|
+
'User has an AWS id in a master account and wants to assume '\
|
16
|
+
'a role in another account. This module exposes a single '\
|
17
17
|
'authenticate() method that handles authentication and switching role '\
|
18
18
|
'by referencing the user\'s aws secrets.'
|
19
19
|
spec.homepage = 'https://github.com/museadmin'
|
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
if spec.respond_to?(:metadata)
|
25
25
|
spec.metadata['homepage_uri'] = spec.homepage
|
26
26
|
spec.metadata['source_code_uri'] = 'https://github.com/museadmin/aws_su'
|
27
|
-
spec.metadata['changelog_uri'] =
|
27
|
+
spec.metadata['changelog_uri'] = 'https://github.com/museadmin/aws_su/blob/master/CHANGELOG.md'
|
28
28
|
else
|
29
29
|
raise 'RubyGems >= 2.0 is required to protect against public gem pushes'
|
30
30
|
end
|
@@ -39,6 +39,7 @@ Gem::Specification.new do |spec|
|
|
39
39
|
spec.bindir = 'exe'
|
40
40
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
41
41
|
spec.require_paths = ['lib']
|
42
|
+
spec.required_ruby_version = '>= 2.4'
|
42
43
|
|
43
44
|
spec.add_development_dependency 'awsecrets'
|
44
45
|
spec.add_development_dependency 'bundler', '~> 1.17'
|
data/bin/console
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require "bundler/setup"
|
4
|
-
require "aws_su"
|
3
|
+
require "bundler/setup".freeze
|
4
|
+
require "aws_su".freeze
|
5
5
|
|
6
6
|
# You can add fixtures and/or initialization code here to make experimenting
|
7
7
|
# with your gem easier. You can also use a different console, if you like.
|
@@ -10,5 +10,5 @@ require "aws_su"
|
|
10
10
|
# require "pry"
|
11
11
|
# Pry.start
|
12
12
|
|
13
|
-
require "irb"
|
13
|
+
require "irb".freeze
|
14
14
|
IRB.start(__FILE__)
|
data/lib/aws_su/version.rb
CHANGED
data/lib/aws_su.rb
CHANGED
@@ -3,9 +3,39 @@
|
|
3
3
|
require 'aws_config'
|
4
4
|
require 'matches'
|
5
5
|
require 'awsecrets'
|
6
|
-
require '
|
6
|
+
require 'aws_su/version'
|
7
7
|
|
8
|
-
# Set up the AWS authentication environment
|
8
|
+
# Set up the AWS authentication environment for a user
|
9
|
+
# who has an ID in a master account and is allowed to
|
10
|
+
# switch to a role in another account.
|
11
|
+
#
|
12
|
+
# Typical usage scenario:
|
13
|
+
#
|
14
|
+
# require 'aws_su'
|
15
|
+
#
|
16
|
+
# class RunAwsSu
|
17
|
+
# include AwsSu
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# run_aws_su = RunAwsSu.new
|
21
|
+
# run_aws_su.authenticate(
|
22
|
+
# profile: 'ds-nonprod',
|
23
|
+
# duration: '28800',
|
24
|
+
# region: 'eu-west-2'
|
25
|
+
# )
|
26
|
+
# run_aws_su.ec2_client.describe_vpcs
|
27
|
+
#
|
28
|
+
# also sets up current shell so system calls don't need further authentication:
|
29
|
+
#
|
30
|
+
# system('aws ec2 describe-vpcs --region eu-west-2')
|
31
|
+
#
|
32
|
+
# It is assumed that the region is set in the first profile in .aws/config, e.g.
|
33
|
+
#
|
34
|
+
# [profile master]
|
35
|
+
# region=eu-west-2
|
36
|
+
#
|
37
|
+
# or it can be set in the call to authenticate() as shown above
|
38
|
+
#
|
9
39
|
module AwsSu
|
10
40
|
class Error < StandardError; end
|
11
41
|
|
@@ -19,11 +49,21 @@ module AwsSu
|
|
19
49
|
@master_config = Awsecrets.load # AWS config for master account
|
20
50
|
|
21
51
|
# Authenticate user for the session
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
52
|
+
# @param options Hash {
|
53
|
+
# duration: 'AWS role session timeout',
|
54
|
+
# region: AWS region,
|
55
|
+
# profile: Name of profile in .aws/config to use
|
56
|
+
# }
|
57
|
+
def authenticate(options = {})
|
58
|
+
@session = "aws-su-session-#{Time.now.to_i}"
|
59
|
+
@profile = options[:profile]
|
60
|
+
@duration = options[:duration].nil? ? DURATION : options[:duration]
|
61
|
+
@token_ttl = calculate_session_expiry(@duration)
|
62
|
+
|
63
|
+
region = AWSConfig.profiles.first[1][:region]
|
64
|
+
@region = options[:region].nil? ? region : options[:region]
|
65
|
+
raise('Unable to determine region') if @region.nil?
|
66
|
+
|
27
67
|
export_aws_sudo_file
|
28
68
|
assume_role
|
29
69
|
end
|
@@ -48,21 +88,24 @@ module AwsSu
|
|
48
88
|
Aws::S3::Client.new
|
49
89
|
end
|
50
90
|
|
51
|
-
#
|
91
|
+
# SQS Client
|
92
|
+
def sqs_client
|
93
|
+
Aws::SQS::Client.new
|
94
|
+
end
|
95
|
+
|
96
|
+
# STS
|
52
97
|
def sts_client
|
53
98
|
Aws::STS::Client.new(
|
54
|
-
|
55
|
-
|
99
|
+
credentials: load_secrets,
|
100
|
+
region: @region
|
56
101
|
)
|
57
102
|
end
|
58
103
|
|
59
104
|
private
|
105
|
+
|
60
106
|
# Assume a role
|
61
|
-
# @param duration A string integer representing the session duration
|
107
|
+
# @param duration A string integer representing the role session duration
|
62
108
|
def assume_role(duration = DURATION)
|
63
|
-
# For the benefit of anything downstream we are running
|
64
|
-
export_aws_sudo_file
|
65
|
-
|
66
109
|
if session_valid?
|
67
110
|
# Recover persisted session and use that to update AWS.config
|
68
111
|
Aws.config.update(
|
@@ -74,25 +117,28 @@ module AwsSu
|
|
74
117
|
)
|
75
118
|
else
|
76
119
|
# Session has expired so auth again
|
77
|
-
|
120
|
+
assume_role_mfa(duration)
|
78
121
|
end
|
122
|
+
# For the benefit of anything downstream we are running
|
123
|
+
export_aws_sudo_file
|
79
124
|
end
|
80
125
|
|
81
126
|
# Assume a role using an MFA Token
|
82
|
-
def
|
127
|
+
def assume_role_mfa(duration, mfa_code = nil)
|
83
128
|
mfa_code = prompt_for_mfa_code if mfa_code.nil?
|
84
129
|
role_creds = sts_client.assume_role(
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
130
|
+
role_arn: AWSConfig[@profile]['role_arn'],
|
131
|
+
role_session_name: @session,
|
132
|
+
duration_seconds: duration.to_i,
|
133
|
+
serial_number: AWSConfig[@profile]['mfa_serial'],
|
134
|
+
token_code: mfa_code.to_s
|
90
135
|
)
|
91
136
|
update_aws_config(role_creds)
|
92
|
-
|
137
|
+
persist_aws_su(role_creds)
|
93
138
|
end
|
94
139
|
|
95
140
|
# Calculate the session expiration
|
141
|
+
# # @param duration A string integer representing the role session duration
|
96
142
|
def calculate_session_expiry(duration = DURATION)
|
97
143
|
(Time.now + duration.to_i).strftime('%Y-%m-%d %H:%M:%S')
|
98
144
|
end
|
@@ -148,20 +194,6 @@ module AwsSu
|
|
148
194
|
end
|
149
195
|
end
|
150
196
|
|
151
|
-
# Recover the role_arn from the AWS config file
|
152
|
-
def parse_role_arn
|
153
|
-
File.readlines(AWS_CONFIG_FILE).each do |line|
|
154
|
-
return line.split('=')[1].chomp if line.include?('role_arn')
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
# Recover the mfa serial number from AWS config file
|
159
|
-
def parse_mfa_serial
|
160
|
-
File.readlines(AWS_CONFIG_FILE).each do |line|
|
161
|
-
return line.split('=')[1].chomp if line.include?('mfa_serial')
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
197
|
# Parse the session token from awssudo
|
166
198
|
def parse_session_token
|
167
199
|
File.readlines(AWS_SUDO_FILE).each do |line|
|
@@ -177,14 +209,16 @@ module AwsSu
|
|
177
209
|
end
|
178
210
|
|
179
211
|
# Persist the config to the awssudo file
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
212
|
+
# @param config Credentials from assume role to persist
|
213
|
+
# @param file The temporary secrets file ~/.awssudo
|
214
|
+
def persist_aws_su(config, file = AWS_SUDO_FILE)
|
215
|
+
File.open(file, 'w') do |f|
|
216
|
+
f.puts('AWS_ACCESS_KEY_ID=' + config.credentials.access_key_id)
|
217
|
+
f.puts('AWS_SECRET_ACCESS_KEY=' + config.credentials.secret_access_key)
|
218
|
+
f.puts('AWS_SESSION_TOKEN=' + config.credentials.session_token)
|
219
|
+
f.puts('AWS_SECURITY_TOKEN=' + config.credentials.session_token)
|
220
|
+
f.puts('AWS_TOKEN_TTL=' + @token_ttl)
|
221
|
+
f.puts('AWS_PROFILE=' + @profile)
|
188
222
|
end
|
189
223
|
end
|
190
224
|
|
data/lib/matches_aws_profile.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aws_su
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bradley Atkins
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-12-
|
11
|
+
date: 2018-12-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: awsecrets
|
@@ -67,7 +67,7 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '10.0'
|
69
69
|
description: 'Developed for a specific use case: User has an AWS id in a master account
|
70
|
-
and wants to assume a role in another account. This module exposes a
|
70
|
+
and wants to assume a role in another account. This module exposes a single authenticate()
|
71
71
|
method that handles authentication and switching role by referencing the user''s
|
72
72
|
aws secrets.'
|
73
73
|
email:
|
@@ -103,7 +103,7 @@ licenses:
|
|
103
103
|
metadata:
|
104
104
|
homepage_uri: https://github.com/museadmin
|
105
105
|
source_code_uri: https://github.com/museadmin/aws_su
|
106
|
-
changelog_uri:
|
106
|
+
changelog_uri: https://github.com/museadmin/aws_su/blob/master/CHANGELOG.md
|
107
107
|
post_install_message:
|
108
108
|
rdoc_options: []
|
109
109
|
require_paths:
|
@@ -112,7 +112,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
112
112
|
requirements:
|
113
113
|
- - ">="
|
114
114
|
- !ruby/object:Gem::Version
|
115
|
-
version: '
|
115
|
+
version: '2.4'
|
116
116
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
117
|
requirements:
|
118
118
|
- - ">="
|