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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7c94982b2139e90c3f36bb7b8e7f4d2989b05a2e
4
- data.tar.gz: b6de06567ecb9a29348ecce20a12d4b93600ad19
3
+ metadata.gz: ced5b07379bc4a4e9f0f3d316e575886367f0cca
4
+ data.tar.gz: 14ab789e98f42ad0790d43d1d72020c65514db48
5
5
  SHA512:
6
- metadata.gz: 412fb1c85c563d71b74e6aca277ef5c3031ad7503aafbeb6baccc58dde436b81fe5c7755ac0d71095af878cff2d1062b3570868624cd7f8041782f32f006561b
7
- data.tar.gz: de13c38ada25aeada402abff4465d24f91346b032365ebaef4c02f5992b20bdb503332caab3b8a9800d9a58571ed977a2779e72a541550fcb4a95df812a9580a
6
+ metadata.gz: c2eeaa96c2b04eb60d6ed82d5d7b76c4f9c0cc1d5d24aa881754f4581d5bd142ac8321f3e0a905ec4fc35d49b6c2c7820a255806fc04cebe043b6ced7dbabd58
7
+ data.tar.gz: 10253e4ab496fc1924807d6f22b32d6c271b7c634a671a1813b929e6c433066040c8b9afd5e99348109df32abd36f783b7db43dc1c7266306f72a203b280e93c
data/.gitignore CHANGED
@@ -10,3 +10,4 @@
10
10
  .idea/*
11
11
  Gemfile.lock
12
12
  *.html
13
+ /test/runner.rb
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 setuo in an AWS master account and wants to
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 Runner
31
- include AwsSu
32
- end
33
-
34
- runner = Runner.new
35
- runner.authenticate('my-profile')
36
- runner.ec2_client.describe_vpcs
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/[USERNAME]/aws_sudo. 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.
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
- require "bundler/gem_tasks"
2
- require "rake/testtask"
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 << "test"
6
- t.libs << "lib"
7
+ t.libs << 'test'
8
+ t.libs << 'lib'
7
9
  t.test_files = FileList["test/**/*_test.rb"]
8
10
  end
9
11
 
10
- task :default => :test
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
- ' a role in another account. This module exposes a single'\
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'] = "Put your gem's CHANGELOG.md URL here."
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__)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AwsSu
4
- VERSION = '0.1.0'
4
+ VERSION = '0.1.1'
5
5
  end
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 'aws_sudo/version'
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
- def authenticate(profile, duration = DURATION)
23
- @session = "awssudo-session-#{Time.now.to_i}"
24
- @token_ttl = calculate_session_expiry(duration)
25
- @profile = profile
26
- @duration = duration
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
- # Get an STS client so we can request a session token
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
- credentials: load_secrets,
55
- region: 'eu-west-2'
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
- assume_role_with_mfa_token(duration)
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 assume_role_with_mfa_token(duration, mfa_code = nil)
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
- role_arn: AWSConfig[@profile]['role_arn'],
86
- role_session_name: @session,
87
- duration_seconds: duration.to_i,
88
- serial_number: AWSConfig[@profile]['mfa_serial'],
89
- token_code: mfa_code.to_s
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
- persist_aws_sudo(role_creds)
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
- def persist_aws_sudo(config, file = AWS_SUDO_FILE)
181
- File.open(file, 'w') do |file|
182
- file.puts('AWS_ACCESS_KEY_ID=' + config.credentials.access_key_id)
183
- file.puts('AWS_SECRET_ACCESS_KEY=' + config.credentials.secret_access_key)
184
- file.puts('AWS_SESSION_TOKEN=' + config.credentials.session_token)
185
- file.puts('AWS_SECURITY_TOKEN=' + config.credentials.session_token)
186
- file.puts('AWS_TOKEN_TTL=' + @token_ttl)
187
- file.puts('AWS_PROFILE=' + @profile)
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
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  # Match AWS_ACCESS_KEY_ID
3
4
  class MatchesAwsAccessKeyId
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  # Match AWS_PROFILE
3
4
  class MatchesAwsProfile
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  # Match AWS_SECRET_ACCESS_KEY
3
4
  class MatchesAwsSecretAccessKey
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  # Match AWS_SECURITY_TOKEN
3
4
  class MatchesAwsSecurityToken
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  # Match AWS_SESSION_TOKEN
3
4
  class MatchesAwsSessionToken
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  # Match AWS_TOKEN_TTL
3
4
  class MatchesAwsTokenEtl
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.0
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-01 00:00:00.000000000 Z
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 singleauthenticate()
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: Put your gem's CHANGELOG.md URL here.
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: '0'
115
+ version: '2.4'
116
116
  required_rubygems_version: !ruby/object:Gem::Requirement
117
117
  requirements:
118
118
  - - ">="