config_o_mat 0.4.1 → 0.5.0.beta1

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: df6fa2a90625e5927b75d670dce66e5e4823cdb9af32ce64f1bdae0280a3146d
4
- data.tar.gz: ac2ec11e30427a04952478b8b4293eb9be53ba6af3299ac8a7e6156f6eca14ac
3
+ metadata.gz: bb9ec5b07f001551fee80b15ba613646a295d35a1aa0d341e1cdd7924f014b17
4
+ data.tar.gz: 60a37f95f84bb1d0c29de65cbe43110a7dd4e1eab1f41b7c1952268a200d0776
5
5
  SHA512:
6
- metadata.gz: f9efe6b0f7c05308fe8acfd7e569ca95adb3c85f8952fd70a820ef82f652054c0428ce0c7e773248c1e31d8e47c01d3a70791fedf34266016eeab07fe73eb224
7
- data.tar.gz: a43d73f798e16f4388551666da9a8d573fa3e97442288a3d8b215014fa4593dbe07253c2cde4346146b79871b4daba3856342cf41588a6d43d18f7df01c40755
6
+ metadata.gz: 14de2abaa1de0b6d6fb5b8301fb628f7c7315d7ac8ed302a5392115a754ba24c9b263784e2862ea3abafb0850b3f4b1626f2a74fe0b5bc97b9a461ac73c7bdfc
7
+ data.tar.gz: 483f4cfd52cd9d0e835490249602abb87167ae65bb07aa29113b33cce4d679e2e1a1364e2916a1c84784d32749be6fba7631c26d0254a94720bf6efe36242024
data/CHANGELOG.md CHANGED
@@ -1,3 +1,37 @@
1
+ ## 0.5.0.beta1
2
+
3
+ NEW FEATURES:
4
+
5
+ * Profiles can now specify an s3_fallback key. If AWS AppConfig is unreachable, we will fall back to loading the specified S3 object from the top level configured fallback_s3_bucket and interpreting it as a response from AWS AppConfig. For best results enable versioning on the bucket. It is an error to specify an s3_fallback key if the configuration does not have a top level fallback_s3_bucket.
6
+ * AppConfig responses can request that the s3_fallback be used by setting a top level "aws:chaos_config" key to true. This allows for deployments which AppConfig deployments which can test the fallback mechanism. If a chaos config load fails, the source AppConfig profile will remain in use. Chaos config is ignored in error recovery scenarios.
7
+
8
+ BUG FIXES:
9
+
10
+ * config_o_mat-configurator/meta_configurator now correctly log the op that errored.
11
+
12
+ ## 0.4.4
13
+
14
+ BUG FIXES:
15
+
16
+ * Fix MetaConfigurator with new GC parameters.
17
+
18
+ ## 0.4.3
19
+
20
+ BUG FIXES:
21
+
22
+ * Fix MetaConfigurator with new GC parameters.
23
+
24
+ ## 0.4.2
25
+
26
+ NEW FEATURES:
27
+
28
+ * gc_compact configuration variable. If set, will run `GC.compact` every given number of ticks (roughly seconds).
29
+ * gc_stat configuration variable. If set, will log `GC.stat` at the info level every given number of ticks (roughly seconds).
30
+
31
+ ENHANCEMENTS:
32
+
33
+ * Now remove ec2_metadata.iam key from Facter. This value updated every hour or so causing spurious template regeneration and did not contain actionable information.
34
+
1
35
  ## 0.4.1
2
36
 
3
37
  ENHANCEMENTS:
data/Gemfile.lock CHANGED
@@ -1,8 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- config_o_mat (0.4.0)
4
+ config_o_mat (0.4.4)
5
5
  aws-sdk-appconfig (~> 1.18)
6
+ aws-sdk-s3 (~> 1.114)
6
7
  aws-sdk-secretsmanager (~> 1.57)
7
8
  facter (~> 4.2, >= 4.2.8)
8
9
  lifecycle_vm (~> 0.1.1)
@@ -14,23 +15,30 @@ GEM
14
15
  remote: https://rubygems.org/
15
16
  specs:
16
17
  aws-eventstream (1.2.0)
17
- aws-partitions (1.574.0)
18
+ aws-partitions (1.593.0)
18
19
  aws-sdk-appconfig (1.25.0)
19
20
  aws-sdk-core (~> 3, >= 3.127.0)
20
21
  aws-sigv4 (~> 1.1)
21
- aws-sdk-core (3.130.0)
22
+ aws-sdk-core (3.131.1)
22
23
  aws-eventstream (~> 1, >= 1.0.2)
23
24
  aws-partitions (~> 1, >= 1.525.0)
24
25
  aws-sigv4 (~> 1.1)
25
- jmespath (~> 1.0)
26
- aws-sdk-secretsmanager (1.59.0)
26
+ jmespath (~> 1, >= 1.6.1)
27
+ aws-sdk-kms (1.57.0)
27
28
  aws-sdk-core (~> 3, >= 3.127.0)
28
29
  aws-sigv4 (~> 1.1)
29
- aws-sigv4 (1.4.0)
30
+ aws-sdk-s3 (1.114.0)
31
+ aws-sdk-core (~> 3, >= 3.127.0)
32
+ aws-sdk-kms (~> 1)
33
+ aws-sigv4 (~> 1.4)
34
+ aws-sdk-secretsmanager (1.62.0)
35
+ aws-sdk-core (~> 3, >= 3.127.0)
36
+ aws-sigv4 (~> 1.1)
37
+ aws-sigv4 (1.5.0)
30
38
  aws-eventstream (~> 1, >= 1.0.2)
31
39
  diff-lcs (1.5.0)
32
40
  docile (1.4.0)
33
- facter (4.2.9)
41
+ facter (4.2.10)
34
42
  hocon (~> 1.3)
35
43
  thor (>= 1.0.1, < 2.0)
36
44
  hocon (1.3.1)
@@ -36,12 +36,12 @@ vm = ConfigOMat::Configurator::VM.new(memory)
36
36
  vm.call
37
37
 
38
38
  if vm.errors?
39
- warn "Errored executing #{vm.error_op.class.name}"
39
+ warn "Errored executing #{vm.error_op.op.name}"
40
40
  warn "Errors: #{vm.errors}"
41
41
 
42
42
  if vm.recovery_errors?
43
43
  warn ''
44
- warn "Errors recovering from error. Errored executing recovery #{vm.current_op.class.name}"
44
+ warn "Errors recovering from error. Errored executing recovery #{vm.current_op.op.name}"
45
45
  warn "Errors: #{vm.recovery_errors}"
46
46
  end
47
47
 
@@ -36,12 +36,12 @@ vm = ConfigOMat::MetaConfigurator::VM.new(memory)
36
36
  vm.call
37
37
 
38
38
  if vm.errors?
39
- warn "Errored executing #{vm.error_op.class.name}"
39
+ warn "Errored executing #{vm.error_op.op.name}"
40
40
  warn "Errors: #{vm.errors}"
41
41
 
42
42
  if vm.recovery_errors?
43
43
  warn ''
44
- warn "Errors recovering from error. Errored executing recovery #{vm.current_op.class.name}"
44
+ warn "Errors recovering from error. Errored executing recovery #{vm.current_op.op.name}"
45
45
  warn "Errors: #{vm.recovery_errors}"
46
46
  end
47
47
 
data/config_o_mat.gemspec CHANGED
@@ -39,6 +39,7 @@ Gem::Specification.new do |spec|
39
39
  spec.executables = ["config_o_mat-configurator", "config_o_mat-meta_configurator"]
40
40
 
41
41
  spec.add_dependency('aws-sdk-appconfig', '~> 1.18')
42
+ spec.add_dependency('aws-sdk-s3', '~> 1.114')
42
43
  spec.add_dependency('aws-sdk-secretsmanager', '~> 1.57')
43
44
  spec.add_dependency('logsformyfamily', '~> 0.2')
44
45
  spec.add_dependency('lifecycle_vm', '~> 0.1.1')
@@ -22,13 +22,19 @@ module ConfigOMat
22
22
  reads :error_op, :retries_left, :applying_profile
23
23
 
24
24
  def call
25
- logger&.error(:op_failure, op: error_op.class.name, errors: error_op.errors)
25
+ logger&.error(:retry_from_failure, state: error_op.state_name, op: error_op.op.name, errors: error_op.errors)
26
26
 
27
27
  # If we aren't currently applying a profile then there's nothing for us to retry.
28
- return false if applying_profile.nil?
28
+ if applying_profile.nil?
29
+ logger&.error(:cannot_retry, reason: 'not applying profile')
30
+ return false
31
+ end
29
32
 
30
33
  # If we're out of retries, well, no more retrying
31
- return false if retries_left.zero?
34
+ if retries_left.zero?
35
+ logger&.error(:cannot_retry, reason: 'out of retries')
36
+ return false
37
+ end
32
38
 
33
39
  true
34
40
  end
@@ -25,8 +25,9 @@ module ConfigOMat
25
25
  :client_id, :compiled_templates, :applied_profiles, :applying_profile,
26
26
  :generated_templates, :services_to_reload, :profiles_to_apply,
27
27
  :last_refresh_time, :next_state, :retry_count, :retries_left, :retry_wait,
28
- :region, :appconfig_client, :secretsmanager_client, :systemd_interface,
29
- :secrets_loader_memory
28
+ :region, :appconfig_client, :secretsmanager_client, :s3_client,
29
+ :systemd_interface, :secrets_loader_memory, :gc_compact, :gc_stat,
30
+ :fallback_s3_bucket
30
31
 
31
32
  def initialize(
32
33
  argv: [],
@@ -57,8 +58,12 @@ module ConfigOMat
57
58
  region: nil,
58
59
  appconfig_client: nil,
59
60
  secretsmanager_client: nil,
61
+ s3_client: nil,
60
62
  systemd_interface: nil,
61
- secrets_loader_memory: nil
63
+ secrets_loader_memory: nil,
64
+ gc_compact: 0,
65
+ gc_stat: 0,
66
+ fallback_s3_bucket: nil
62
67
  )
63
68
  super()
64
69
 
@@ -90,8 +95,12 @@ module ConfigOMat
90
95
  @region = region
91
96
  @appconfig_client = appconfig_client
92
97
  @secretsmanager_client = secretsmanager_client
98
+ @s3_client = s3_client
93
99
  @systemd_interface = systemd_interface
94
100
  @secrets_loader_memory = secrets_loader_memory
101
+ @gc_compact = gc_compact
102
+ @gc_stat = gc_stat
103
+ @fallback_s3_bucket = fallback_s3_bucket
95
104
  end
96
105
  end
97
106
  end
@@ -17,19 +17,21 @@
17
17
  require 'lifecycle_vm/op_base'
18
18
 
19
19
  require 'aws-sdk-appconfig'
20
+ require 'aws-sdk-s3'
20
21
  require 'aws-sdk-secretsmanager'
21
22
 
22
23
  module ConfigOMat
23
24
  module Op
24
25
  class ConnectToAws < LifecycleVM::OpBase
25
26
  reads :region
26
- writes :appconfig_client, :secretsmanager_client
27
+ writes :appconfig_client, :secretsmanager_client, :s3_client
27
28
 
28
29
  def call
29
30
  client_opts = { logger: logger }
30
31
  client_opts[:region] = region if region
31
32
 
32
33
  self.appconfig_client = Aws::AppConfig::Client.new(client_opts)
34
+ self.s3_client = Aws::S3::Client.new(client_opts)
33
35
  self.secretsmanager_client = Aws::SecretsManager::Client.new(client_opts)
34
36
  end
35
37
  end
@@ -23,7 +23,7 @@ module ConfigOMat
23
23
  class NextTick < LifecycleVM::OpBase
24
24
  PAUSE_INTERVAL = 1
25
25
 
26
- reads :last_refresh_time, :refresh_interval, :run_count, :retry_count
26
+ reads :last_refresh_time, :refresh_interval, :run_count, :retry_count, :gc_stat, :gc_compact
27
27
  writes :next_state, :run_count, :retries_left
28
28
 
29
29
  def call
@@ -31,6 +31,16 @@ module ConfigOMat
31
31
 
32
32
  SdNotify.watchdog
33
33
 
34
+ if gc_compact > 0 && run_count % gc_compact == 0
35
+ response = GC.compact
36
+ logger&.info(:gc_compact, compact: response)
37
+ end
38
+
39
+ if gc_stat > 0 && run_count % gc_stat == 0
40
+ response = GC.stat
41
+ logger&.info(:gc_stat, stat: response)
42
+ end
43
+
34
44
  # If we got here then our retry process has succeeded.
35
45
  self.retries_left = retry_count
36
46
 
@@ -21,7 +21,8 @@ require 'config_o_mat/secrets_loader'
21
21
  module ConfigOMat
22
22
  module Op
23
23
  class RefreshAllProfiles < LifecycleVM::OpBase
24
- reads :profile_defs, :applied_profiles, :client_id, :appconfig_client, :secrets_loader_memory, :secretsmanager_client
24
+ reads :profile_defs, :applied_profiles, :client_id, :appconfig_client, :secrets_loader_memory,
25
+ :secretsmanager_client, :s3_client, :fallback_s3_bucket
25
26
  writes :profiles_to_apply, :last_refresh_time, :secrets_loader_memory
26
27
 
27
28
  def call
@@ -55,6 +56,21 @@ module ConfigOMat
55
56
  profiles_to_apply << LoadedProfile.new(new_profile, nil)
56
57
  end
57
58
 
59
+ def request_from_s3(profile_name, definition, ignore_errors)
60
+ begin
61
+ s3_response = s3_client.get_object(bucket: fallback_s3_bucket, key: definition.s3_fallback)
62
+ OpenStruct.new(
63
+ content: s3_response.body,
64
+ content_type: s3_response.content_type,
65
+ configuration_version: s3_response.version_id || s3_response.etag
66
+ )
67
+ rescue StandardError => e
68
+ logger&.error(:s3_fallback_load_failed, name: profile_name, reason: e)
69
+ error profile_name, e unless ignore_errors
70
+ nil
71
+ end
72
+ end
73
+
58
74
  def refresh_appconfig_profile(profile_name, definition)
59
75
  request = {
60
76
  application: definition.application, environment: definition.environment,
@@ -63,13 +79,20 @@ module ConfigOMat
63
79
 
64
80
  current_version = applied_profiles&.fetch(profile_name, nil)&.version
65
81
  request[:client_configuration_version] = current_version if current_version
82
+ fallback = false
66
83
 
67
84
  response =
68
85
  begin
69
86
  appconfig_client.get_configuration(request)
70
87
  rescue StandardError => e
71
- error profile_name, e
72
- nil
88
+ if definition.s3_fallback
89
+ fallback = true
90
+ logger&.error(:s3_fallback_request, name: profile_name, reason: e)
91
+ request_from_s3(profile_name, definition, false)
92
+ else
93
+ error profile_name, e
94
+ nil
95
+ end
73
96
  end
74
97
 
75
98
  return if response.nil?
@@ -83,9 +106,27 @@ module ConfigOMat
83
106
  )
84
107
 
85
108
  profile = LoadedAppconfigProfile.new(
86
- profile_name, loaded_version, response.content.read, response.content_type
109
+ profile_name, loaded_version, response.content.read, response.content_type, fallback
87
110
  )
88
111
 
112
+ if profile.chaos_config? && !fallback
113
+ logger&.notice(:chaos_config_requested, name: profile_name)
114
+ if !definition.s3_fallback
115
+ logger&.error(:refusing_chaos_config, name: profile_name, reason: 'no s3 fallback provided')
116
+ else
117
+ response = request_from_s3(profile_name, definition, true)
118
+ if !response
119
+ logger&.error(:chaos_config_load_failed, name: profile_name)
120
+ else
121
+ loaded_version = response.configuration_version
122
+ logger&.notice(:chaos_config_profile_loaded, name: profile_name, new_version: loaded_version)
123
+ profile = LoadedAppconfigProfile.new(
124
+ profile_name, loaded_version, response.content.read, response.content_type, true
125
+ )
126
+ end
127
+ end
128
+ end
129
+
89
130
  loaded_secrets = nil
90
131
 
91
132
  if !profile.secret_defs.empty?
@@ -19,7 +19,8 @@ require 'lifecycle_vm/op_base'
19
19
  module ConfigOMat
20
20
  module Op
21
21
  class RefreshProfile < LifecycleVM::OpBase
22
- reads :profile_defs, :client_id, :applying_profile, :appconfig_client, :secretsmanager_client, :secrets_loader_memory
22
+ reads :profile_defs, :client_id, :applying_profile, :appconfig_client, :secretsmanager_client,
23
+ :secrets_loader_memory, :s3_client, :fallback_s3_bucket
23
24
  writes :applying_profile, :secrets_loader_memory
24
25
 
25
26
  def call
@@ -54,6 +55,20 @@ module ConfigOMat
54
55
  self.applying_profile = LoadedProfile.new(new_profile, nil)
55
56
  end
56
57
 
58
+ def request_from_s3(profile_name, definition)
59
+ begin
60
+ s3_response = s3_client.get_object(bucket: fallback_s3_bucket, key: definition.s3_fallback)
61
+ OpenStruct.new(
62
+ content: s3_response.body,
63
+ content_type: s3_response.content_type,
64
+ configuration_version: s3_response.version_id || s3_response.etag
65
+ )
66
+ rescue StandardError => e
67
+ error profile_name, e
68
+ nil
69
+ end
70
+ end
71
+
57
72
  def refresh_appconfig_profile
58
73
  profile_name = applying_profile.name
59
74
  profile_version = applying_profile.version
@@ -63,13 +78,20 @@ module ConfigOMat
63
78
  configuration: definition.profile, client_id: client_id,
64
79
  client_configuration_version: profile_version
65
80
  }
81
+ fallback = false
66
82
 
67
83
  response =
68
84
  begin
69
85
  appconfig_client.get_configuration(request)
70
86
  rescue StandardError => e
71
- error profile_name, e
72
- nil
87
+ if definition.s3_fallback
88
+ fallback = true
89
+ logger&.error(:s3_fallback_request, name: profile_name, reason: e)
90
+ request_from_s3(profile_name, definition)
91
+ else
92
+ error profile_name, e
93
+ nil
94
+ end
73
95
  end
74
96
 
75
97
  return if response.nil? || errors?
@@ -89,7 +111,7 @@ module ConfigOMat
89
111
  )
90
112
 
91
113
  profile = LoadedAppconfigProfile.new(
92
- profile_name, loaded_version, response.content.read, response.content_type
114
+ profile_name, loaded_version, response.content.read, response.content_type, fallback
93
115
  )
94
116
 
95
117
  loaded_secrets = nil
@@ -23,7 +23,8 @@ module ConfigOMat
23
23
  :systemd_directory, :logs_directory, :profile_defs,
24
24
  :template_defs, :service_defs, :dependencies, :refresh_interval,
25
25
  :client_id, :retry_count, :retries_left, :retry_wait,
26
- :region, :systemd_interface
26
+ :region, :systemd_interface, :gc_stat, :gc_compact,
27
+ :fallback_s3_bucket
27
28
 
28
29
  def initialize(
29
30
  argv: [],
@@ -44,7 +45,10 @@ module ConfigOMat
44
45
  retries_left: 3,
45
46
  retry_wait: 2,
46
47
  region: nil,
47
- systemd_interface: nil
48
+ systemd_interface: nil,
49
+ gc_stat: 0,
50
+ gc_copmact: 0,
51
+ fallback_s3_bucket: nil
48
52
  )
49
53
  super()
50
54
 
@@ -67,6 +71,9 @@ module ConfigOMat
67
71
  @retry_wait = retry_wait
68
72
  @region = region
69
73
  @systemd_interface = systemd_interface
74
+ @gc_stat = gc_stat
75
+ @gc_compact = gc_compact
76
+ @fallback_s3_bucket = fallback_s3_bucket
70
77
  end
71
78
  end
72
79
  end
@@ -63,7 +63,8 @@ module ConfigOMat
63
63
  reads :configuration_directory, :logs_directory, :env
64
64
  writes :profile_defs, :template_defs, :service_defs, :dependencies,
65
65
  :refresh_interval, :client_id, :logger, :retry_count, :retries_left,
66
- :retry_wait, :region, :systemd_interface
66
+ :retry_wait, :region, :systemd_interface, :gc_stat, :gc_compact,
67
+ :fallback_s3_bucket
67
68
 
68
69
  def call
69
70
  default_config = {
@@ -74,7 +75,9 @@ module ConfigOMat
74
75
  services: [],
75
76
  templates: [],
76
77
  profiles: [],
77
- region: nil
78
+ region: nil,
79
+ gc_compact: 0,
80
+ gc_stat: 0
78
81
  }
79
82
 
80
83
  # TODO: I would like to make this configurable. I think the trick
@@ -125,6 +128,11 @@ module ConfigOMat
125
128
  self.service_defs = instantiate.call(:services, Service)
126
129
  self.template_defs = instantiate.call(:templates, Template)
127
130
  self.profile_defs = instantiate.call(:profiles, Profile)
131
+ self.fallback_s3_bucket = merged_config[:fallback_s3_bucket]
132
+
133
+ if profile_defs.values.any? { |pd| pd.s3_fallback } && (fallback_s3_bucket.nil? || fallback_s3_bucket.empty?)
134
+ error :fallback_s3_bucket, 'must be present to use s3_fallback on profiles'
135
+ end
128
136
 
129
137
  facter = merged_config[:facter]
130
138
  if facter
@@ -174,6 +182,8 @@ module ConfigOMat
174
182
  self.retries_left = retry_count
175
183
  self.retry_wait = merged_config[:retry_wait]
176
184
  self.region = merged_config[:region]
185
+ self.gc_stat = merged_config[:gc_stat]
186
+ self.gc_compact = merged_config[:gc_compact]
177
187
 
178
188
  self.dependencies = service_defs.each_with_object({}) do |(name, service), template_to_services|
179
189
  service.templates.each do |template|
@@ -164,27 +164,40 @@ module ConfigOMat
164
164
  end
165
165
 
166
166
  class Profile < ConfigItem
167
- attr_reader :application, :environment, :profile
167
+ attr_reader :application, :environment, :profile, :s3_fallback
168
168
 
169
169
  def initialize(opts)
170
170
  @application = opts[:application]
171
171
  @environment = opts[:environment]
172
172
  @profile = opts[:profile]
173
+ @s3_fallback = opts[:s3_fallback]
173
174
  end
174
175
 
175
176
  def validate
176
177
  error :application, 'must be present' if @application.nil? || @application.empty?
177
178
  error :environment, 'must be present' if @environment.nil? || @environment.empty?
178
179
  error :profile, 'must be present' if @profile.nil? || @profile.empty?
180
+ if !@s3_fallback.nil?
181
+ if @s3_fallback.kind_of?(String)
182
+ error :s3_fallback, 'must be non-empty' if @s3_fallback.empty?
183
+ else
184
+ error :s3_fallback, 'must be a string'
185
+ end
186
+ end
179
187
  end
180
188
 
181
189
  def hash
182
- application.hash ^ environment.hash ^ profile.hash
190
+ application.hash ^ environment.hash ^ profile.hash ^ s3_fallback.hash
183
191
  end
184
192
 
185
193
  def eql?(other)
186
194
  return false if !super(other)
187
- return false if other.application != application || other.environment != environment || other.profile != profile
195
+ if other.application != application ||
196
+ other.environment != environment ||
197
+ other.profile != profile ||
198
+ other.s3_fallback != s3_fallback
199
+ return false
200
+ end
188
201
  true
189
202
  end
190
203
  end
@@ -195,7 +208,7 @@ module ConfigOMat
195
208
  class LoadedFacterProfile < ConfigItem
196
209
  CLEAR_FROM_FACTER = [
197
210
  "memoryfree", "memoryfree_mb", "load_averages", "uptime", "system_uptime", "uptime_seconds", "uptime_hours", "uptime_days",
198
- {"ec2_metadata" => ["identity-credentials"]},
211
+ {"ec2_metadata" => ["identity-credentials", "iam"]},
199
212
  {"memory" => [{"system" => ["capacity", "available_bytes", "used", "used_bytes", "available"] }] }
200
213
  ].freeze
201
214
 
@@ -207,6 +220,10 @@ module ConfigOMat
207
220
  @version = contents.hash
208
221
  end
209
222
 
223
+ def fallback?
224
+ false
225
+ end
226
+
210
227
  def validate
211
228
  error :name, 'must be present' if @name.nil? || @name.empty?
212
229
  error :contents, 'must be present' if @contents.nil? || @contents.empty?
@@ -275,10 +292,12 @@ module ConfigOMat
275
292
  'application/x-yaml' => proc { |str| YAML.safe_load(str, symbolize_names: true) }
276
293
  }.freeze
277
294
 
278
- def initialize(name, version, contents, content_type)
295
+ def initialize(name, version, contents, content_type, fallback = false)
279
296
  @name = name
280
297
  @version = version
281
298
  @secret_defs = {}
299
+ @fallback = fallback
300
+ @chaos_config = false
282
301
 
283
302
  parser = PARSERS[content_type]
284
303
 
@@ -287,6 +306,7 @@ module ConfigOMat
287
306
  @contents = parser.call(contents)
288
307
  if @contents.kind_of?(Hash)
289
308
  parse_secrets
309
+ @chaos_config = @contents.fetch(:"aws:chaos_config", false)
290
310
  @contents.default_proc = proc do |hash, key|
291
311
  raise KeyError.new("No key #{key.inspect} in profile #{name}", key: key, receiver: hash)
292
312
  end
@@ -307,16 +327,30 @@ module ConfigOMat
307
327
  end
308
328
 
309
329
  def hash
310
- @name.hash ^ @version.hash ^ @contents.hash
330
+ @name.hash ^ @version.hash ^ @contents.hash ^ @fallback.hash ^ @chaos_config.hash
311
331
  end
312
332
 
313
333
  def to_h
314
334
  @contents
315
335
  end
316
336
 
337
+ def fallback?
338
+ @fallback
339
+ end
340
+
341
+ def chaos_config?
342
+ @chaos_config
343
+ end
344
+
317
345
  def eql?(other)
318
346
  return false if !super(other)
319
- return false if other.version != version || other.contents != contents || other.name != name
347
+ if other.version != version ||
348
+ other.contents != contents ||
349
+ other.name != name ||
350
+ other.fallback? != fallback? ||
351
+ other.chaos_config? != chaos_config?
352
+ return false
353
+ end
320
354
  true
321
355
  end
322
356
 
@@ -426,7 +460,7 @@ module ConfigOMat
426
460
 
427
461
  attr_reader :secrets, :loaded_profile_data
428
462
 
429
- def_delegators :@loaded_profile_data, :name, :version, :contents
463
+ def_delegators :@loaded_profile_data, :name, :version, :contents, :fallback?
430
464
 
431
465
  def initialize(loaded_profile_data, secrets)
432
466
  @loaded_profile_data = loaded_profile_data
@@ -15,5 +15,5 @@
15
15
  # limitations under the License.
16
16
 
17
17
  module ConfigOMat
18
- VERSION = "0.4.1"
18
+ VERSION = "0.5.0.beta1"
19
19
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: config_o_mat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.5.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Scarborough
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-04-08 00:00:00.000000000 Z
11
+ date: 2022-05-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-appconfig
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.18'
27
+ - !ruby/object:Gem::Dependency
28
+ name: aws-sdk-s3
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.114'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.114'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: aws-sdk-secretsmanager
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -245,9 +259,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
245
259
  version: 2.7.0
246
260
  required_rubygems_version: !ruby/object:Gem::Requirement
247
261
  requirements:
248
- - - ">="
262
+ - - ">"
249
263
  - !ruby/object:Gem::Version
250
- version: '0'
264
+ version: 1.3.1
251
265
  requirements: []
252
266
  rubygems_version: 3.1.6
253
267
  signing_key: