MovableInkAWS 2.6.0 → 2.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aee7128060ef1c160ab30f71a01ba8dc906b3cc19e600ebef7b48df7d0fd29d2
4
- data.tar.gz: 36d923a0fca6ca5098f8e9dd4c12ee8257f9c0896853d56a2979e9bbe461ac5b
3
+ metadata.gz: 4e7ad037cd5628c4064e602e7818305adf691666f178b1cba16f967c17021b1d
4
+ data.tar.gz: 7f6fbc76c3c7669aadd15682cd806c2e3268f39cd74dd395913910aa01b826f7
5
5
  SHA512:
6
- metadata.gz: f3328245aeb3822471f9a3c52f4e015c4cb60d0ae2950c5af09dff732081b66c0409607c8e4f3d21a676e6986ba8087f7509dc62a87862cfbbf3740af5d75f6a
7
- data.tar.gz: a5decec040107d6b7240551412cc43827fdf78be921ae8eaae3fc61d419aa578d72a6af24851d8397f721e7674e03eda56cd662af8871eec9569e125a20a9199
6
+ metadata.gz: 73af21192d6d001442427ed83f21e18b7aee0e214243b6e8572d1ca51f2b9d15a562e14435f666737f6158651285c2a95ac59f3c7a38d8a7539404a4f24a2559
7
+ data.tar.gz: 0cc73c99406611d2d6482149eea67a8c235b7b5caa0dd7d366ac0e6256c5a2b8faae3de6e83350ff71a464cac40f2b518c6b7a5b72e80613af8a8ee8042352c3
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- MovableInkAWS (2.6.0)
4
+ MovableInkAWS (2.6.3)
5
5
  aws-sdk-athena (~> 1)
6
6
  aws-sdk-autoscaling (~> 1)
7
7
  aws-sdk-cloudwatch (~> 1)
@@ -9,6 +9,7 @@ PATH
9
9
  aws-sdk-ec2 (~> 1)
10
10
  aws-sdk-eks (~> 1)
11
11
  aws-sdk-elasticache (~> 1)
12
+ aws-sdk-iam (~> 1)
12
13
  aws-sdk-rds (~> 1)
13
14
  aws-sdk-route53 (~> 1)
14
15
  aws-sdk-s3 (~> 1)
@@ -48,6 +49,9 @@ GEM
48
49
  aws-sdk-elasticache (1.76.0)
49
50
  aws-sdk-core (~> 3, >= 3.127.0)
50
51
  aws-sigv4 (~> 1.1)
52
+ aws-sdk-iam (1.68.0)
53
+ aws-sdk-core (~> 3, >= 3.127.0)
54
+ aws-sigv4 (~> 1.1)
51
55
  aws-sdk-kms (1.55.0)
52
56
  aws-sdk-core (~> 3, >= 3.127.0)
53
57
  aws-sigv4 (~> 1.1)
@@ -117,4 +121,4 @@ DEPENDENCIES
117
121
  webmock
118
122
 
119
123
  BUNDLED WITH
120
- 2.1.4
124
+ 2.3.11
@@ -16,6 +16,7 @@ Gem::Specification.new do |s|
16
16
  s.add_runtime_dependency 'aws-sdk-ec2', '~> 1'
17
17
  s.add_runtime_dependency 'aws-sdk-eks', '~> 1'
18
18
  s.add_runtime_dependency 'aws-sdk-elasticache', '~> 1'
19
+ s.add_runtime_dependency 'aws-sdk-iam', '~> 1'
19
20
  s.add_runtime_dependency 'aws-sdk-rds', '~> 1'
20
21
  s.add_runtime_dependency 'aws-sdk-route53', '~> 1'
21
22
  s.add_runtime_dependency 'aws-sdk-s3', '~> 1'
@@ -0,0 +1,23 @@
1
+ require 'aws-sdk-iam'
2
+
3
+ module MovableInk
4
+ class AWS
5
+ module IAM
6
+ def is_arn_iam_user?(arn, username = nil)
7
+ # arn:aws:iam::account:user/user-name-with-path
8
+ !arn.match(/arn:aws:iam::\d+:user\/#{(username) ? username + '$' : ''}/).nil?
9
+ end
10
+
11
+ def is_arn_iam_role?(arn, rolename = nil)
12
+ # arn:aws:iam::account:role/role-name-with-path
13
+ !arn.match(/arn:aws:iam::\d+:role\/#{(rolename) ? rolename + '$' : ''}/).nil?
14
+ end
15
+
16
+ def is_arn_iam_assumed_role?(arn, rolename = nil, exact_match = true)
17
+ # arn:aws:sts::account:assumed-role/role-name/role-session-name
18
+ role_name_session_delimiter = (exact_match) ? '/' : ''
19
+ !arn.match(/arn:aws:sts::\d+:assumed\-role\/#{(rolename) ? rolename + role_name_session_delimiter : ''}/).nil?
20
+ end
21
+ end
22
+ end
23
+ end
@@ -3,26 +3,48 @@ require 'aws-sdk-ssm'
3
3
  module MovableInk
4
4
  class AWS
5
5
  module SSM
6
- def ssm_client
7
- @ssm_client ||= Aws::SSM::Client.new(region: 'us-east-1')
6
+
7
+ SSM_DEFAULT_REGION = 'us-east-1'
8
+ SSM_DEFAULT_FAILOVER_REGION = 'us-west-2'
9
+
10
+ def mi_secrets_config_file_path
11
+ '/etc/movableink/secrets_config.json'
12
+ end
13
+
14
+ def mi_secrets_config
15
+ @mi_secrets_config ||= (File.exist?(mi_secrets_config_file_path)) ? JSON.parse(File.read(mi_secrets_config_file_path), :symbolize_names => true) : nil
16
+ end
17
+
18
+ def mi_ssm_clients_regions
19
+ default_regions = [SSM_DEFAULT_REGION, SSM_DEFAULT_FAILOVER_REGION]
20
+
21
+ return default_regions if !mi_secrets_config || !mi_secrets_config[:ssm_parameters_regions_map] || !mi_secrets_config[:ssm_parameters_regions_map].key?(my_region.to_sym)
22
+ my_region_map = mi_secrets_config[:ssm_parameters_regions_map][my_region.to_sym]
23
+ (my_region_map.keys == [:primary_region, :failover_region]) ? my_region_map.values : default_regions
24
+ end
25
+
26
+ def ssm_client(region = nil)
27
+ @ssm_clients_map ||= {}
28
+ @ssm_clients_map[region] ||= Aws::SSM::Client.new(region: (region.nil?) ? mi_ssm_clients_regions[0] : region)
8
29
  end
9
30
 
10
- def ssm_client_failover
11
- @ssm_client_failover ||= Aws::SSM::Client.new(region: 'us-west-2')
31
+ def ssm_client_failover(failregion = nil)
32
+ @ssm_failover_clients_map ||= {}
33
+ @ssm_failover_clients_map[failregion] ||= Aws::SSM::Client.new(region: (failregion.nil?) ? mi_ssm_clients_regions[1] : failregion)
12
34
  end
13
35
 
14
- def run_with_backoff_and_client_fallback(&block)
36
+ def run_with_backoff_and_client_fallback(region = nil, failregion = nil, &block)
15
37
  run_with_backoff do
16
- block.call(ssm_client)
38
+ block.call(ssm_client(region))
17
39
  end
18
40
  rescue MovableInk::AWS::Errors::FailedWithBackoff => e
19
41
  run_with_backoff(tries: 3) do
20
- block.call(ssm_client_failover)
42
+ block.call(ssm_client_failover(failregion))
21
43
  end
22
44
  end
23
45
 
24
- def get_secret(environment: mi_env, role:, attribute:)
25
- run_with_backoff_and_client_fallback do |ssm|
46
+ def get_secret(environment: mi_env, role:, attribute:, region: nil, failregion: nil)
47
+ run_with_backoff_and_client_fallback(region, failregion) do |ssm|
26
48
  begin
27
49
  resp = ssm.get_parameter(
28
50
  name: "/#{environment}/#{role}/#{attribute}",
@@ -35,9 +57,9 @@ module MovableInk
35
57
  end
36
58
  end
37
59
 
38
- def get_role_secrets(environment: mi_env, role:)
60
+ def get_role_secrets(environment: mi_env, role:, region: nil, failregion: nil)
39
61
  path = "/#{environment}/#{role}"
40
- run_with_backoff_and_client_fallback do |ssm|
62
+ run_with_backoff_and_client_fallback(region, failregion) do |ssm|
41
63
  ssm.get_parameters_by_path(
42
64
  path: path,
43
65
  with_decryption: true
@@ -7,13 +7,13 @@ require_relative 'aws/route53'
7
7
  require_relative 'aws/ssm'
8
8
  require_relative 'aws/athena'
9
9
  require_relative 'aws/s3'
10
+ require_relative 'aws/iam'
10
11
  require_relative 'aws/eks'
11
12
  require_relative 'aws/elasticache'
12
13
  require_relative 'aws/api_gateway'
13
14
  require_relative 'consul/consul'
14
15
  require 'aws-sdk-cloudwatch'
15
16
 
16
-
17
17
  module MovableInk
18
18
  class AWS
19
19
  include Metadata
@@ -27,6 +27,7 @@ module MovableInk
27
27
  include ElastiCache
28
28
  include ApiGateway
29
29
  include EKS
30
+ include IAM
30
31
 
31
32
  class << self
32
33
  def regions
@@ -84,7 +85,10 @@ module MovableInk
84
85
  Aws::SSM::Errors::Http503Error,
85
86
  Aws::SSM::Errors::Http502Error,
86
87
  Aws::Athena::Errors::ThrottlingException,
87
- MovableInk::AWS::Errors::NoEnvironmentTagError
88
+ MovableInk::AWS::Errors::NoEnvironmentTagError,
89
+ Aws::IAM::Errors::LimitExceededException,
90
+ Aws::IAM::Errors::RequestLimitExceeded,
91
+ Aws::IAM::Errors::Throttling
88
92
  sleep_time = (num+1)**2 + rand(10)
89
93
  if quiet
90
94
  (num >= tries - 1) ? notify_and_sleep(sleep_time, $!.class) : sleep(sleep_time)
@@ -1,5 +1,5 @@
1
1
  module MovableInk
2
2
  class AWS
3
- VERSION = '2.6.0'
3
+ VERSION = '2.6.3'
4
4
  end
5
5
  end
data/spec/iam_spec.rb ADDED
@@ -0,0 +1,43 @@
1
+ require_relative '../lib/movable_ink/aws'
2
+
3
+ describe MovableInk::AWS::IAM do
4
+ let(:aws) { MovableInk::AWS.new }
5
+
6
+ describe 'is_arn_iam_user?' do
7
+ it 'matches user by arn type' do
8
+ expect(aws.is_arn_iam_user?('arn:aws:iam::123:user/anosulchyk')).to eq true
9
+ expect(aws.is_arn_iam_user?('arn:aws:iam::123:role/anosulchyk')).to eq false
10
+ end
11
+
12
+ it 'matches user by arn type and name' do
13
+ expect(aws.is_arn_iam_user?('arn:aws:iam::123:user/anosulchyk', 'anosulchyk')).to eq true
14
+ expect(aws.is_arn_iam_user?('arn:aws:iam::123:user/this/is/user/too', 'this/is/user/too')).to eq true
15
+ expect(aws.is_arn_iam_user?('arn:aws:iam::123:user/anosulchyk', 'anosulchik11')).to eq false
16
+ end
17
+ end
18
+
19
+ describe 'is_arn_iam_role?' do
20
+ it 'matches role by arn type' do
21
+ expect(aws.is_arn_iam_role?('arn:aws:iam::123:role/anosulchyk')).to eq true
22
+ expect(aws.is_arn_iam_role?('arn:aws:sts::123:role/anosulchyk')).to eq false
23
+ end
24
+
25
+ it 'matches role by arn type and name' do
26
+ expect(aws.is_arn_iam_role?('arn:aws:iam::123:role/anosulchyk', 'anosulchyk')).to eq true
27
+ expect(aws.is_arn_iam_role?('arn:aws:iam::123:role/anosulchyk', 'anosulchik11')).to eq false
28
+ end
29
+ end
30
+
31
+ describe 'is_arn_iam_assumed_role?' do
32
+ it 'matches role by arn type' do
33
+ expect(aws.is_arn_iam_assumed_role?('arn:aws:sts::123:assumed-role/anosulchyk/session')).to eq true
34
+ expect(aws.is_arn_iam_assumed_role?('arn:aws:sts::123:role/anosulchyk')).to eq false
35
+ end
36
+
37
+ it 'matches role by arn type and name' do
38
+ expect(aws.is_arn_iam_assumed_role?('arn:aws:sts::123:assumed-role/anosulchyk/session', 'anosulchyk')).to eq true
39
+ expect(aws.is_arn_iam_assumed_role?('arn:aws:sts::123:assumed-role/anosulchyk/session-name', '1anosulchyk1')).to eq false
40
+ end
41
+ end
42
+
43
+ end
data/spec/ssm_spec.rb CHANGED
@@ -9,6 +9,8 @@ describe MovableInk::AWS::SSM do
9
9
  value: 'too-many-secrets'
10
10
  })
11
11
  }
12
+ let(:mi_secrets_config_file_path) { '/etc/movableink/secrets_config.json' }
13
+ let(:mi_secrets_config_file_mock) { "{\"ssm_parameters_regions_map\": { \"us-east-1\": {\"primary_region\": \"us-east-1\", \"failover_region\": \"us-east-2\"}}}" }
12
14
  let(:parameters) { ssm.stub_data(:get_parameters_by_path, parameters: [
13
15
  {
14
16
  name: '/test/zelda/Its',
@@ -68,6 +70,11 @@ describe MovableInk::AWS::SSM do
68
70
  expect(Aws::SSM::Client).to receive(:new).with({ region: 'us-east-1' })
69
71
  aws.ssm_client
70
72
  end
73
+
74
+ it 'Allows region to be defined as a parameter' do
75
+ expect(Aws::SSM::Client).to receive(:new).with({ region: 'us-east-2' })
76
+ aws.ssm_client('us-east-2')
77
+ end
71
78
  end
72
79
 
73
80
  describe 'ssm_client_failover' do
@@ -75,6 +82,11 @@ describe MovableInk::AWS::SSM do
75
82
  expect(Aws::SSM::Client).to receive(:new).with({ region: 'us-west-2' })
76
83
  aws.ssm_client_failover
77
84
  end
85
+
86
+ it 'fails over to parameter defined region' do
87
+ expect(Aws::SSM::Client).to receive(:new).with({ region: 'us-west-1' })
88
+ aws.ssm_client_failover('us-west-1')
89
+ end
78
90
  end
79
91
 
80
92
  describe 'run_with_backoff_and_client_fallback' do
@@ -103,4 +115,36 @@ describe MovableInk::AWS::SSM do
103
115
  expect(results).to include(1, 2)
104
116
  end
105
117
  end
118
+
119
+ describe 'mi_secrets_config_file_path' do
120
+ it 'returns string' do
121
+ expect(aws.mi_secrets_config_file_path).to eq mi_secrets_config_file_path
122
+ end
123
+ end
124
+
125
+ describe 'mi_secrets_config' do
126
+ it 'parses config file with symbols' do
127
+ allow(File).to receive(:read).with(mi_secrets_config_file_path).and_return(mi_secrets_config_file_mock)
128
+ allow(File).to receive(:exist?).with(mi_secrets_config_file_path).and_return(true)
129
+
130
+ config = aws.mi_secrets_config
131
+ expect(config.keys).to eq([:ssm_parameters_regions_map])
132
+ expect(config[:ssm_parameters_regions_map][:"us-east-1"][:primary_region]).to eq 'us-east-1'
133
+ expect(config[:ssm_parameters_regions_map][:"us-east-1"][:failover_region]).to eq 'us-east-2'
134
+ end
135
+ end
136
+
137
+ describe 'mi_ssm_clients_regions' do
138
+ it 'returns values from config' do
139
+ allow(aws).to receive(:mi_secrets_config).and_return(JSON.parse(mi_secrets_config_file_mock, :symbolize_names => true))
140
+ allow(aws).to receive(:my_region).and_return('us-east-1')
141
+ expect(aws.mi_ssm_clients_regions).to eq ['us-east-1', 'us-east-2']
142
+ end
143
+
144
+ it 'returns default values if config is missing' do
145
+ allow(aws).to receive(:mi_secrets_config).and_return(nil)
146
+ allow(aws).to receive(:my_region).and_return('us-east-1')
147
+ expect(aws.mi_ssm_clients_regions).to eq ['us-east-1', 'us-west-2']
148
+ end
149
+ end
106
150
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: MovableInkAWS
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.6.0
4
+ version: 2.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Chesler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-04-06 00:00:00.000000000 Z
11
+ date: 2022-05-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-core
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '1'
111
+ - !ruby/object:Gem::Dependency
112
+ name: aws-sdk-iam
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: aws-sdk-rds
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -241,6 +255,7 @@ files:
241
255
  - lib/movable_ink/aws/eks.rb
242
256
  - lib/movable_ink/aws/elasticache.rb
243
257
  - lib/movable_ink/aws/errors.rb
258
+ - lib/movable_ink/aws/iam.rb
244
259
  - lib/movable_ink/aws/metadata.rb
245
260
  - lib/movable_ink/aws/route53.rb
246
261
  - lib/movable_ink/aws/s3.rb
@@ -253,6 +268,7 @@ files:
253
268
  - spec/consul_spec.rb
254
269
  - spec/ec2_spec.rb
255
270
  - spec/elasticache_spec.rb
271
+ - spec/iam_spec.rb
256
272
  - spec/metadata_spec.rb
257
273
  - spec/route53_spec.rb
258
274
  - spec/s3_spec.rb