aws_assume_role 1.1.0-universal-openbsd
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 +7 -0
- data/.gitignore +9 -0
- data/.rubocop.yml +57 -0
- data/.ruby-version +1 -0
- data/.simplecov +22 -0
- data/.travis.yml +24 -0
- data/CHANGELOG.md +61 -0
- data/Gemfile +18 -0
- data/LICENSE.md +201 -0
- data/README.md +303 -0
- data/Rakefile +63 -0
- data/aws_assume_role.gemspec +56 -0
- data/bin/aws-assume-role +4 -0
- data/i18n/en.yml +109 -0
- data/lib/aws_assume_role.rb +4 -0
- data/lib/aws_assume_role/cli.rb +20 -0
- data/lib/aws_assume_role/cli/actions/abstract_action.rb +61 -0
- data/lib/aws_assume_role/cli/actions/configure_profile.rb +24 -0
- data/lib/aws_assume_role/cli/actions/configure_role_assumption.rb +22 -0
- data/lib/aws_assume_role/cli/actions/console.rb +70 -0
- data/lib/aws_assume_role/cli/actions/delete_profile.rb +22 -0
- data/lib/aws_assume_role/cli/actions/includes.rb +12 -0
- data/lib/aws_assume_role/cli/actions/list_profiles.rb +12 -0
- data/lib/aws_assume_role/cli/actions/migrate_profile.rb +20 -0
- data/lib/aws_assume_role/cli/actions/reset_environment.rb +50 -0
- data/lib/aws_assume_role/cli/actions/run.rb +36 -0
- data/lib/aws_assume_role/cli/actions/set_environment.rb +62 -0
- data/lib/aws_assume_role/cli/actions/test.rb +35 -0
- data/lib/aws_assume_role/cli/commands/configure.rb +32 -0
- data/lib/aws_assume_role/cli/commands/console.rb +19 -0
- data/lib/aws_assume_role/cli/commands/delete.rb +13 -0
- data/lib/aws_assume_role/cli/commands/environment.rb +34 -0
- data/lib/aws_assume_role/cli/commands/list.rb +12 -0
- data/lib/aws_assume_role/cli/commands/migrate.rb +13 -0
- data/lib/aws_assume_role/cli/commands/run.rb +19 -0
- data/lib/aws_assume_role/cli/commands/test.rb +20 -0
- data/lib/aws_assume_role/cli/includes.rb +3 -0
- data/lib/aws_assume_role/configuration.rb +30 -0
- data/lib/aws_assume_role/core_ext/aws-sdk/credential_provider_chain.rb +4 -0
- data/lib/aws_assume_role/core_ext/aws-sdk/includes.rb +9 -0
- data/lib/aws_assume_role/credentials/factories.rb +11 -0
- data/lib/aws_assume_role/credentials/factories/abstract_factory.rb +33 -0
- data/lib/aws_assume_role/credentials/factories/assume_role.rb +39 -0
- data/lib/aws_assume_role/credentials/factories/default_chain_provider.rb +113 -0
- data/lib/aws_assume_role/credentials/factories/environment.rb +26 -0
- data/lib/aws_assume_role/credentials/factories/includes.rb +15 -0
- data/lib/aws_assume_role/credentials/factories/instance_profile.rb +19 -0
- data/lib/aws_assume_role/credentials/factories/repository.rb +37 -0
- data/lib/aws_assume_role/credentials/factories/shared.rb +19 -0
- data/lib/aws_assume_role/credentials/factories/static.rb +18 -0
- data/lib/aws_assume_role/credentials/includes.rb +6 -0
- data/lib/aws_assume_role/credentials/providers/assume_role_credentials.rb +60 -0
- data/lib/aws_assume_role/credentials/providers/includes.rb +9 -0
- data/lib/aws_assume_role/credentials/providers/mfa_session_credentials.rb +119 -0
- data/lib/aws_assume_role/credentials/providers/shared_keyring_credentials.rb +41 -0
- data/lib/aws_assume_role/includes.rb +38 -0
- data/lib/aws_assume_role/logging.rb +27 -0
- data/lib/aws_assume_role/profile_configuration.rb +73 -0
- data/lib/aws_assume_role/runner.rb +40 -0
- data/lib/aws_assume_role/store/includes.rb +8 -0
- data/lib/aws_assume_role/store/keyring.rb +61 -0
- data/lib/aws_assume_role/store/serialization.rb +20 -0
- data/lib/aws_assume_role/store/shared_config_with_keyring.rb +250 -0
- data/lib/aws_assume_role/types.rb +31 -0
- data/lib/aws_assume_role/ui.rb +57 -0
- data/lib/aws_assume_role/vendored/aws.rb +4 -0
- data/lib/aws_assume_role/vendored/aws/README.md +2 -0
- data/lib/aws_assume_role/vendored/aws/assume_role_credentials.rb +67 -0
- data/lib/aws_assume_role/vendored/aws/includes.rb +9 -0
- data/lib/aws_assume_role/vendored/aws/refreshing_credentials.rb +58 -0
- data/lib/aws_assume_role/vendored/aws/shared_config.rb +223 -0
- data/lib/aws_assume_role/version.rb +5 -0
- metadata +438 -0
@@ -0,0 +1,119 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "includes"
|
4
|
+
require_relative "../../types"
|
5
|
+
require_relative "../../configuration"
|
6
|
+
begin
|
7
|
+
require "smartcard"
|
8
|
+
require "yubioath"
|
9
|
+
SMARTCARD_SUPPORT = true
|
10
|
+
rescue LoadError
|
11
|
+
SMARTCARD_SUPPORT = false
|
12
|
+
end
|
13
|
+
|
14
|
+
class AwsAssumeRole::Credentials::Providers::MfaSessionCredentials < Dry::Struct
|
15
|
+
constructor_type :schema
|
16
|
+
include AwsAssumeRole::Vendored::Aws::CredentialProvider
|
17
|
+
include AwsAssumeRole::Vendored::Aws::RefreshingCredentials
|
18
|
+
include AwsAssumeRole::Ui
|
19
|
+
include AwsAssumeRole::Logging
|
20
|
+
|
21
|
+
attribute :permanent_credentials, Dry::Types["object"].optional
|
22
|
+
attribute :credentials, Dry::Types["object"].optional
|
23
|
+
attribute :expiration, Dry::Types["strict.time"].default(Time.now)
|
24
|
+
attribute :first_time, Dry::Types["strict.bool"].default(true)
|
25
|
+
attribute :persist_session, Dry::Types["strict.bool"].default(true)
|
26
|
+
attribute :duration_seconds, Dry::Types["coercible.int"].default(3600)
|
27
|
+
attribute :region, AwsAssumeRole::Types::Region.optional
|
28
|
+
attribute :serial_number, AwsAssumeRole::Types::MfaSerial.optional.default("automatic")
|
29
|
+
attribute :yubikey_oath_name, Dry::Types["strict.string"].optional
|
30
|
+
|
31
|
+
def initialize(options)
|
32
|
+
options.each { |key, value| instance_variable_set("@#{key}", value) }
|
33
|
+
@permanent_credentials ||= @credentials
|
34
|
+
@credentials = nil
|
35
|
+
@serial_number = resolve_serial_number(serial_number)
|
36
|
+
AwsAssumeRole::Vendored::Aws::RefreshingCredentials.instance_method(:initialize).bind(self).call(options)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def keyring_username
|
42
|
+
@keyring_username ||= "#{@identity.to_json}|#{@serial_number}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def sts_client
|
46
|
+
@sts_client ||= Aws::STS::Client.new(region: @region, credentials: @permanent_credentials)
|
47
|
+
end
|
48
|
+
|
49
|
+
def prompt_for_token
|
50
|
+
text = @first_time ? t("options.mfa_token.first_time") : t("options.mfa_token.other_times")
|
51
|
+
Ui.input.ask text
|
52
|
+
end
|
53
|
+
|
54
|
+
def initialized
|
55
|
+
@first_time = false
|
56
|
+
end
|
57
|
+
|
58
|
+
def refresh
|
59
|
+
return set_credentials_from_keyring if @persist_session && @first_time
|
60
|
+
refresh_using_mfa if near_expiration?
|
61
|
+
broadcast(:mfa_completed)
|
62
|
+
end
|
63
|
+
|
64
|
+
def retrieve_yubikey_token
|
65
|
+
raise t("options.mfa_token.smartcard_not_supported") unless SMARTCARD_SUPPORT
|
66
|
+
context = Smartcard::PCSC::Context.new
|
67
|
+
raise "Yubikey not found" unless context.readers.length == 1
|
68
|
+
reader_name = context.readers.first
|
69
|
+
card = Smartcard::PCSC::Card.new(context, reader_name, :shared)
|
70
|
+
codes = YubiOATH.new(card).calculate_all(timestamp: Time.now)
|
71
|
+
codes.fetch(BinData::String.new(@yubikey_oath_name))
|
72
|
+
end
|
73
|
+
|
74
|
+
def refresh_using_mfa
|
75
|
+
token_code = @yubikey_oath_name ? retrieve_yubikey_token : prompt_for_token
|
76
|
+
token = sts_client.get_session_token(
|
77
|
+
duration_seconds: @duration_seconds,
|
78
|
+
serial_number: @serial_number,
|
79
|
+
token_code: token_code,
|
80
|
+
)
|
81
|
+
initialized
|
82
|
+
instance_credentials token.credentials
|
83
|
+
persist_credentials if @persist_session
|
84
|
+
end
|
85
|
+
|
86
|
+
def credentials_from_keyring
|
87
|
+
@credentials_from_keyring ||= AwsAssumeRole::Store::Keyring.fetch keyring_username
|
88
|
+
rescue Aws::Errors::NoSuchProfileError
|
89
|
+
logger.debug "Key not found"
|
90
|
+
@credentials_from_keyring = nil
|
91
|
+
return nil
|
92
|
+
end
|
93
|
+
|
94
|
+
def persist_credentials
|
95
|
+
AwsAssumeRole::Store::Keyring.save_credentials keyring_username, @credentials, expiration: @expiration
|
96
|
+
end
|
97
|
+
|
98
|
+
def instance_credentials(credentials)
|
99
|
+
return unless credentials
|
100
|
+
@credentials = AwsAssumeRole::Store::Serialization.credentials_from_hash(credentials)
|
101
|
+
@expiration = credentials.respond_to?(:expiration) ? credentials.expiration : Time.parse(credentials[:expiration])
|
102
|
+
end
|
103
|
+
|
104
|
+
def set_credentials_from_keyring
|
105
|
+
instance_credentials credentials_from_keyring if credentials_from_keyring
|
106
|
+
initialized
|
107
|
+
refresh_using_mfa unless @credentials && !near_expiration?
|
108
|
+
end
|
109
|
+
|
110
|
+
def identity
|
111
|
+
@identity ||= sts_client.get_caller_identity
|
112
|
+
end
|
113
|
+
|
114
|
+
def resolve_serial_number(serial_number)
|
115
|
+
return serial_number unless serial_number.nil? || serial_number == "automatic"
|
116
|
+
user_name = identity.arn.split("/")[1]
|
117
|
+
"arn:aws:iam::#{identity.account}:mfa/#{user_name}"
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "includes"
|
4
|
+
require_relative "../../types"
|
5
|
+
|
6
|
+
class AwsAssumeRole::Credentials::Providers::SharedKeyringCredentials < ::Aws::SharedCredentials
|
7
|
+
include AwsAssumeRole::Logging
|
8
|
+
attr_reader :region, :role_arn
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
logger.debug "SharedKeyringCredentials initiated with #{options}"
|
12
|
+
@path = options[:path]
|
13
|
+
@path ||= AwsAssumeRole.shared_config.credentials_path
|
14
|
+
@profile_name = options[:profile_name] ||= options[:profile]
|
15
|
+
@profile_name ||= ENV["AWS_PROFILE"]
|
16
|
+
@profile_name ||= AwsAssumeRole.shared_config.profile_name
|
17
|
+
logger.debug "SharedKeyringCredentials resolved profile name #{@profile_name}"
|
18
|
+
config = determine_config(@path, @profile_name)
|
19
|
+
@role_arn = config.profile_hash(@profile_name)
|
20
|
+
@region = config.profile_region(@profile_name)
|
21
|
+
@role_arn = config.profile_role(@profile_name)
|
22
|
+
attempted_credential = config.credentials(options)
|
23
|
+
return unless attempted_credential && attempted_credential.set?
|
24
|
+
@credentials = attempted_credential
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def determine_config(path, profile_name)
|
30
|
+
if path && path == AwsAssumeRole.shared_config.credentials_path
|
31
|
+
logger.debug "SharedKeyringCredentials found shared credential path"
|
32
|
+
AwsAssumeRole.shared_config
|
33
|
+
else
|
34
|
+
logger.debug "SharedKeyringCredentials found custom credential path"
|
35
|
+
AwsAssumeRole::Store::SharedConfigWithKeyring.new(
|
36
|
+
credentials_path: path,
|
37
|
+
profile_name: profile_name,
|
38
|
+
)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "i18n"
|
4
|
+
require "active_support/json"
|
5
|
+
require "active_support/core_ext/object/blank"
|
6
|
+
require "active_support/core_ext/string/inflections"
|
7
|
+
require "active_support/core_ext/hash/compact"
|
8
|
+
require "active_support/core_ext/hash/keys"
|
9
|
+
require "active_support/core_ext/hash/slice"
|
10
|
+
require "aws-sdk"
|
11
|
+
require "aws-sdk-core/ini_parser"
|
12
|
+
require "dry-configurable"
|
13
|
+
require "dry-struct"
|
14
|
+
require "dry-validation"
|
15
|
+
require "dry-types"
|
16
|
+
require "English"
|
17
|
+
require "gli"
|
18
|
+
require "highline"
|
19
|
+
require "inifile"
|
20
|
+
require "json"
|
21
|
+
require "keyring"
|
22
|
+
require "launchy"
|
23
|
+
require "logger"
|
24
|
+
require "open-uri"
|
25
|
+
require "pastel"
|
26
|
+
require "securerandom"
|
27
|
+
require "set"
|
28
|
+
require "thread"
|
29
|
+
require "time"
|
30
|
+
|
31
|
+
module AwsAssumeRole
|
32
|
+
module_function
|
33
|
+
|
34
|
+
def shared_config
|
35
|
+
enabled = ENV["AWS_SDK_CONFIG_OPT_OUT"] ? false : true
|
36
|
+
@shared_config ||= SharedConfigWithKeyring.new(config_enabled: enabled)
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "includes"
|
4
|
+
require_relative "configuration"
|
5
|
+
module AwsAssumeRole::Logging
|
6
|
+
module ClassMethods
|
7
|
+
def logger
|
8
|
+
@logger ||= begin
|
9
|
+
logger = Logger.new($stderr)
|
10
|
+
logger.level = AwsAssumeRole::Config.log_level
|
11
|
+
ENV["GLI_DEBUG"] = "true" if AwsAssumeRole::Config.log_level.zero?
|
12
|
+
logger
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module InstanceMethods
|
18
|
+
def logger
|
19
|
+
self.class.logger
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.included(base)
|
24
|
+
base.extend ClassMethods
|
25
|
+
base.include InstanceMethods
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "includes"
|
4
|
+
require_relative "logging"
|
5
|
+
|
6
|
+
class AwsAssumeRole::ProfileConfiguration < Dry::Struct
|
7
|
+
constructor_type :schema
|
8
|
+
include AwsAssumeRole::Logging
|
9
|
+
attribute :access_key_id, Dry::Types["strict.string"].optional
|
10
|
+
attribute :credentials, Dry::Types["object"].optional
|
11
|
+
attribute :secret_access_key, Dry::Types["strict.string"].optional
|
12
|
+
attribute :session_token, Dry::Types["strict.string"].optional
|
13
|
+
attribute :duration_seconds, Dry::Types["coercible.int"].optional
|
14
|
+
attribute :external_id, Dry::Types["strict.string"].optional
|
15
|
+
attribute :path, Dry::Types["strict.string"].optional
|
16
|
+
attribute :persist_session, Dry::Types["strict.bool"].optional.default(true)
|
17
|
+
attribute :profile, Dry::Types["strict.string"].optional
|
18
|
+
attribute :region, Dry::Types["strict.string"].optional
|
19
|
+
attribute :role_arn, Dry::Types["strict.string"].optional
|
20
|
+
attribute :role_session_name, Dry::Types["strict.string"].optional
|
21
|
+
attribute :serial_number, Dry::Types["strict.string"].optional
|
22
|
+
attribute :mfa_serial, Dry::Types["strict.string"].optional
|
23
|
+
attribute :yubikey_oath_name, Dry::Types["strict.string"].optional
|
24
|
+
attribute :use_mfa, Dry::Types["strict.bool"].optional.default(false)
|
25
|
+
attribute :no_profile, Dry::Types["strict.bool"].optional.default(false)
|
26
|
+
attribute :shell_type, Dry::Types["strict.string"].optional
|
27
|
+
attribute :source_profile, Dry::Types["strict.string"].optional
|
28
|
+
attribute :args, Dry::Types["strict.array"].optional.default([])
|
29
|
+
attribute :instance_profile_credentials_retries, Dry::Types["strict.int"].default(0)
|
30
|
+
attribute :instance_profile_credentials_timeout, Dry::Types["coercible.float"].default(1.0)
|
31
|
+
|
32
|
+
attr_writer :credentials
|
33
|
+
|
34
|
+
def self.merge_mfa_variable(options)
|
35
|
+
new_hash = options.key?(:mfa_serial) ? options.merge(serial_number: options[:mfa_serial]) : options
|
36
|
+
new_hash[:use_mfa] ||= new_hash.fetch(:serial_number, nil) ? true : false
|
37
|
+
if new_hash.key?(:serial_number) && new_hash[:serial_number] == "automatic"
|
38
|
+
new_hash.delete(:serial_number)
|
39
|
+
end
|
40
|
+
new_hash
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.new_from_cli(global_options, options, args)
|
44
|
+
options = global_options.merge options
|
45
|
+
options = options.map do |k, v|
|
46
|
+
[k.to_s.underscore.to_sym, v]
|
47
|
+
end.to_h
|
48
|
+
options[:args] = args
|
49
|
+
new merge_mfa_variable(options)
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.new_from_credential_provider_initialization(options)
|
53
|
+
logger.debug "new_from_credential_provider_initialization with #{options.to_h}"
|
54
|
+
new_from_credential_provider(options, credentials: nil, delete: [])
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.new_from_credential_provider(options = {}, credentials: nil, delete: [])
|
58
|
+
option_hash = options.to_h
|
59
|
+
config = option_hash.fetch(:config, {}).to_h
|
60
|
+
hash_to_merge = option_hash.merge config
|
61
|
+
hash_to_merge.merge(credentials: credentials) if credentials
|
62
|
+
delete.each do |k|
|
63
|
+
hash_to_merge.delete k
|
64
|
+
end
|
65
|
+
hash = merge_mfa_variable(hash_to_merge)
|
66
|
+
logger.debug "new_from_credential_provider with #{hash}"
|
67
|
+
new hash
|
68
|
+
end
|
69
|
+
|
70
|
+
def to_h
|
71
|
+
to_hash
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "includes"
|
4
|
+
require_relative "logging"
|
5
|
+
|
6
|
+
class AwsAssumeRole::Runner < Dry::Struct
|
7
|
+
include AwsAssumeRole::Logging
|
8
|
+
constructor_type :schema
|
9
|
+
attribute :command, Dry::Types["coercible.array"].of(Dry::Types["strict.string"]).default([])
|
10
|
+
attribute :exit_on_error, Dry::Types["strict.bool"].default(true)
|
11
|
+
attribute :expected_exit_code, Dry::Types["strict.int"].default(0)
|
12
|
+
attribute :environment, Dry::Types["strict.hash"].default({})
|
13
|
+
attribute :credentials, Dry::Types["object"].optional
|
14
|
+
|
15
|
+
def initialize(options)
|
16
|
+
super(options)
|
17
|
+
command_to_exec = command.map(&:shellescape).join(" ")
|
18
|
+
process_credentials unless credentials.blank?
|
19
|
+
system environment, command_to_exec
|
20
|
+
exit_status = $CHILD_STATUS.exitstatus
|
21
|
+
process_error(exit_status) if exit_status != expected_exit_code
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def process_credentials
|
27
|
+
cred_env = {
|
28
|
+
"AWS_ACCESS_KEY_ID" => credentials.credentials.access_key_id,
|
29
|
+
"AWS_SECRET_ACCESS_KEY" => credentials.credentials.secret_access_key,
|
30
|
+
"AWS_SESSION_TOKEN" => credentials.credentials.session_token,
|
31
|
+
}
|
32
|
+
@environment = environment.merge cred_env
|
33
|
+
end
|
34
|
+
|
35
|
+
def process_error(exit_status)
|
36
|
+
logger.error "#{command} failed with #{exit_status}"
|
37
|
+
exit exit_status if exit_on_error
|
38
|
+
raise "#{command} failed with #{exit_status}"
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "includes"
|
4
|
+
require_relative "serialization"
|
5
|
+
require_relative "../configuration"
|
6
|
+
require_relative "../logging"
|
7
|
+
|
8
|
+
module AwsAssumeRole::Store::Keyring
|
9
|
+
include AwsAssumeRole
|
10
|
+
include AwsAssumeRole::Store
|
11
|
+
include AwsAssumeRole::Logging
|
12
|
+
|
13
|
+
module_function
|
14
|
+
|
15
|
+
KEYRING_KEY = "AwsAssumeRole".freeze
|
16
|
+
|
17
|
+
def semaphore
|
18
|
+
@semaphore ||= Mutex.new
|
19
|
+
end
|
20
|
+
|
21
|
+
def keyrings
|
22
|
+
@keyrings ||= {}
|
23
|
+
end
|
24
|
+
|
25
|
+
def try_backend_plugin
|
26
|
+
return if AwsAssumeRole::Config.backend_plugin.blank?
|
27
|
+
logger.info "Attempting to load #{AwsAssumeRole::Config.backend_plugin} plugin"
|
28
|
+
require AwsAssumeRole::Config.backend_plugin
|
29
|
+
end
|
30
|
+
|
31
|
+
def keyring(backend = AwsAssumeRole::Config.backend)
|
32
|
+
keyrings[backend] ||= begin
|
33
|
+
try_backend_plugin
|
34
|
+
klass = backend ? "Keyring::Backend::#{backend}".constantize : nil
|
35
|
+
logger.debug "Initializing #{klass} backend"
|
36
|
+
::Keyring.new(klass)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def fetch(id, backend: nil)
|
41
|
+
logger.debug "Fetching #{id} from keyring"
|
42
|
+
fetched = keyring(backend).get_password(KEYRING_KEY, id)
|
43
|
+
raise Aws::Errors::NoSuchProfileError if fetched == "null" || fetched.nil? || !fetched
|
44
|
+
JSON.parse(fetched, symbolize_names: true)
|
45
|
+
end
|
46
|
+
|
47
|
+
def delete_credentials(id, backend: nil)
|
48
|
+
semaphore.synchronize do
|
49
|
+
keyring(backend).delete_password(KEYRING_KEY, id)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def save_credentials(id, credentials, expiration: nil, backend: nil)
|
54
|
+
credentials_to_persist = Serialization.credentials_to_hash(credentials)
|
55
|
+
credentials_to_persist[:expiration] = expiration if expiration
|
56
|
+
semaphore.synchronize do
|
57
|
+
keyring(backend).delete_password(KEYRING_KEY, id)
|
58
|
+
keyring(backend).set_password(KEYRING_KEY, id, credentials_to_persist.to_json)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AwsAssumeRole::Store::Serialization
|
4
|
+
module_function
|
5
|
+
|
6
|
+
def credentials_from_hash(credentials)
|
7
|
+
creds_for_deserialization = credentials.respond_to?("[]") ? credentials : credentials_to_hash(credentials)
|
8
|
+
Aws::Credentials.new(creds_for_deserialization[:access_key_id],
|
9
|
+
creds_for_deserialization[:secret_access_key],
|
10
|
+
creds_for_deserialization[:session_token])
|
11
|
+
end
|
12
|
+
|
13
|
+
def credentials_to_hash(credentials)
|
14
|
+
{
|
15
|
+
access_key_id: credentials.access_key_id,
|
16
|
+
secret_access_key: credentials.secret_access_key,
|
17
|
+
session_token: credentials.session_token,
|
18
|
+
}
|
19
|
+
end
|
20
|
+
end
|