aws_assume_role 0.1.1 → 0.1.2
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 +2 -0
- data/.rubocop.yml +0 -4
- data/.ruby-version +1 -0
- data/.simplecov +22 -0
- data/.travis.yml +10 -1
- data/Gemfile +1 -0
- data/README.md +9 -4
- data/Rakefile +16 -1
- data/aws_assume_role.gemspec +4 -2
- data/lib/aws_assume_role/cli/actions/abstract_action.rb +7 -3
- data/lib/aws_assume_role/cli/actions/includes.rb +1 -9
- data/lib/aws_assume_role/cli/actions/run.rb +1 -1
- data/lib/aws_assume_role/cli/actions/test.rb +3 -1
- data/lib/aws_assume_role/cli/includes.rb +1 -0
- data/lib/aws_assume_role/core_ext/aws-sdk/includes.rb +1 -1
- data/lib/aws_assume_role/credentials/factories/abstract_factory.rb +1 -1
- data/lib/aws_assume_role/credentials/factories/assume_role.rb +13 -14
- data/lib/aws_assume_role/credentials/factories/default_chain_provider.rb +56 -47
- data/lib/aws_assume_role/credentials/factories/includes.rb +7 -11
- data/lib/aws_assume_role/credentials/factories/instance_profile.rb +1 -1
- data/lib/aws_assume_role/credentials/factories/repository.rb +2 -2
- data/lib/aws_assume_role/credentials/factories/shared.rb +7 -5
- data/lib/aws_assume_role/credentials/includes.rb +4 -0
- data/lib/aws_assume_role/credentials/providers/includes.rb +3 -5
- data/lib/aws_assume_role/credentials/providers/mfa_session_credentials.rb +20 -23
- data/lib/aws_assume_role/credentials/providers/shared_keyring_credentials.rb +27 -10
- data/lib/aws_assume_role/includes.rb +9 -3
- data/lib/aws_assume_role/profile_configuration.rb +24 -25
- data/lib/aws_assume_role/runner.rb +9 -10
- data/lib/aws_assume_role/store/includes.rb +1 -11
- data/lib/aws_assume_role/store/keyring.rb +1 -2
- data/lib/aws_assume_role/store/shared_config_with_keyring.rb +86 -28
- data/lib/aws_assume_role/types.rb +1 -2
- data/lib/aws_assume_role/vendored/aws/assume_role_credentials.rb +0 -1
- data/lib/aws_assume_role/vendored/aws/includes.rb +1 -1
- data/lib/aws_assume_role/vendored/aws/refreshing_credentials.rb +0 -2
- data/lib/aws_assume_role/vendored/aws/shared_config.rb +4 -1
- data/lib/aws_assume_role/version.rb +1 -1
- metadata +40 -9
- data/lib/aws_assume_role/credentials/factories/shared_keyring.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 740d4539f3f7bf68b7acedc131890496b67eaef4
|
4
|
+
data.tar.gz: a5f739bbb05c1cd1edfc59e156ee2a348c88c9ff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0898326d54de021a939f2375466c7376a3e42cca8b7c597d4b03a9b11b4a407b078b4560ec3790418c462a84bbde0836a2f9ea30acf5e1b3cebfab25e2567a55
|
7
|
+
data.tar.gz: f161cc86abf84c2e893cc9426bea9861b02b30bd31fccbf2ed8f7ac526252d51f236e530b5a178fffde1db94ef910a7cf87fc22c9645f8685f0eaa49eeb58c24
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
---
|
2
|
-
#require: rubocop-rspec
|
3
2
|
AllCops:
|
4
3
|
DisplayCopNames: true
|
5
4
|
Exclude:
|
@@ -26,9 +25,6 @@ Metrics/PerceivedComplexity:
|
|
26
25
|
Style/IndentationWidth:
|
27
26
|
Width: 4
|
28
27
|
|
29
|
-
RSpec/ExampleLength:
|
30
|
-
Enabled: false
|
31
|
-
|
32
28
|
Style/TrailingCommaInArguments:
|
33
29
|
EnforcedStyleForMultiline: comma
|
34
30
|
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.1.10
|
data/.simplecov
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'coveralls'
|
2
|
+
Coveralls.wear_merged!
|
3
|
+
|
4
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
|
5
|
+
SimpleCov::Formatter::HTMLFormatter,
|
6
|
+
Coveralls::SimpleCov::Formatter
|
7
|
+
])
|
8
|
+
|
9
|
+
SimpleCov.start do
|
10
|
+
|
11
|
+
project_name 'AWS Assume Role'
|
12
|
+
|
13
|
+
add_filter '/spec/'
|
14
|
+
add_filter 'lib/aws_assume_role/vendored'
|
15
|
+
|
16
|
+
%w(aws_assume_role).each do |group_name|
|
17
|
+
add_group(group_name, "/#{group_name}/lib")
|
18
|
+
end
|
19
|
+
|
20
|
+
merge_timeout 60 * 15 # 15 minutes
|
21
|
+
|
22
|
+
end
|
data/.travis.yml
CHANGED
@@ -1,11 +1,20 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
+
- 2.1
|
3
4
|
- 2.2
|
5
|
+
- 2.3.0
|
6
|
+
sudo: false
|
7
|
+
script: bundle exec rake
|
4
8
|
deploy:
|
5
9
|
provider: rubygems
|
6
10
|
api_key:
|
7
|
-
secure:
|
11
|
+
secure: H6MYP5cWFC0BtqrxW6ahc1RFxywtyKRFjGlSpyoBM+AH2y8U194toWQdGyO/QMRQVr7vAZf+MdxYTutDvnBEkwQbof6QBJ1+4GFWSqFgYAVEV5Ddva0ea5dVE8xC3rMRvd+i5KTzwuVNX/+Cux49v2wGRWZLKOmBSWbujsL8SbpdKaPi+qsClkdz3YTrHpGEEWTPNBNTwDMlg+qAX3UkqoAxD5ebrUaFPdJR83yMSGUPfTm/urlKvkx85MONuj7lPL1CyoYJCvy31bE6CWGq2L/+2Fnk8RvNMCaDffY+8YjKhWduBLrGuUYWf+ZcERxW6AxDy6BFIkekpFwpeaDmrdfSTK0aELSZogGqs9VHs9O1pTApdS/NRYDzxC9hmlvub80xC2uI1Vnhn04Z95Gh9KYh0H20UnlBJJ7ewvFPHzQ3zK8Z2O3kJOeZo0rX2d3yGOydyHlf1dX/auGnn8QVcr7w1jERQDLi5ZEAR+EGnYROvfGKjfP9rgaLoouTbEGXx7KV9QQjLUsmQ0q2yu+HoVlQaDtv7VEQTtFnvdmiVGYbWj+DhaquvTmHyiizO7hFOfvVYYFyOM2iFoRCY+dT3kapqc0DM94BUjxV3tMZX6MYNYfwnNwhNNpTXLVvVXP9cShL+ogwY/E0C2Fg2CYdY5/Ioe6hUbAiPx79dwzVfic=
|
8
12
|
gem: aws_assume_role
|
9
13
|
on:
|
10
14
|
tags: true
|
11
15
|
repo: scalefactory/aws-assume-role
|
16
|
+
notifications:
|
17
|
+
slack:
|
18
|
+
secure: RmJmJSSDI8qdIpM2KKYoXX2mpcL85YZ9r9gF4rauZH9TuqnYOPP3kQ5iYJsE0VUTuZpuvQ8Axoux5IQr+IDK7kMrmrI0iaZp1dAR9tGK+aLF73sprOmQEou6HIoDs97UQhOWlsAUR8max/7WYdJYJ1o78dqavfFtOy0VcHCkUMRf+WxcKzz+8MunsocIYi0HXuz5vC3RAZCOaK2h8epXzmnWq0ke8YeTmddpDWC85wzeDNjA9T1j5WD+y6gC9F0vyaqVqDCsCXlbRKZl7a1TU9QGDVyBzowoGsWmTpFR80v4CKofAn6nnMRqblwATOS1jMT+HC+Yku29qFzXPugYa2KAUSQaYQiOe+TE5IDa2Exe/57ZQCOq4ve8gKSE9aQXh4Riq3u8qccM+UeoQdcwgXQIciTeWjqi4LQro6Dbyrv8XrUbxdG0VPsWmf49jbWgq6PPAJqdcbXr9eGb+81uJ2REa1vhDYZu4T3JHv4erd5QlyYWzeBJ/LMQav/C5mnMF43jg8DzZ2g0BZBao/reO9xcZre/ka8eOus9Ll1i+8PCxmFZMx2KDPC9i5R7bXL/CwPBjzFInmvHM0cgKjxrRSY6xMWSPyBbgdsKJl2qag74K5xG+2VPlMcVx0ikTKVjsja5iPlOYKhflGAfCKvpzPcd2QoEWg8jZYqZtO9Nj+M=
|
19
|
+
on_success: change
|
20
|
+
on_failure: change
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
aws-assume-role
|
2
2
|
---------------
|
3
|
+
[](https://travis-ci.org/scalefactory/aws-assume-role)
|
4
|
+
[](https://coveralls.io/github/scalefactory/aws-assume-role?branch=master)
|
5
|
+
[](https://codeclimate.com/github/scalefactory/aws-assume-role)
|
6
|
+
[](https://libraries.io/rubygems/aws_assume_role)
|
7
|
+
[](https://badge.fury.io/rb/aws_assume_role)
|
3
8
|
|
4
9
|
aws-assume-role is a utility intended for developer and operator environments
|
5
10
|
who need to use 2FA and role assumption to access AWS services.
|
@@ -17,11 +22,11 @@ disk as unencrypted files.
|
|
17
22
|
|
18
23
|
It allows easy credential management and role assumption with a 2FA/MFA device.
|
19
24
|
|
20
|
-
For more information on role assumption, see the AWS documentation.
|
25
|
+
For more information on role assumption, see the [AWS documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html).
|
21
26
|
|
22
27
|
Requirements
|
23
28
|
------------
|
24
|
-
* Ruby ≥ 2.
|
29
|
+
* Ruby ≥ 2.1
|
25
30
|
* OS X KeyChain or GNOME Keyring
|
26
31
|
|
27
32
|
Install
|
@@ -179,14 +184,14 @@ where options is a hash with the following symbol keys:
|
|
179
184
|
`aws_assume_role` resolves credentials in almost the same way as the AWS SDK, i.e.:
|
180
185
|
|
181
186
|
```no-highlight
|
182
|
-
static credentials ⟶ environment variables ⟶ configured profiles
|
187
|
+
static credentials ⟶ environment variables ⟶ configured profiles role ⟶ assumption (look up source profile and check for 2FA)
|
183
188
|
```
|
184
189
|
|
185
190
|
Any of the above may get chained to do MFA or role assumption, or both,
|
186
191
|
in the following order:
|
187
192
|
|
188
193
|
```no-highlight
|
189
|
-
second factor ⟶
|
194
|
+
second factor ⟶ ecs/instance profile
|
190
195
|
```
|
191
196
|
|
192
197
|
These are the same as the AWS SDK equivalents whereever possible. The command line help will give an explanation of the rest.
|
data/Rakefile
CHANGED
@@ -1,8 +1,23 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
|
-
task default: :
|
2
|
+
task default: :test
|
3
3
|
|
4
4
|
begin
|
5
5
|
require "rspec/core/rake_task"
|
6
6
|
RSpec::Core::RakeTask.new(:spec)
|
7
7
|
rescue LoadError # rubocop:disable Lint/HandleExceptions
|
8
8
|
end
|
9
|
+
|
10
|
+
begin
|
11
|
+
require "rubocop/rake_task"
|
12
|
+
RuboCop::RakeTask.new(:rubocop)
|
13
|
+
rescue LoadError # rubocop:disable Lint/HandleExceptions
|
14
|
+
end
|
15
|
+
|
16
|
+
task :test => [:no_pry, :rubocop, :spec] # rubocop:disable Style/HashSyntax
|
17
|
+
|
18
|
+
task :no_pry do
|
19
|
+
files = Dir.glob("**/**").reject { |x| x.match(/^spec|Gemfile|coverage|\.gemspec$|Rakefile/) || File.directory?(x) }
|
20
|
+
files.each do |file|
|
21
|
+
raise "Use of pry found in #{file}." if File.read(file) =~ /"pry"/
|
22
|
+
end
|
23
|
+
end
|
data/aws_assume_role.gemspec
CHANGED
@@ -22,10 +22,10 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.executables = spec.files.grep(%r{^bin/aws}) { |f| File.basename(f) }
|
23
23
|
spec.require_paths = ["lib"]
|
24
24
|
|
25
|
-
spec.add_runtime_dependency "activesupport", "~> 4.
|
25
|
+
spec.add_runtime_dependency "activesupport", "~> 4.2"
|
26
26
|
spec.add_runtime_dependency "aws-sdk", "~> 2.7"
|
27
27
|
spec.add_runtime_dependency "dry-configurable", "~> 0.5"
|
28
|
-
spec.add_runtime_dependency "dry-
|
28
|
+
spec.add_runtime_dependency "dry-struct", "~> 0.1"
|
29
29
|
spec.add_runtime_dependency "dry-types", "~> 0.9"
|
30
30
|
spec.add_runtime_dependency "dry-validation", "~> 0.10"
|
31
31
|
spec.add_runtime_dependency "gli", "~> 2.15"
|
@@ -38,6 +38,8 @@ Gem::Specification.new do |spec|
|
|
38
38
|
spec.add_development_dependency "rspec", "~> 3.5"
|
39
39
|
spec.add_development_dependency "rubocop", "~> 0.46"
|
40
40
|
spec.add_development_dependency "yard", "~> 0.9"
|
41
|
+
spec.add_development_dependency "simplecov", "~> 0.13"
|
42
|
+
spec.add_development_dependency "webmock", "~> 2.3"
|
41
43
|
|
42
44
|
case Gem::Platform.local.os
|
43
45
|
when "linux"
|
@@ -4,12 +4,15 @@ require_relative "../../profile_configuration"
|
|
4
4
|
class AwsAssumeRole::Cli::Actions::AbstractAction
|
5
5
|
include AwsAssumeRole
|
6
6
|
include AwsAssumeRole::Types
|
7
|
-
include Ui
|
7
|
+
include AwsAssumeRole::Ui
|
8
|
+
include AwsAssumeRole::Logging
|
8
9
|
CommandSchema = proc { raise "CommandSchema Not implemented" }
|
9
10
|
|
10
11
|
def initialize(global_options, options, args)
|
11
12
|
config = ProfileConfiguration.new_from_cli(global_options, options, args)
|
12
|
-
|
13
|
+
logger.debug "Config initialized with #{config.to_hash}"
|
14
|
+
result = validate_options(config.to_hash)
|
15
|
+
logger.debug "Config validated as #{result.to_hash}"
|
13
16
|
return act_on(config) if result.success?
|
14
17
|
Ui.show_validation_errors result
|
15
18
|
end
|
@@ -17,8 +20,9 @@ class AwsAssumeRole::Cli::Actions::AbstractAction
|
|
17
20
|
private
|
18
21
|
|
19
22
|
def try_for_credentials(config)
|
20
|
-
@provider ||= AwsAssumeRole::Credentials::Factories::DefaultChainProvider.new(config.
|
23
|
+
@provider ||= AwsAssumeRole::Credentials::Factories::DefaultChainProvider.new(config.to_hash)
|
21
24
|
creds = @provider.resolve(nil_with_role_not_set: true)
|
25
|
+
logger.debug "Got credentials #{creds}"
|
22
26
|
return creds unless creds.nil?
|
23
27
|
rescue NoMethodError
|
24
28
|
error "Cannot find any credentials"
|
@@ -1,13 +1,5 @@
|
|
1
|
-
|
2
|
-
require "aws-sdk"
|
3
|
-
require "dry-types"
|
1
|
+
require_relative "../includes"
|
4
2
|
require_relative "../../types"
|
5
|
-
require "dry-validation"
|
6
|
-
require "active_support/core_ext/hash/compact"
|
7
|
-
require "active_support/core_ext/hash/keys"
|
8
|
-
require "launchy"
|
9
|
-
require "open-uri"
|
10
|
-
require "json"
|
11
3
|
require_relative "../../../aws_assume_role"
|
12
4
|
|
13
5
|
module AwsAssumeRole
|
@@ -20,7 +20,7 @@ class AwsAssumeRole::Cli::Actions::Run < AwsAssumeRole::Cli::Actions::AbstractAc
|
|
20
20
|
def act_on(config)
|
21
21
|
credentials = try_for_credentials config.to_h
|
22
22
|
unless config.args.empty?
|
23
|
-
Runner.new(config.args,
|
23
|
+
Runner.new(command: config.args,
|
24
24
|
environment: { "AWS_DEFAULT_REGION" => resolved_region },
|
25
25
|
credentials: credentials)
|
26
26
|
end
|
@@ -17,7 +17,9 @@ class AwsAssumeRole::Cli::Actions::Test < AwsAssumeRole::Cli::Actions::AbstractA
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def act_on(config)
|
20
|
-
|
20
|
+
logger.debug "Will try for credentials"
|
21
|
+
credentials = try_for_credentials config
|
22
|
+
logger.debug "Got credentials #{credentials}"
|
21
23
|
client = Aws::STS::Client.new(credentials: credentials, region: resolved_region)
|
22
24
|
identity = client.get_caller_identity
|
23
25
|
out format(t("commands.test.output"), identity.account, identity.arn, identity.user_id)
|
@@ -0,0 +1 @@
|
|
1
|
+
require_relative "../includes"
|
@@ -15,7 +15,7 @@ class AwsAssumeRole::Credentials::Factories::AbstractFactory
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def self.type(str)
|
18
|
-
@type = Types::Strict::Symbol.enum(:credential_provider, :second_factor_provider, :
|
18
|
+
@type = Types::Strict::Symbol.enum(:credential_provider, :second_factor_provider, :instance_role_provider)[str]
|
19
19
|
register_if_complete
|
20
20
|
end
|
21
21
|
|
@@ -4,11 +4,14 @@ require_relative "../providers/mfa_session_credentials"
|
|
4
4
|
|
5
5
|
class AwsAssumeRole::Credentials::Factories::AssumeRole < AwsAssumeRole::Credentials::Factories::AbstractFactory
|
6
6
|
include AwsAssumeRole::Credentials::Factories
|
7
|
-
type :
|
8
|
-
priority
|
7
|
+
type :credential_provider
|
8
|
+
priority 20
|
9
9
|
|
10
10
|
def initialize(options)
|
11
|
+
logger.debug "AwsAssumeRole::Credentials::Factories::AssumeRole initiated with #{options}"
|
12
|
+
return unless options[:profile] || options[:role_arn]
|
11
13
|
if options[:profile]
|
14
|
+
logger.debug "AwsAssumeRole: #{options[:profile]} found. Trying with profile"
|
12
15
|
try_with_profile(options)
|
13
16
|
else
|
14
17
|
if options[:use_mfa]
|
@@ -19,20 +22,16 @@ class AwsAssumeRole::Credentials::Factories::AssumeRole < AwsAssumeRole::Credent
|
|
19
22
|
end
|
20
23
|
|
21
24
|
def try_with_profile(options)
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
@
|
28
|
-
@region ||= AwsAssumeRole.shared_config.profile_region(@profiles)
|
25
|
+
return unless AwsAssumeRole.shared_config.config_enabled?
|
26
|
+
logger.debug "AwsAssumeRole: Shared Config enabled"
|
27
|
+
@profile = options[:profile]
|
28
|
+
@region = options[:region]
|
29
|
+
@credentials = assume_role_with_profile(options)
|
30
|
+
@region ||= AwsAssumeRole.shared_config.profile_region(@profile)
|
29
31
|
@role_arn ||= AwsAssumeRole.shared_config.profile_role(@profile)
|
30
32
|
end
|
31
33
|
|
32
|
-
def assume_role_with_profile(
|
33
|
-
AwsAssumeRole.shared_config.assume_role_credentials_from_config(
|
34
|
-
profile: prof,
|
35
|
-
region: region,
|
36
|
-
)
|
34
|
+
def assume_role_with_profile(options)
|
35
|
+
AwsAssumeRole.shared_config.assume_role_credentials_from_config(options)
|
37
36
|
end
|
38
37
|
end
|
@@ -6,77 +6,83 @@ require_relative "environment"
|
|
6
6
|
require_relative "repository"
|
7
7
|
require_relative "instance_profile"
|
8
8
|
require_relative "assume_role"
|
9
|
-
require_relative "shared_keyring"
|
10
9
|
require_relative "shared"
|
11
10
|
require_relative "static"
|
12
11
|
|
13
|
-
class AwsAssumeRole::Credentials::Factories::DefaultChainProvider
|
14
|
-
|
12
|
+
class AwsAssumeRole::Credentials::Factories::DefaultChainProvider < Dry::Struct
|
13
|
+
constructor_type :schema
|
15
14
|
include AwsAssumeRole::Credentials::Factories
|
15
|
+
include AwsAssumeRole::Logging
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
17
|
+
attribute :access_key_id, Dry::Types["strict.string"].optional
|
18
|
+
attribute :credentials, Dry::Types["object"].optional
|
19
|
+
attribute :secret_access_key, Dry::Types["strict.string"].optional
|
20
|
+
attribute :session_token, Dry::Types["strict.string"].optional
|
21
|
+
attribute :duration_seconds, Dry::Types["coercible.int"].optional
|
22
|
+
attribute :external_id, Dry::Types["strict.string"].optional
|
23
|
+
attribute :persist_session, Dry::Types["strict.bool"].default(true)
|
24
|
+
attribute :path, Dry::Types["strict.string"].optional
|
25
|
+
attribute :profile, Dry::Types["strict.string"].optional
|
26
|
+
attribute :profile_name, Dry::Types["strict.string"].optional
|
27
|
+
attribute :region, Dry::Types["strict.string"].optional
|
28
|
+
attribute :role_arn, Dry::Types["strict.string"].optional
|
29
|
+
attribute :role_session_name, Dry::Types["strict.string"].optional
|
30
|
+
attribute :serial_number, Dry::Types["strict.string"].optional
|
31
|
+
attribute :mfa_serial, Dry::Types["strict.string"].optional
|
32
|
+
attribute :use_mfa, Dry::Types["strict.bool"].default(false)
|
33
|
+
attribute :no_profile, Dry::Types["strict.bool"].default(false)
|
34
|
+
attribute :source_profile, Dry::Types["strict.string"].optional
|
35
|
+
attribute :instance_profile_credentials_retries, Dry::Types["strict.int"].default(0)
|
36
|
+
attribute :instance_profile_credentials_timeout, Dry::Types["coercible.float"].default(1.0)
|
35
37
|
|
36
|
-
def
|
37
|
-
if options
|
38
|
-
|
38
|
+
def self.new(options)
|
39
|
+
if options.respond_to? :resolve
|
40
|
+
finalize_instance new_with_seahorse(options)
|
39
41
|
else
|
40
|
-
|
42
|
+
finalize_instance(options)
|
41
43
|
end
|
42
|
-
|
43
|
-
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.finalize_instance(options)
|
47
|
+
new_opts = options.to_h
|
48
|
+
new_opts[:profile_name] ||= new_opts[:profile]
|
49
|
+
new_opts[:original_profile] = new_opts[:profile_name]
|
50
|
+
instance = allocate
|
51
|
+
instance.send(:initialize, new_opts)
|
52
|
+
instance
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.new_with_seahorse(resolver)
|
56
|
+
keys = resolver.resolve
|
57
|
+
options = keys.map do |k|
|
58
|
+
[k, resolver.send(k)]
|
59
|
+
end
|
60
|
+
finalize_instance(options.to_h)
|
44
61
|
end
|
45
62
|
|
46
63
|
def resolve(nil_with_role_not_set: false, explicit_default_profile: false)
|
47
64
|
resolve_final_credentials(explicit_default_profile)
|
48
|
-
nil_creds = Aws::Credentials.new(nil, nil, nil)
|
49
|
-
return
|
65
|
+
# nil_creds = Aws::Credentials.new(nil, nil, nil)
|
66
|
+
return nil if (nil_with_role_not_set &&
|
50
67
|
@role_arn &&
|
51
68
|
@credentials.credentials.session_token.nil?) || @credentials.nil?
|
52
69
|
@credentials
|
53
70
|
end
|
54
71
|
|
72
|
+
def to_h
|
73
|
+
to_hash
|
74
|
+
end
|
75
|
+
|
55
76
|
private
|
56
77
|
|
57
78
|
def resolve_final_credentials(explicit_default_profile = false)
|
58
79
|
resolve_credentials(:credential_provider, true, explicit_default_profile)
|
59
80
|
return @credentials if @credentials && @credentials.set? && !use_mfa && !role_arn
|
60
81
|
resolve_credentials(:second_factor_provider, true, explicit_default_profile)
|
61
|
-
return @credentials if @credentials && @credentials.set? && !role_arn
|
62
|
-
resolve_credentials(:role_assumption_provider, true, explicit_default_profile)
|
63
82
|
return @credentials if @credentials && @credentials.set?
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
def initialize_with_seahorse(resolver)
|
68
|
-
keys = resolver.resolve
|
69
|
-
options = keys.map do |k|
|
70
|
-
[k, resolver.send(k)]
|
71
|
-
end
|
72
|
-
__initialize__(options.to_h)
|
73
|
-
end
|
74
|
-
|
75
|
-
def to_h
|
76
|
-
instance_values.delete("__options__").symbolize_keys.merge(
|
77
|
-
instance_profile_credentials_retries: instance_profile_credentials_retries,
|
78
|
-
instance_profile_credentials_timeout: instance_profile_credentials_timeout,
|
79
|
-
)
|
83
|
+
resolve_credentials(:instance_role_provider, true, explicit_default_profile)
|
84
|
+
return @credentials if @credentials && @credentials.set?
|
85
|
+
nil
|
80
86
|
end
|
81
87
|
|
82
88
|
def resolve_credentials(type, break_if_successful = false, explicit_default_profile = false)
|
@@ -84,13 +90,16 @@ class AwsAssumeRole::Credentials::Factories::DefaultChainProvider
|
|
84
90
|
factories_to_try.each do |x|
|
85
91
|
options = to_h
|
86
92
|
options[:credentials] = credentials if credentials && credentials.set?
|
93
|
+
logger.debug "About to try credential lookup with #{x}"
|
87
94
|
factory = x.new(options)
|
88
95
|
@region ||= factory.region
|
89
96
|
@profile ||= factory.profile
|
90
97
|
@role_arn ||= factory.role_arn
|
91
98
|
next unless factory.credentials && factory.credentials.set?
|
99
|
+
logger.debug "Profile currently #{@profile}"
|
92
100
|
next if explicit_default_profile && (@profile == "default") && (@profile != @original_profile)
|
93
101
|
@credentials ||= factory.credentials
|
102
|
+
logger.debug "Got #{@credentials}"
|
94
103
|
break if break_if_successful
|
95
104
|
end
|
96
105
|
end
|
@@ -1,17 +1,13 @@
|
|
1
|
-
|
2
|
-
require "dry-types"
|
3
|
-
require "aws-sdk"
|
1
|
+
require_relative "../includes"
|
4
2
|
require_relative "../../logging"
|
5
3
|
require_relative "../../vendored/aws"
|
6
4
|
require_relative "../../../aws_assume_role"
|
7
5
|
|
8
|
-
module AwsAssumeRole
|
9
|
-
module
|
10
|
-
module
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
include AwsAssumeRole::Vendored::Aws
|
15
|
-
end
|
6
|
+
module AwsAssumeRole::Credentials
|
7
|
+
module Factories
|
8
|
+
Types = Dry::Types.module
|
9
|
+
include AwsAssumeRole
|
10
|
+
include AwsAssumeRole::Logging
|
11
|
+
include AwsAssumeRole::Vendored::Aws
|
16
12
|
end
|
17
13
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require_relative "abstract_factory"
|
2
2
|
|
3
3
|
class AwsAssumeRole::Credentials::Factories::InstanceProfile < AwsAssumeRole::Credentials::Factories::AbstractFactory
|
4
|
-
type :
|
4
|
+
type :instance_role_provider
|
5
5
|
priority 40
|
6
6
|
|
7
7
|
def initialize(options = {})
|
@@ -9,7 +9,7 @@ class AwsAssumeRole::Credentials::Factories::Repository
|
|
9
9
|
FactoryRepositoryType = Types::Hash.schema(
|
10
10
|
credential_provider: SubFactoryRepositoryType,
|
11
11
|
second_factor_provider: SubFactoryRepositoryType,
|
12
|
-
|
12
|
+
instance_role_provider: SubFactoryRepositoryType,
|
13
13
|
)
|
14
14
|
|
15
15
|
def self.factories
|
@@ -20,7 +20,7 @@ class AwsAssumeRole::Credentials::Factories::Repository
|
|
20
20
|
@repository ||= FactoryRepositoryType[
|
21
21
|
credential_provider: {},
|
22
22
|
second_factor_provider: {},
|
23
|
-
|
23
|
+
instance_role_provider: {},
|
24
24
|
]
|
25
25
|
end
|
26
26
|
|
@@ -1,14 +1,16 @@
|
|
1
1
|
require_relative "abstract_factory"
|
2
|
+
require_relative "../providers/shared_keyring_credentials"
|
2
3
|
|
3
4
|
class AwsAssumeRole::Credentials::Factories::Shared < AwsAssumeRole::Credentials::Factories::AbstractFactory
|
4
5
|
type :credential_provider
|
5
|
-
priority
|
6
|
+
priority 30
|
6
7
|
|
7
8
|
def initialize(options = {})
|
8
|
-
|
9
|
-
@
|
10
|
-
@
|
11
|
-
@
|
9
|
+
logger.debug "Shared Factory initiated with #{options}"
|
10
|
+
@profile = options[:profile]
|
11
|
+
@credentials = AwsAssumeRole::Credentials::Providers::SharedKeyringCredentials.new(options)
|
12
|
+
@region = @credentials.region
|
13
|
+
@role_arn = @credentials.role_arn
|
12
14
|
rescue Aws::Errors::NoSuchProfileError
|
13
15
|
nil
|
14
16
|
end
|
@@ -1,9 +1,7 @@
|
|
1
|
+
require_relative "../includes"
|
1
2
|
require_relative "../../vendored/aws"
|
2
3
|
require_relative "../../ui"
|
3
4
|
require_relative "../../logging"
|
4
|
-
module AwsAssumeRole
|
5
|
-
module
|
6
|
-
module Providers
|
7
|
-
end
|
8
|
-
end
|
5
|
+
module AwsAssumeRole::Credentials
|
6
|
+
module Providers end
|
9
7
|
end
|
@@ -1,32 +1,29 @@
|
|
1
1
|
require_relative "includes"
|
2
2
|
require_relative "../../types"
|
3
|
+
require_relative "../../configuration"
|
3
4
|
|
4
|
-
class AwsAssumeRole::Credentials::Providers::MfaSessionCredentials
|
5
|
+
class AwsAssumeRole::Credentials::Providers::MfaSessionCredentials < Dry::Struct
|
6
|
+
constructor_type :schema
|
5
7
|
include AwsAssumeRole::Vendored::Aws::CredentialProvider
|
6
8
|
include AwsAssumeRole::Vendored::Aws::RefreshingCredentials
|
7
9
|
include AwsAssumeRole::Ui
|
8
10
|
include AwsAssumeRole::Logging
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
option :region, type: AwsAssumeRole::Types::Region.optional, default: proc { AwsAssumeRole.Config.region }
|
22
|
-
option :serial_number, type: AwsAssumeRole::Types::MfaSerial.optional, default: proc { "automatic" }
|
23
|
-
|
24
|
-
def initialize(*options)
|
25
|
-
super(*options)
|
11
|
+
|
12
|
+
attribute :permanent_credentials, Dry::Types["object"].optional
|
13
|
+
attribute :credentials, Dry::Types["object"].optional
|
14
|
+
attribute :expiration, Dry::Types["strict.time"].default(Time.now)
|
15
|
+
attribute :first_time, Dry::Types["strict.bool"].default(true)
|
16
|
+
attribute :persist_session, Dry::Types["strict.bool"].default(true)
|
17
|
+
attribute :duration_seconds, Dry::Types["coercible.int"].default(3600)
|
18
|
+
attribute :region, AwsAssumeRole::Types::Region.optional
|
19
|
+
attribute :serial_number, AwsAssumeRole::Types::MfaSerial.optional.default("automatic")
|
20
|
+
|
21
|
+
def initialize(options)
|
22
|
+
options.each { |key, value| instance_variable_set("@#{key}", value) }
|
26
23
|
@permanent_credentials ||= credentials
|
27
24
|
@credentials = nil
|
28
25
|
@serial_number = resolve_serial_number(serial_number)
|
29
|
-
AwsAssumeRole::Vendored::Aws::RefreshingCredentials.instance_method(:initialize).bind(self).call(
|
26
|
+
AwsAssumeRole::Vendored::Aws::RefreshingCredentials.instance_method(:initialize).bind(self).call(options)
|
30
27
|
end
|
31
28
|
|
32
29
|
private
|
@@ -67,14 +64,15 @@ class AwsAssumeRole::Credentials::Providers::MfaSessionCredentials
|
|
67
64
|
end
|
68
65
|
|
69
66
|
def credentials_from_keyring
|
70
|
-
@credentials_from_keyring ||= AwsAssumeRole::Store::Keyring.fetch
|
67
|
+
@credentials_from_keyring ||= AwsAssumeRole::Store::Keyring.fetch keyring_username
|
71
68
|
rescue Aws::Errors::NoSuchProfileError
|
72
69
|
logger.debug "Key not found"
|
73
70
|
@credentials_from_keyring = nil
|
71
|
+
return nil
|
74
72
|
end
|
75
73
|
|
76
74
|
def persist_credentials
|
77
|
-
AwsAssumeRole::Store::Keyring.save_credentials
|
75
|
+
AwsAssumeRole::Store::Keyring.save_credentials keyring_username, @credentials, expiration: @expiration
|
78
76
|
end
|
79
77
|
|
80
78
|
def instance_credentials(credentials)
|
@@ -84,7 +82,7 @@ class AwsAssumeRole::Credentials::Providers::MfaSessionCredentials
|
|
84
82
|
end
|
85
83
|
|
86
84
|
def set_credentials_from_keyring
|
87
|
-
instance_credentials credentials_from_keyring
|
85
|
+
instance_credentials credentials_from_keyring if credentials_from_keyring
|
88
86
|
initialized
|
89
87
|
refresh_using_mfa unless @credentials && !near_expiration?
|
90
88
|
end
|
@@ -98,5 +96,4 @@ class AwsAssumeRole::Credentials::Providers::MfaSessionCredentials
|
|
98
96
|
user_name = identity.arn.split("/")[1]
|
99
97
|
"arn:aws:iam::#{identity.account}:mfa/#{user_name}"
|
100
98
|
end
|
101
|
-
Dry::Types.register_class(self)
|
102
99
|
end
|
@@ -2,21 +2,38 @@ require_relative "includes"
|
|
2
2
|
require_relative "../../types"
|
3
3
|
|
4
4
|
class AwsAssumeRole::Credentials::Providers::SharedKeyringCredentials < ::Aws::SharedCredentials
|
5
|
+
include AwsAssumeRole::Logging
|
6
|
+
attr_reader :region, :role_arn
|
7
|
+
|
5
8
|
def initialize(options = {})
|
6
|
-
|
9
|
+
logger.debug "SharedKeyringCredentials initiated with #{options}"
|
7
10
|
@path = options[:path]
|
8
|
-
@path ||= shared_config.credentials_path
|
9
|
-
@profile_name = options[:profile_name]
|
11
|
+
@path ||= AwsAssumeRole.shared_config.credentials_path
|
12
|
+
@profile_name = options[:profile_name] ||= options[:profile]
|
10
13
|
@profile_name ||= ENV["AWS_PROFILE"]
|
11
|
-
@profile_name ||= shared_config.profile_name
|
12
|
-
|
13
|
-
|
14
|
+
@profile_name ||= AwsAssumeRole.shared_config.profile_name
|
15
|
+
logger.debug "SharedKeyringCredentials resolved profile name #{@profile_name}"
|
16
|
+
config = determine_config(@path, @profile_name)
|
17
|
+
@role_arn = config.profile_hash(@profile_name)
|
18
|
+
@region = config.profile_region(@profile_name)
|
19
|
+
@role_arn = config.profile_role(@profile_name)
|
20
|
+
attempted_credential = config.credentials(options)
|
21
|
+
return unless attempted_credential && attempted_credential.set?
|
22
|
+
@credentials = attempted_credential
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def determine_config(path, profile_name)
|
28
|
+
if path && path == AwsAssumeRole.shared_config.credentials_path
|
29
|
+
logger.debug "SharedKeyringCredentials found shared credential path"
|
30
|
+
AwsAssumeRole.shared_config
|
14
31
|
else
|
15
|
-
|
16
|
-
|
17
|
-
|
32
|
+
logger.debug "SharedKeyringCredentials found custom credential path"
|
33
|
+
AwsAssumeRole::Store::SharedConfigWithKeyring.new(
|
34
|
+
credentials_path: path,
|
35
|
+
profile_name: profile_name,
|
18
36
|
)
|
19
|
-
@credentials = config.credentials(profile: @profile_name)
|
20
37
|
end
|
21
38
|
end
|
22
39
|
end
|
@@ -1,13 +1,14 @@
|
|
1
1
|
require "i18n"
|
2
|
-
require "
|
2
|
+
require "active_support/json"
|
3
3
|
require "active_support/core_ext/object/blank"
|
4
4
|
require "active_support/core_ext/string/inflections"
|
5
|
+
require "active_support/core_ext/hash/compact"
|
5
6
|
require "active_support/core_ext/hash/keys"
|
6
|
-
require "active_support/core_ext/
|
7
|
+
require "active_support/core_ext/hash/slice"
|
7
8
|
require "aws-sdk"
|
8
9
|
require "aws-sdk-core/ini_parser"
|
9
10
|
require "dry-configurable"
|
10
|
-
require "dry-
|
11
|
+
require "dry-struct"
|
11
12
|
require "dry-validation"
|
12
13
|
require "dry-types"
|
13
14
|
require "English"
|
@@ -15,8 +16,13 @@ require "gli"
|
|
15
16
|
require "highline"
|
16
17
|
require "inifile"
|
17
18
|
require "json"
|
19
|
+
require "keyring"
|
20
|
+
require "launchy"
|
18
21
|
require "logger"
|
22
|
+
require "open-uri"
|
19
23
|
require "pastel"
|
24
|
+
require "securerandom"
|
25
|
+
require "set"
|
20
26
|
require "thread"
|
21
27
|
require "time"
|
22
28
|
|
@@ -1,29 +1,30 @@
|
|
1
1
|
require_relative "includes"
|
2
2
|
require_relative "logging"
|
3
3
|
|
4
|
-
class AwsAssumeRole::ProfileConfiguration
|
5
|
-
|
4
|
+
class AwsAssumeRole::ProfileConfiguration < Dry::Struct
|
5
|
+
constructor_type :schema
|
6
6
|
include AwsAssumeRole::Logging
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
7
|
+
attribute :access_key_id, Dry::Types["strict.string"].optional
|
8
|
+
attribute :credentials, Dry::Types["object"].optional
|
9
|
+
attribute :secret_access_key, Dry::Types["strict.string"].optional
|
10
|
+
attribute :session_token, Dry::Types["strict.string"].optional
|
11
|
+
attribute :duration_seconds, Dry::Types["coercible.int"].optional
|
12
|
+
attribute :external_id, Dry::Types["strict.string"].optional
|
13
|
+
attribute :path, Dry::Types["strict.string"].optional
|
14
|
+
attribute :persist_session, Dry::Types["strict.bool"].optional.default(true)
|
15
|
+
attribute :profile, Dry::Types["strict.string"].optional
|
16
|
+
attribute :region, Dry::Types["strict.string"].optional
|
17
|
+
attribute :role_arn, Dry::Types["strict.string"].optional
|
18
|
+
attribute :role_session_name, Dry::Types["strict.string"].optional
|
19
|
+
attribute :serial_number, Dry::Types["strict.string"].optional
|
20
|
+
attribute :mfa_serial, Dry::Types["strict.string"].optional
|
21
|
+
attribute :use_mfa, Dry::Types["strict.bool"].optional.default(false)
|
22
|
+
attribute :no_profile, Dry::Types["strict.bool"].optional.default(false)
|
23
|
+
attribute :shell_type, Dry::Types["strict.string"].optional
|
24
|
+
attribute :source_profile, Dry::Types["strict.string"].optional
|
25
|
+
attribute :args, Dry::Types["strict.array"].optional.default([])
|
26
|
+
attribute :instance_profile_credentials_retries, Dry::Types["strict.int"].default(0)
|
27
|
+
attribute :instance_profile_credentials_timeout, Dry::Types["coercible.float"].default(1.0)
|
27
28
|
|
28
29
|
attr_writer :credentials
|
29
30
|
|
@@ -64,8 +65,6 @@ class AwsAssumeRole::ProfileConfiguration
|
|
64
65
|
end
|
65
66
|
|
66
67
|
def to_h
|
67
|
-
|
68
|
+
to_hash
|
68
69
|
end
|
69
|
-
|
70
|
-
Dry::Types.register_class(self)
|
71
70
|
end
|
@@ -1,18 +1,17 @@
|
|
1
1
|
require_relative "includes"
|
2
2
|
require_relative "logging"
|
3
3
|
|
4
|
-
class AwsAssumeRole::Runner
|
4
|
+
class AwsAssumeRole::Runner < Dry::Struct
|
5
5
|
include AwsAssumeRole::Logging
|
6
|
-
|
6
|
+
constructor_type :schema
|
7
|
+
attribute :command, Dry::Types["coercible.array"].member(Dry::Types["strict.string"]).default([])
|
8
|
+
attribute :exit_on_error, Dry::Types["strict.bool"].default(true)
|
9
|
+
attribute :expected_exit_code, Dry::Types["strict.int"].default(0)
|
10
|
+
attribute :environment, Dry::Types["strict.hash"].default({})
|
11
|
+
attribute :credentials, Dry::Types["object"].optional
|
7
12
|
|
8
|
-
|
9
|
-
|
10
|
-
option :expected_exit_code, Dry::Types["strict.int"], default: proc { 0 }
|
11
|
-
option :environment, Dry::Types["strict.hash"], default: proc { {} }
|
12
|
-
option :credentials, optional: true
|
13
|
-
|
14
|
-
def initialize(params, options = {})
|
15
|
-
super(params, options)
|
13
|
+
def initialize(options)
|
14
|
+
super(options)
|
16
15
|
command_to_exec = command.join(" ")
|
17
16
|
process_credentials unless credentials.blank?
|
18
17
|
system environment, command_to_exec
|
@@ -1,14 +1,4 @@
|
|
1
|
-
|
2
|
-
require "active_support/core_ext/string/inflections"
|
3
|
-
require "active_support/core_ext/hash/slice"
|
4
|
-
require "active_support/json"
|
5
|
-
require "aws-sdk"
|
6
|
-
require "aws-sdk-core/ini_parser"
|
7
|
-
require "inifile"
|
8
|
-
require "json"
|
9
|
-
require "keyring"
|
10
|
-
require "time"
|
11
|
-
require "securerandom"
|
1
|
+
require_relative "../includes"
|
12
2
|
|
13
3
|
module AwsAssumeRole
|
14
4
|
module Store
|
@@ -38,8 +38,7 @@ module AwsAssumeRole::Store::Keyring
|
|
38
38
|
def fetch(id, backend: nil)
|
39
39
|
logger.debug "Fetching #{id} from keyring"
|
40
40
|
fetched = keyring(backend).get_password(KEYRING_KEY, id)
|
41
|
-
|
42
|
-
raise Aws::Errors::NoSuchProfileError unless fetched
|
41
|
+
raise Aws::Errors::NoSuchProfileError if fetched == "null" || fetched.nil? || !fetched
|
43
42
|
JSON.parse(fetched, symbolize_names: true)
|
44
43
|
end
|
45
44
|
|
@@ -10,14 +10,51 @@ class AwsAssumeRole::Store::SharedConfigWithKeyring < AwsAssumeRole::Vendored::A
|
|
10
10
|
|
11
11
|
attr_reader :parsed_config
|
12
12
|
|
13
|
+
# @param [Hash] options
|
14
|
+
# @option options [String] :credentials_path Path to the shared credentials
|
15
|
+
# file. Defaults to "#{Dir.home}/.aws/credentials".
|
16
|
+
# @option options [String] :config_path Path to the shared config file.
|
17
|
+
# Defaults to "#{Dir.home}/.aws/config".
|
18
|
+
# @option options [String] :profile_name The credential/config profile name
|
19
|
+
# to use. If not specified, will check `ENV['AWS_PROFILE']` before using
|
20
|
+
# the fixed default value of 'default'.
|
21
|
+
# @option options [Boolean] :config_enabled If true, loads the shared config
|
22
|
+
# file and enables new config values outside of the old shared credential
|
23
|
+
# spec.
|
13
24
|
def initialize(options = {})
|
14
|
-
|
15
|
-
@config_enabled =
|
16
|
-
@
|
17
|
-
|
25
|
+
@profile_name = determine_profile(options)
|
26
|
+
@config_enabled = options[:config_enabled]
|
27
|
+
@credentials_path = options[:credentials_path] ||
|
28
|
+
determine_credentials_path
|
29
|
+
@parsed_credentials = {}
|
30
|
+
load_credentials_file if loadable?(@credentials_path)
|
31
|
+
return unless @config_enabled
|
32
|
+
@config_path = options[:config_path] || determine_config_path
|
33
|
+
load_config_file if loadable?(@config_path)
|
34
|
+
end
|
35
|
+
|
36
|
+
# @api private
|
37
|
+
def fresh(options = {})
|
38
|
+
@configuration = nil
|
39
|
+
@semaphore = nil
|
40
|
+
@assume_role_shared_config = nil
|
41
|
+
@profile_name = nil
|
42
|
+
@credentials_path = nil
|
43
|
+
@config_path = nil
|
44
|
+
@parsed_credentials = {}
|
45
|
+
@parsed_config = nil
|
46
|
+
@config_enabled = options[:config_enabled] ? true : false
|
47
|
+
@profile_name = determine_profile(options)
|
48
|
+
@credentials_path = options[:credentials_path] ||
|
49
|
+
determine_credentials_path
|
50
|
+
load_credentials_file if loadable?(@credentials_path)
|
51
|
+
return unless @config_enabled
|
52
|
+
@config_path = options[:config_path] || determine_config_path
|
53
|
+
load_config_file if loadable?(@config_path)
|
18
54
|
end
|
19
55
|
|
20
56
|
def credentials(opts = {})
|
57
|
+
logger.debug "SharedConfigWithKeyring asked for credentials with opts #{opts}"
|
21
58
|
p = opts[:profile] || @profile_name
|
22
59
|
validate_profile_exists(p) if credentials_present?
|
23
60
|
credentials_from_keyring(p, opts) || credentials_from_shared(p, opts) || credentials_from_config(p, opts)
|
@@ -59,20 +96,15 @@ class AwsAssumeRole::Store::SharedConfigWithKeyring < AwsAssumeRole::Vendored::A
|
|
59
96
|
end
|
60
97
|
|
61
98
|
def profile_region(profile_name)
|
62
|
-
|
63
|
-
resolve_region(@parsed_config, prof_cfg)
|
99
|
+
resolve_profile_parameter(profile_name, "region")
|
64
100
|
end
|
65
101
|
|
66
102
|
def profile_role(profile_name)
|
67
|
-
|
68
|
-
resolve_arn(@parsed_config, prof_cfg)
|
103
|
+
resolve_profile_parameter(profile_name, "role_arn")
|
69
104
|
end
|
70
105
|
|
71
|
-
def
|
72
|
-
|
73
|
-
ret ||= ENV["AWS_PROFILE"]
|
74
|
-
ret ||= "default"
|
75
|
-
ret
|
106
|
+
def profile_hash(profile_name)
|
107
|
+
{} || @parsed_config[profile_key(profile_name)]
|
76
108
|
end
|
77
109
|
|
78
110
|
private
|
@@ -86,21 +118,32 @@ class AwsAssumeRole::Store::SharedConfigWithKeyring < AwsAssumeRole::Vendored::A
|
|
86
118
|
end
|
87
119
|
end
|
88
120
|
|
89
|
-
def
|
121
|
+
def resolve_profile_parameter(profile_name, param)
|
122
|
+
return unless @parsed_config
|
123
|
+
prof_cfg = @parsed_config[profile_key(profile_name)]
|
124
|
+
resolve_parameter(param, @parsed_config, prof_cfg)
|
125
|
+
end
|
126
|
+
|
127
|
+
def resolve_parameter(param, cfg, prof_cfg)
|
90
128
|
return unless prof_cfg && cfg
|
91
|
-
return prof_cfg[
|
92
|
-
|
93
|
-
|
129
|
+
return prof_cfg[param] if prof_cfg.key? param
|
130
|
+
source_profile = prof_cfg["source_profile"]
|
131
|
+
return unless source_profile
|
132
|
+
source_cfg = cfg[source_profile]
|
133
|
+
return unless source_cfg
|
134
|
+
cfg[prof_cfg["source_profile"]][param] if source_cfg.key?(param)
|
135
|
+
end
|
136
|
+
|
137
|
+
def resolve_region(cfg, prof_cfg)
|
138
|
+
resolve_parameter("region", cfg, prof_cfg)
|
94
139
|
end
|
95
140
|
|
96
141
|
def resolve_arn(cfg, prof_cfg)
|
97
|
-
|
98
|
-
return prof_cfg["role_arn"] if prof_cfg.key? "role_arn"
|
99
|
-
source_cfg = cfg[prof_cfg["source_profile"]]
|
100
|
-
cfg[prof_cfg["source_profile"]]["role_arn"] if source_cfg && source_cfg.key?("role_arn")
|
142
|
+
resolve_parameter("role_arn", cfg, prof_cfg)
|
101
143
|
end
|
102
144
|
|
103
145
|
def assume_role_from_profile(cfg, profile, opts)
|
146
|
+
logger.debug "Entering assume_role_from_profile with #{cfg}, #{profile}, #{opts}"
|
104
147
|
prof_cfg = cfg[profile]
|
105
148
|
return unless cfg && prof_cfg
|
106
149
|
opts[:source_profile] ||= prof_cfg["source_profile"]
|
@@ -133,7 +176,7 @@ class AwsAssumeRole::Store::SharedConfigWithKeyring < AwsAssumeRole::Vendored::A
|
|
133
176
|
def mfa_session(cfg, profile, opts)
|
134
177
|
prof_cfg = cfg[profile]
|
135
178
|
return unless cfg && prof_cfg
|
136
|
-
opts[:serial_number] ||= prof_cfg["mfa_serial"]
|
179
|
+
opts[:serial_number] ||= opts[:mfa_serial] || prof_cfg["mfa_serial"]
|
137
180
|
opts[:source_profile] ||= prof_cfg["source_profile"]
|
138
181
|
opts[:region] ||= profile_region(profile)
|
139
182
|
return unless opts[:serial_number]
|
@@ -141,11 +184,26 @@ class AwsAssumeRole::Store::SharedConfigWithKeyring < AwsAssumeRole::Vendored::A
|
|
141
184
|
AwsAssumeRole::Credentials::Providers::MfaSessionCredentials.new(opts)
|
142
185
|
end
|
143
186
|
|
144
|
-
def credentials_from_keyring(profile,
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
187
|
+
def credentials_from_keyring(profile, opts)
|
188
|
+
logger.debug "Entering credentials_from_keyring"
|
189
|
+
return unless @parsed_config
|
190
|
+
logger.debug "credentials_from_keyring: @parsed_config found"
|
191
|
+
prof_cfg = @parsed_config[profile]
|
192
|
+
return unless prof_cfg
|
193
|
+
logger.debug "credentials_from_keyring: prof_cfg found"
|
194
|
+
opts[:serial_number] ||= opts[:mfa_serial] || prof_cfg[:mfa_serial] || prof_cfg[:serial_number]
|
195
|
+
if opts[:serial_number]
|
196
|
+
logger.debug "credentials_from_keyring detected mfa requirement"
|
197
|
+
mfa_session(@parsed_config, profile, opts)
|
198
|
+
else
|
199
|
+
logger.debug "Attempt to fetch #{profile} from keyring"
|
200
|
+
keyring_creds = Keyring.fetch(profile)
|
201
|
+
return unless keyring_creds
|
202
|
+
creds = Serialization.credentials_from_hash Keyring.fetch(profile)
|
203
|
+
creds if credentials_complete(creds)
|
204
|
+
end
|
205
|
+
rescue Aws::Errors::NoSourceProfileError, Aws::Errors::NoSuchProfileError
|
206
|
+
nil
|
149
207
|
end
|
150
208
|
|
151
209
|
def semaphore
|
@@ -170,6 +228,6 @@ module AwsAssumeRole
|
|
170
228
|
|
171
229
|
def shared_config
|
172
230
|
enabled = ENV["AWS_SDK_CONFIG_OPT_OUT"] ? false : true
|
173
|
-
@
|
231
|
+
@assume_role_shared_config ||= ::AwsAssumeRole::Store::SharedConfigWithKeyring.new(config_enabled: enabled)
|
174
232
|
end
|
175
233
|
end
|
@@ -2,6 +2,7 @@ require_relative "includes"
|
|
2
2
|
module AwsAssumeRole::Vendored::Aws
|
3
3
|
# @api private
|
4
4
|
class SharedConfig
|
5
|
+
include AwsAssumeRole::Logging
|
5
6
|
# @return [String]
|
6
7
|
attr_reader :credentials_path
|
7
8
|
|
@@ -102,9 +103,11 @@ module AwsAssumeRole::Vendored::Aws
|
|
102
103
|
# Will always attempt first to assume a role from the shared credentials
|
103
104
|
# file, if present.
|
104
105
|
def assume_role_credentials_from_config(opts = {})
|
106
|
+
logger.debug "Entered assume_role_credentials_from_config with #{opts}"
|
105
107
|
p = opts.delete(:profile) || @profile_name
|
106
108
|
credentials = assume_role_from_profile(@parsed_credentials, p, opts)
|
107
109
|
if @parsed_config
|
110
|
+
logger.debug "Parsed config loaded, testing"
|
108
111
|
credentials ||= assume_role_from_profile(@parsed_config, p, opts)
|
109
112
|
end
|
110
113
|
credentials
|
@@ -140,7 +143,7 @@ module AwsAssumeRole::Vendored::Aws
|
|
140
143
|
opts[:external_id] ||= prof_cfg["external_id"]
|
141
144
|
opts[:serial_number] ||= prof_cfg["mfa_serial"]
|
142
145
|
opts[:profile] = opts.delete(:source_profile)
|
143
|
-
|
146
|
+
AssumeRoleCredentials.new(opts)
|
144
147
|
else
|
145
148
|
raise ::Aws::Errors::NoSourceProfileError, "Profile #{profile} has a role_arn, and source_profile, but the"\
|
146
149
|
" source_profile does not have credentials."
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aws_assume_role
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jon Topper
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2017-02-
|
13
|
+
date: 2017-02-20 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
@@ -18,14 +18,14 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - "~>"
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: '4.
|
21
|
+
version: '4.2'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
26
|
- - "~>"
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
version: '4.
|
28
|
+
version: '4.2'
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
30
|
name: aws-sdk
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|
@@ -55,19 +55,19 @@ dependencies:
|
|
55
55
|
- !ruby/object:Gem::Version
|
56
56
|
version: '0.5'
|
57
57
|
- !ruby/object:Gem::Dependency
|
58
|
-
name: dry-
|
58
|
+
name: dry-struct
|
59
59
|
requirement: !ruby/object:Gem::Requirement
|
60
60
|
requirements:
|
61
61
|
- - "~>"
|
62
62
|
- !ruby/object:Gem::Version
|
63
|
-
version: '
|
63
|
+
version: '0.1'
|
64
64
|
type: :runtime
|
65
65
|
prerelease: false
|
66
66
|
version_requirements: !ruby/object:Gem::Requirement
|
67
67
|
requirements:
|
68
68
|
- - "~>"
|
69
69
|
- !ruby/object:Gem::Version
|
70
|
-
version: '
|
70
|
+
version: '0.1'
|
71
71
|
- !ruby/object:Gem::Dependency
|
72
72
|
name: dry-types
|
73
73
|
requirement: !ruby/object:Gem::Requirement
|
@@ -242,6 +242,34 @@ dependencies:
|
|
242
242
|
- - "~>"
|
243
243
|
- !ruby/object:Gem::Version
|
244
244
|
version: '0.9'
|
245
|
+
- !ruby/object:Gem::Dependency
|
246
|
+
name: simplecov
|
247
|
+
requirement: !ruby/object:Gem::Requirement
|
248
|
+
requirements:
|
249
|
+
- - "~>"
|
250
|
+
- !ruby/object:Gem::Version
|
251
|
+
version: '0.13'
|
252
|
+
type: :development
|
253
|
+
prerelease: false
|
254
|
+
version_requirements: !ruby/object:Gem::Requirement
|
255
|
+
requirements:
|
256
|
+
- - "~>"
|
257
|
+
- !ruby/object:Gem::Version
|
258
|
+
version: '0.13'
|
259
|
+
- !ruby/object:Gem::Dependency
|
260
|
+
name: webmock
|
261
|
+
requirement: !ruby/object:Gem::Requirement
|
262
|
+
requirements:
|
263
|
+
- - "~>"
|
264
|
+
- !ruby/object:Gem::Version
|
265
|
+
version: '2.3'
|
266
|
+
type: :development
|
267
|
+
prerelease: false
|
268
|
+
version_requirements: !ruby/object:Gem::Requirement
|
269
|
+
requirements:
|
270
|
+
- - "~>"
|
271
|
+
- !ruby/object:Gem::Version
|
272
|
+
version: '2.3'
|
245
273
|
- !ruby/object:Gem::Dependency
|
246
274
|
name: gir_ffi-gnome_keyring
|
247
275
|
requirement: !ruby/object:Gem::Requirement
|
@@ -275,6 +303,8 @@ extra_rdoc_files: []
|
|
275
303
|
files:
|
276
304
|
- ".gitignore"
|
277
305
|
- ".rubocop.yml"
|
306
|
+
- ".ruby-version"
|
307
|
+
- ".simplecov"
|
278
308
|
- ".travis.yml"
|
279
309
|
- Gemfile
|
280
310
|
- LICENSE.md
|
@@ -305,6 +335,7 @@ files:
|
|
305
335
|
- lib/aws_assume_role/cli/commands/migrate.rb
|
306
336
|
- lib/aws_assume_role/cli/commands/run.rb
|
307
337
|
- lib/aws_assume_role/cli/commands/test.rb
|
338
|
+
- lib/aws_assume_role/cli/includes.rb
|
308
339
|
- lib/aws_assume_role/configuration.rb
|
309
340
|
- lib/aws_assume_role/core_ext/aws-sdk/credential_provider_chain.rb
|
310
341
|
- lib/aws_assume_role/core_ext/aws-sdk/includes.rb
|
@@ -317,8 +348,8 @@ files:
|
|
317
348
|
- lib/aws_assume_role/credentials/factories/instance_profile.rb
|
318
349
|
- lib/aws_assume_role/credentials/factories/repository.rb
|
319
350
|
- lib/aws_assume_role/credentials/factories/shared.rb
|
320
|
-
- lib/aws_assume_role/credentials/factories/shared_keyring.rb
|
321
351
|
- lib/aws_assume_role/credentials/factories/static.rb
|
352
|
+
- lib/aws_assume_role/credentials/includes.rb
|
322
353
|
- lib/aws_assume_role/credentials/providers/assume_role_credentials.rb
|
323
354
|
- lib/aws_assume_role/credentials/providers/includes.rb
|
324
355
|
- lib/aws_assume_role/credentials/providers/mfa_session_credentials.rb
|
@@ -360,7 +391,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
360
391
|
version: '0'
|
361
392
|
requirements: []
|
362
393
|
rubyforge_project:
|
363
|
-
rubygems_version: 2.5
|
394
|
+
rubygems_version: 2.4.5
|
364
395
|
signing_key:
|
365
396
|
specification_version: 4
|
366
397
|
summary: Manage AWS STS credentials with MFA
|
@@ -1,16 +0,0 @@
|
|
1
|
-
require_relative "abstract_factory"
|
2
|
-
require_relative "../providers/shared_keyring_credentials"
|
3
|
-
|
4
|
-
class AwsAssumeRole::Credentials::Factories::SharedKeyring < AwsAssumeRole::Credentials::Factories::AbstractFactory
|
5
|
-
type :credential_provider
|
6
|
-
priority 19
|
7
|
-
|
8
|
-
def initialize(options = {})
|
9
|
-
@profile = options[:profile] || "default"
|
10
|
-
@credentials = AwsAssumeRole::Credentials::Providers::SharedKeyringCredentials.new(profile_name: @profile)
|
11
|
-
@region = AwsAssumeRole.shared_config.profile_region(@profile)
|
12
|
-
@role_arn = AwsAssumeRole.shared_config.profile_role(@profile)
|
13
|
-
rescue Aws::Errors::NoSuchProfileError
|
14
|
-
nil
|
15
|
-
end
|
16
|
-
end
|