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.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rubocop.yml +57 -0
  4. data/.ruby-version +1 -0
  5. data/.simplecov +22 -0
  6. data/.travis.yml +24 -0
  7. data/CHANGELOG.md +61 -0
  8. data/Gemfile +18 -0
  9. data/LICENSE.md +201 -0
  10. data/README.md +303 -0
  11. data/Rakefile +63 -0
  12. data/aws_assume_role.gemspec +56 -0
  13. data/bin/aws-assume-role +4 -0
  14. data/i18n/en.yml +109 -0
  15. data/lib/aws_assume_role.rb +4 -0
  16. data/lib/aws_assume_role/cli.rb +20 -0
  17. data/lib/aws_assume_role/cli/actions/abstract_action.rb +61 -0
  18. data/lib/aws_assume_role/cli/actions/configure_profile.rb +24 -0
  19. data/lib/aws_assume_role/cli/actions/configure_role_assumption.rb +22 -0
  20. data/lib/aws_assume_role/cli/actions/console.rb +70 -0
  21. data/lib/aws_assume_role/cli/actions/delete_profile.rb +22 -0
  22. data/lib/aws_assume_role/cli/actions/includes.rb +12 -0
  23. data/lib/aws_assume_role/cli/actions/list_profiles.rb +12 -0
  24. data/lib/aws_assume_role/cli/actions/migrate_profile.rb +20 -0
  25. data/lib/aws_assume_role/cli/actions/reset_environment.rb +50 -0
  26. data/lib/aws_assume_role/cli/actions/run.rb +36 -0
  27. data/lib/aws_assume_role/cli/actions/set_environment.rb +62 -0
  28. data/lib/aws_assume_role/cli/actions/test.rb +35 -0
  29. data/lib/aws_assume_role/cli/commands/configure.rb +32 -0
  30. data/lib/aws_assume_role/cli/commands/console.rb +19 -0
  31. data/lib/aws_assume_role/cli/commands/delete.rb +13 -0
  32. data/lib/aws_assume_role/cli/commands/environment.rb +34 -0
  33. data/lib/aws_assume_role/cli/commands/list.rb +12 -0
  34. data/lib/aws_assume_role/cli/commands/migrate.rb +13 -0
  35. data/lib/aws_assume_role/cli/commands/run.rb +19 -0
  36. data/lib/aws_assume_role/cli/commands/test.rb +20 -0
  37. data/lib/aws_assume_role/cli/includes.rb +3 -0
  38. data/lib/aws_assume_role/configuration.rb +30 -0
  39. data/lib/aws_assume_role/core_ext/aws-sdk/credential_provider_chain.rb +4 -0
  40. data/lib/aws_assume_role/core_ext/aws-sdk/includes.rb +9 -0
  41. data/lib/aws_assume_role/credentials/factories.rb +11 -0
  42. data/lib/aws_assume_role/credentials/factories/abstract_factory.rb +33 -0
  43. data/lib/aws_assume_role/credentials/factories/assume_role.rb +39 -0
  44. data/lib/aws_assume_role/credentials/factories/default_chain_provider.rb +113 -0
  45. data/lib/aws_assume_role/credentials/factories/environment.rb +26 -0
  46. data/lib/aws_assume_role/credentials/factories/includes.rb +15 -0
  47. data/lib/aws_assume_role/credentials/factories/instance_profile.rb +19 -0
  48. data/lib/aws_assume_role/credentials/factories/repository.rb +37 -0
  49. data/lib/aws_assume_role/credentials/factories/shared.rb +19 -0
  50. data/lib/aws_assume_role/credentials/factories/static.rb +18 -0
  51. data/lib/aws_assume_role/credentials/includes.rb +6 -0
  52. data/lib/aws_assume_role/credentials/providers/assume_role_credentials.rb +60 -0
  53. data/lib/aws_assume_role/credentials/providers/includes.rb +9 -0
  54. data/lib/aws_assume_role/credentials/providers/mfa_session_credentials.rb +119 -0
  55. data/lib/aws_assume_role/credentials/providers/shared_keyring_credentials.rb +41 -0
  56. data/lib/aws_assume_role/includes.rb +38 -0
  57. data/lib/aws_assume_role/logging.rb +27 -0
  58. data/lib/aws_assume_role/profile_configuration.rb +73 -0
  59. data/lib/aws_assume_role/runner.rb +40 -0
  60. data/lib/aws_assume_role/store/includes.rb +8 -0
  61. data/lib/aws_assume_role/store/keyring.rb +61 -0
  62. data/lib/aws_assume_role/store/serialization.rb +20 -0
  63. data/lib/aws_assume_role/store/shared_config_with_keyring.rb +250 -0
  64. data/lib/aws_assume_role/types.rb +31 -0
  65. data/lib/aws_assume_role/ui.rb +57 -0
  66. data/lib/aws_assume_role/vendored/aws.rb +4 -0
  67. data/lib/aws_assume_role/vendored/aws/README.md +2 -0
  68. data/lib/aws_assume_role/vendored/aws/assume_role_credentials.rb +67 -0
  69. data/lib/aws_assume_role/vendored/aws/includes.rb +9 -0
  70. data/lib/aws_assume_role/vendored/aws/refreshing_credentials.rb +58 -0
  71. data/lib/aws_assume_role/vendored/aws/shared_config.rb +223 -0
  72. data/lib/aws_assume_role/version.rb +5 -0
  73. metadata +438 -0
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "includes"
4
+
5
+ module AwsAssumeRole
6
+ class Configuration
7
+ extend Dry::Configurable
8
+ Types = Dry::Types.module
9
+
10
+ setting(:backend_plugin, ENV.fetch("AWS_ASSUME_ROLE_KEYRING_PLUGIN", nil)) do |value|
11
+ Types::Coercible::String[value]
12
+ end
13
+
14
+ setting(:backend, ENV.fetch("AWS_ASSUME_ROLE_KEYRING_BACKEND", "automatic")) do |value|
15
+ value == "automatic" ? nil : Types::Coercible::String[value]
16
+ end
17
+
18
+ setting(:log_level, ENV.fetch("AWS_ASSUME_ROLE_LOG_LEVEL", "WARN")) do |value|
19
+ {
20
+ DEBUG: 0,
21
+ INFO: 1,
22
+ WARN: 2,
23
+ ERROR: 3,
24
+ FATAL: 4,
25
+ UNKNOWN: 5,
26
+ }[value.to_sym] || 2
27
+ end
28
+ end
29
+ Config = Configuration.config
30
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../credentials/factories/default_chain_provider"
4
+ Aws.const_set :CredentialProviderChain, AwsAssumeRole::Credentials::Factories::DefaultChainProvider
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../includes"
4
+ module AwsAssumeRole
5
+ module CoreExt
6
+ module Aws
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "factories/repository"
4
+ require_relative "factories/abstract_factory"
5
+ require_relative "factories/default_chain_provider"
6
+ require_relative "factories/assume_role"
7
+ require_relative "factories/environment"
8
+ require_relative "factories/instance_profile"
9
+ require_relative "factories/shared_keyring"
10
+ require_relative "factories/shared"
11
+ require_relative "factories/static"
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "includes"
4
+ require_relative "repository"
5
+ require_relative "../../profile_configuration"
6
+
7
+ class AwsAssumeRole::Credentials::Factories::AbstractFactory
8
+ include AwsAssumeRole
9
+ include AwsAssumeRole::Credentials::Factories
10
+ include AwsAssumeRole::Logging
11
+
12
+ Dry::Types.register_class(Aws::SharedCredentials)
13
+ attr_reader :credentials, :region, :profile, :role_arn
14
+
15
+ def initialize(_options)
16
+ raise "Not implemented"
17
+ end
18
+
19
+ def self.type(str)
20
+ @type = Types::Strict::Symbol.enum(:credential_provider, :second_factor_provider, :instance_role_provider)[str]
21
+ register_if_complete
22
+ end
23
+
24
+ def self.priority(i)
25
+ @priority = Types::Strict::Int[i]
26
+ register_if_complete
27
+ end
28
+
29
+ def self.register_if_complete
30
+ return unless @type && @priority
31
+ Repository.register_factory(self, @type, @priority)
32
+ end
33
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "abstract_factory"
4
+ require_relative "../providers/assume_role_credentials"
5
+ require_relative "../providers/mfa_session_credentials"
6
+
7
+ class AwsAssumeRole::Credentials::Factories::AssumeRole < AwsAssumeRole::Credentials::Factories::AbstractFactory
8
+ include AwsAssumeRole::Credentials::Factories
9
+ type :credential_provider
10
+ priority 20
11
+
12
+ def initialize(options)
13
+ logger.debug "AwsAssumeRole::Credentials::Factories::AssumeRole initiated with #{options}"
14
+ return unless options[:profile] || options[:role_arn]
15
+ if options[:profile]
16
+ logger.debug "AwsAssumeRole: #{options[:profile]} found. Trying with profile"
17
+ try_with_profile(options)
18
+ else
19
+ if options[:use_mfa]
20
+ options[:credentials] = AwsAssumeRole::Credentials::Providers::MfaSessionCredentials.new(options).credentials
21
+ end
22
+ @credentials = AwsAssumeRole::Credentials::Providers::AssumeRoleCredentials.new(options)
23
+ end
24
+ end
25
+
26
+ def try_with_profile(options)
27
+ return unless AwsAssumeRole.shared_config.config_enabled?
28
+ logger.debug "AwsAssumeRole: Shared Config enabled"
29
+ @profile = options[:profile]
30
+ @region = options[:region]
31
+ @credentials = assume_role_with_profile(options)
32
+ @region ||= AwsAssumeRole.shared_config.profile_region(@profile)
33
+ @role_arn ||= AwsAssumeRole.shared_config.profile_role(@profile)
34
+ end
35
+
36
+ def assume_role_with_profile(options)
37
+ AwsAssumeRole.shared_config.assume_role_credentials_from_config(options)
38
+ end
39
+ end
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "includes"
4
+ require_relative "../../logging"
5
+ require_relative "../../profile_configuration"
6
+ require_relative "abstract_factory"
7
+ require_relative "environment"
8
+ require_relative "repository"
9
+ require_relative "instance_profile"
10
+ require_relative "assume_role"
11
+ require_relative "shared"
12
+ require_relative "static"
13
+
14
+ class AwsAssumeRole::Credentials::Factories::DefaultChainProvider < Dry::Struct
15
+ constructor_type :schema
16
+ include AwsAssumeRole::Credentials::Factories
17
+ include AwsAssumeRole::Logging
18
+
19
+ attribute :access_key_id, Dry::Types["strict.string"].optional
20
+ attribute :credentials, Dry::Types["object"].optional
21
+ attribute :duration_seconds, Dry::Types["coercible.int"].optional
22
+ attribute :external_id, Dry::Types["strict.string"].optional
23
+ attribute :instance_profile_credentials_retries, Dry::Types["strict.int"].default(0)
24
+ attribute :instance_profile_credentials_timeout, Dry::Types["coercible.float"].default(1.0)
25
+ attribute :mfa_serial, Dry::Types["strict.string"].optional
26
+ attribute :no_profile, Dry::Types["strict.bool"].default(false)
27
+ attribute :path, Dry::Types["strict.string"].optional
28
+ attribute :persist_session, Dry::Types["strict.bool"].default(true)
29
+ attribute :profile_name, Dry::Types["strict.string"].optional
30
+ attribute :profile, Dry::Types["strict.string"].optional
31
+ attribute :region, Dry::Types["strict.string"].optional
32
+ attribute :role_arn, Dry::Types["strict.string"].optional
33
+ attribute :role_session_name, Dry::Types["strict.string"].optional
34
+ attribute :secret_access_key, Dry::Types["strict.string"].optional
35
+ attribute :serial_number, Dry::Types["strict.string"].optional
36
+ attribute :session_token, Dry::Types["strict.string"].optional
37
+ attribute :source_profile, Dry::Types["strict.string"].optional
38
+ attribute :use_mfa, Dry::Types["strict.bool"].default(false)
39
+ attribute :yubikey_oath_name, Dry::Types["strict.string"].optional
40
+
41
+ def self.new(options)
42
+ if options.respond_to? :resolve
43
+ finalize_instance new_with_seahorse(options)
44
+ else
45
+ finalize_instance(options)
46
+ end
47
+ end
48
+
49
+ def self.finalize_instance(options)
50
+ new_opts = options.to_h
51
+ new_opts[:profile_name] ||= new_opts[:profile]
52
+ new_opts[:original_profile] = new_opts[:profile_name]
53
+ instance = allocate
54
+ instance.send(:initialize, new_opts)
55
+ instance
56
+ end
57
+
58
+ def self.new_with_seahorse(resolver)
59
+ keys = resolver.resolve
60
+ options = keys.map do |k|
61
+ [k, resolver.send(k)]
62
+ end
63
+ finalize_instance(options.to_h)
64
+ end
65
+
66
+ def resolve(nil_with_role_not_set: false, explicit_default_profile: false)
67
+ resolve_final_credentials(explicit_default_profile)
68
+ # nil_creds = Aws::Credentials.new(nil, nil, nil)
69
+ return nil if (nil_with_role_not_set &&
70
+ @role_arn &&
71
+ @credentials.credentials.session_token.nil?) || @credentials.nil?
72
+ @credentials
73
+ end
74
+
75
+ def to_h
76
+ to_hash
77
+ end
78
+
79
+ private
80
+
81
+ def resolve_final_credentials(explicit_default_profile = false)
82
+ resolve_credentials(:credential_provider, true, explicit_default_profile)
83
+ return @credentials if @credentials && @credentials.set? && !use_mfa && !role_arn
84
+ resolve_credentials(:second_factor_provider, true, explicit_default_profile)
85
+ return @credentials if @credentials && @credentials.set?
86
+ resolve_credentials(:instance_role_provider, true, explicit_default_profile)
87
+ return @credentials if @credentials && @credentials.set?
88
+ nil
89
+ end
90
+
91
+ def resolve_credentials(type, break_if_successful = false, explicit_default_profile = false)
92
+ factories_to_try = Repository.factories[type]
93
+ factories_to_try.each do |x|
94
+ options = to_h
95
+ options[:credentials] = credentials if credentials && credentials.set?
96
+ logger.debug "About to try credential lookup with #{x}"
97
+ factory = x.new(options)
98
+ @region ||= factory.region
99
+ @profile ||= factory.profile
100
+ @role_arn ||= factory.role_arn
101
+ next unless factory.credentials && factory.credentials.set?
102
+ logger.debug "Profile currently #{@profile}"
103
+ next if explicit_default_profile && (@profile == "default") && (@profile != @original_profile)
104
+ @credentials ||= factory.credentials
105
+ logger.debug "Got #{@credentials}"
106
+ break if break_if_successful
107
+ end
108
+ end
109
+ end
110
+
111
+ module AwsAssumeRole
112
+ DefaultProvider = AwsAssumeRole::Credentials::Factories::DefaultChainProvider
113
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "abstract_factory"
4
+
5
+ class AwsAssumeRole::Credentials::Factories::Environment < AwsAssumeRole::Credentials::Factories::AbstractFactory
6
+ type :credential_provider
7
+ priority 10
8
+
9
+ def initialize(_options, **)
10
+ key = %w[AWS_ACCESS_KEY_ID AMAZON_ACCESS_KEY_ID AWS_ACCESS_KEY]
11
+ secret = %w[AWS_SECRET_ACCESS_KEY AMAZON_SECRET_ACCESS_KEY AWS_SECRET_KEY]
12
+ token = %w[AWS_SESSION_TOKEN AMAZON_SESSION_TOKEN]
13
+ region = %w[AWS_DEFAULT_REGION]
14
+ profile = %w[AWS_PROFILE]
15
+ @credentials = Aws::Credentials.new(envar(key), envar(secret), envar(token))
16
+ @region = envar(region)
17
+ @profile = envar(profile)
18
+ end
19
+
20
+ def envar(keys)
21
+ keys.each do |key|
22
+ return ENV[key] if ENV.key?(key)
23
+ end
24
+ nil
25
+ end
26
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../includes"
4
+ require_relative "../../logging"
5
+ require_relative "../../vendored/aws"
6
+ require_relative "../../../aws_assume_role"
7
+
8
+ module AwsAssumeRole::Credentials
9
+ module Factories
10
+ Types = Dry::Types.module
11
+ include AwsAssumeRole
12
+ include AwsAssumeRole::Logging
13
+ include AwsAssumeRole::Vendored::Aws
14
+ end
15
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "abstract_factory"
4
+
5
+ class AwsAssumeRole::Credentials::Factories::InstanceProfile < AwsAssumeRole::Credentials::Factories::AbstractFactory
6
+ type :instance_role_provider
7
+ priority 40
8
+
9
+ def initialize(options = {})
10
+ options[:retries] ||= options[:instance_profile_credentials_retries] || 0
11
+ options[:http_open_timeout] ||= options[:instance_profile_credentials_timeout] || 1
12
+ options[:http_read_timeout] ||= options[:instance_profile_credentials_timeout] || 1
13
+ @credentials = if ENV["AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"]
14
+ Aws::ECSCredentials.new(options)
15
+ else
16
+ Aws::InstanceProfileCredentials.new(options)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "includes"
4
+ require_relative "abstract_factory"
5
+
6
+ class AwsAssumeRole::Credentials::Factories::Repository
7
+ include AwsAssumeRole::Credentials::Factories
8
+
9
+ SubFactoryRepositoryType = Types::Hash.schema(Types::Coercible::Int => Types::Strict::Array)
10
+
11
+ FactoryRepositoryType = Types::Hash.schema(
12
+ credential_provider: SubFactoryRepositoryType,
13
+ second_factor_provider: SubFactoryRepositoryType,
14
+ instance_role_provider: SubFactoryRepositoryType,
15
+ )
16
+
17
+ def self.factories
18
+ repository.keys.map { |t| [t, flatten_factory_type_list(t)] }.to_h
19
+ end
20
+
21
+ def self.repository
22
+ @repository ||= FactoryRepositoryType[
23
+ credential_provider: {},
24
+ second_factor_provider: {},
25
+ instance_role_provider: {},
26
+ ]
27
+ end
28
+
29
+ def self.register_factory(klass, type, priority)
30
+ repository[type][priority] ||= []
31
+ repository[type][priority] << klass
32
+ end
33
+
34
+ def self.flatten_factory_type_list(type)
35
+ repository[type].keys.sort.map { |x| @repository[type][x] }.flatten
36
+ end
37
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "abstract_factory"
4
+ require_relative "../providers/shared_keyring_credentials"
5
+
6
+ class AwsAssumeRole::Credentials::Factories::Shared < AwsAssumeRole::Credentials::Factories::AbstractFactory
7
+ type :credential_provider
8
+ priority 30
9
+
10
+ def initialize(options = {})
11
+ logger.debug "Shared Factory initiated with #{options}"
12
+ @profile = options[:profile]
13
+ @credentials = AwsAssumeRole::Credentials::Providers::SharedKeyringCredentials.new(options)
14
+ @region = @credentials.region
15
+ @role_arn = @credentials.role_arn
16
+ rescue Aws::Errors::NoSuchProfileError
17
+ nil
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "abstract_factory"
4
+
5
+ class AwsAssumeRole::Credentials::Factories::Static < AwsAssumeRole::Credentials::Factories::AbstractFactory
6
+ type :credential_provider
7
+ priority 0
8
+
9
+ def initialize(options = {})
10
+ @credentials = Aws::Credentials.new(
11
+ options[:access_key_id],
12
+ options[:secret_access_key],
13
+ options[:session_token],
14
+ )
15
+ @region = options[:region]
16
+ @profile = options[:profile]
17
+ end
18
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../includes"
4
+ module AwsAssumeRole
5
+ module Credentials end
6
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "includes"
4
+ require "set"
5
+
6
+ class AwsAssumeRole::Credentials::Providers::AssumeRoleCredentials
7
+ include AwsAssumeRole::Vendored::Aws::CredentialProvider
8
+ include AwsAssumeRole::Vendored::Aws::RefreshingCredentials
9
+
10
+ # @option options [required, String] :role_arn
11
+ # @option options [required, String] :role_session_name
12
+ # @option options [String] :policy
13
+ # @option options [Integer] :duration_seconds
14
+ # @option options [String] :external_id
15
+ # @option options [STS::Client] :client
16
+ #
17
+ #
18
+
19
+ STS_KEYS = %i[role_arn role_session_name policy duration_seconds external_id client credentials region].freeze
20
+
21
+ def initialize(options = {})
22
+ client_opts = {}
23
+ @assume_role_params = {}
24
+ options.each_pair do |key, value|
25
+ if self.class.assume_role_options.include?(key)
26
+ @assume_role_params[key] = value
27
+ else
28
+ next unless STS_KEYS.include?(key)
29
+ client_opts[key] = value
30
+ end
31
+ end
32
+ @client = client_opts[:client] || ::Aws::STS::Client.new(client_opts)
33
+ super
34
+ end
35
+
36
+ # @return [STS::Client]
37
+ attr_reader :client
38
+
39
+ private
40
+
41
+ def refresh
42
+ c = @client.assume_role(@assume_role_params).credentials
43
+ @credentials = ::Aws::Credentials.new(
44
+ c.access_key_id,
45
+ c.secret_access_key,
46
+ c.session_token,
47
+ )
48
+ @expiration = c.expiration
49
+ end
50
+
51
+ class << self
52
+ # @api private
53
+ def assume_role_options
54
+ @aro ||= begin
55
+ input = ::Aws::STS::Client.api.operation(:assume_role).input
56
+ Set.new(input.shape.member_names)
57
+ end
58
+ end
59
+ end
60
+ end