aws_assume_role 1.1.0-universal-openbsd
Sign up to get free protection for your applications and to get access to all the features.
- 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
|