prefab-cloud-ruby 0.13.3 → 0.14.0

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: fc875095444727947594dfa96e7a4e59fbab20a14ec486fdd4b804b936aad374
4
- data.tar.gz: 7af3f2155fdb85063c674b4f4bf3365b089e507789adf9eaa0ca5b4e206b9e19
3
+ metadata.gz: 2fef66a6ac50710f11854f9168c30573ef3fea74acd9089308d1a70ac754f584
4
+ data.tar.gz: 7b424813748667165d263f0869cf0a93c56d9f0fdafe60f22799b358f3f5688a
5
5
  SHA512:
6
- metadata.gz: aff23956f0c34934a5702bd51517ac14111a7888ba99948537fb76fbcdf162abf6a032ae8caba5c902e06894b0f3bf5ffcf5a95efce9cf00210b4f333059e233
7
- data.tar.gz: 21717c0f85eecd1972baf9fc1d8fa8b57d225da60eb6cba006b3ac4f288f4fab77c18f5d6a34e49ca8beb8835e22a520b3bc92b058658309d41db5eba9a05c86
6
+ metadata.gz: 03d9230267363cc51962c3a244f39cc9b6e6bda7da3c6e9b460ed195330d3035840f69fc2837f66b86a4c05d6b830a14db56aee4578fa5e13e580c7be89fa6c8
7
+ data.tar.gz: 1b084b6f4b8180069a214a6edcaeb5d23c1afb234f5161870a6b11d5d2841a1d05683f65eeb94c9cd6b92cd02d70296e2abb9d430d2f1c6143ee2d0224ae3b85
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.13.3
1
+ 0.14.0
@@ -5,7 +5,6 @@ module Prefab
5
5
 
6
6
  RECONNECT_WAIT = 5
7
7
  DEFAULT_CHECKPOINT_FREQ_SEC = 60
8
- DEFAULT_S3CF_BUCKET = 'http://d2j4ed6ti5snnd.cloudfront.net'
9
8
  SSE_READ_TIMEOUT = 300
10
9
 
11
10
  def initialize(base_client, timeout)
@@ -29,8 +28,6 @@ module Prefab
29
28
 
30
29
  @cancellable_interceptor = Prefab::CancellableInterceptor.new(@base_client)
31
30
 
32
- @s3_cloud_front = ENV["PREFAB_S3CF_BUCKET"] || DEFAULT_S3CF_BUCKET
33
-
34
31
  if @options.local_only?
35
32
  finish_init!(:local_only)
36
33
  else
@@ -119,7 +116,6 @@ module Prefab
119
116
  interceptors: [@base_client.interceptor, @cancellable_interceptor])
120
117
  end
121
118
 
122
- # try API first, if not, fallback to s3
123
119
  def load_checkpoint
124
120
  success = load_checkpoint_api_cdn
125
121
 
@@ -134,12 +130,6 @@ module Prefab
134
130
  if success
135
131
  return
136
132
  else
137
- @base_client.log_internal Logger::INFO, "LoadCheckpoint: Fallback to S3"
138
- end
139
-
140
- success = load_checkpoint_from_s3
141
-
142
- if !success
143
133
  @base_client.log_internal Logger::WARN, "No success loading checkpoints"
144
134
  end
145
135
  end
@@ -172,11 +162,6 @@ module Prefab
172
162
  load_url(conn, :remote_cdn_api)
173
163
  end
174
164
 
175
- def load_checkpoint_from_s3
176
- url = "#{@s3_cloud_front}/#{@base_client.api_key.gsub("|", "/")}"
177
- load_url(Faraday.new(url), :remote_s3)
178
- end
179
-
180
165
  def load_url(conn, source)
181
166
  resp = conn.get('')
182
167
  if resp.status == 200
@@ -56,57 +56,59 @@ module Prefab
56
56
 
57
57
  def load_classpath_config
58
58
  classpath_dir = @prefab_options.prefab_config_classpath_dir
59
- load_glob(File.join(classpath_dir, ".prefab*config.yaml"))
59
+ rtn = load_glob(File.join(classpath_dir, ".prefab.default.config.yaml"))
60
+ @prefab_options.prefab_envs.each do |env|
61
+ rtn = rtn.merge load_glob(File.join(classpath_dir, ".prefab.#{env}.config.yaml"))
62
+ end
63
+ rtn
60
64
  end
61
65
 
62
66
  def load_local_overrides
63
67
  override_dir = @prefab_options.prefab_config_override_dir
64
- load_glob(File.join(override_dir, ".prefab*config.yaml"))
68
+ rtn = load_glob(File.join(override_dir, ".prefab.overrides.config.yaml"))
69
+ @prefab_options.prefab_envs.each do |env|
70
+ rtn = rtn.merge load_glob(File.join(override_dir, ".prefab.#{env}.config.yaml"))
71
+ end
72
+ rtn
65
73
  end
66
74
 
67
75
  def load_glob(glob)
68
76
  rtn = {}
69
77
  Dir.glob(glob).each do |file|
78
+ @base_client.log_internal Logger::INFO, "Load #{file}"
70
79
  yaml = load(file)
71
80
  yaml.each do |k, v|
72
- if v.class == Hash
73
- v.each do |env_k, env_v|
74
- if k == @prefab_options.defaults_env
75
- if env_v.class == Hash && env_v['feature_flag']
76
- rtn[env_k] = feature_flag_config(file, k, env_k, env_v)
77
- else
78
- rtn[env_k] = {
79
- source: file,
80
- match: k,
81
- config: Prefab::Config.new(
82
- key: env_k,
83
- rows: [
84
- Prefab::ConfigRow.new(value: Prefab::ConfigValue.new(value_from(env_v)))
85
- ]
86
- )
87
- }
88
- end
89
- else
90
- next
91
- end
92
- end
93
- else
94
- rtn[k] = {
95
- source: file,
96
- match: "default",
97
- config: Prefab::Config.new(
98
- key: k,
99
- rows: [
100
- Prefab::ConfigRow.new(value: Prefab::ConfigValue.new(value_from(v)))
101
- ]
102
- )
103
- }
104
- end
81
+ load_kv(k, v, rtn, file)
105
82
  end
106
83
  end
107
84
  rtn
108
85
  end
109
86
 
87
+ def load_kv(k, v, rtn, file)
88
+ if v.class == Hash
89
+ if v['feature_flag']
90
+ rtn[k] = feature_flag_config(file, k, v)
91
+ else
92
+ v.each do |nest_k, nest_v|
93
+ nested_key = "#{k}.#{nest_k}"
94
+ nested_key = k if nest_k == "_"
95
+ load_kv(nested_key, nest_v, rtn, file)
96
+ end
97
+ end
98
+ else
99
+ rtn[k] = {
100
+ source: file,
101
+ match: "default",
102
+ config: Prefab::Config.new(
103
+ key: k,
104
+ rows: [
105
+ Prefab::ConfigRow.new(value: Prefab::ConfigValue.new(value_from(v)))
106
+ ]
107
+ )
108
+ }
109
+ end
110
+ end
111
+
110
112
  def load(filename)
111
113
  if File.exist? filename
112
114
  @base_client.log_internal Logger::INFO, "Load #{filename}"
@@ -130,11 +132,11 @@ module Prefab
130
132
  end
131
133
  end
132
134
 
133
- def feature_flag_config(file, k, env_k, env_v)
135
+ def feature_flag_config(file, key, value)
134
136
  criteria = Prefab::Criteria.new(operator: 'ALWAYS_TRUE')
135
137
 
136
- if env_v['criteria']
137
- criteria = Prefab::Criteria.new(criteria_values(env_v['criteria']))
138
+ if value['criteria']
139
+ criteria = Prefab::Criteria.new(criteria_values(value['criteria']))
138
140
  end
139
141
 
140
142
  row = Prefab::ConfigRow.new(
@@ -154,16 +156,16 @@ module Prefab
154
156
  )
155
157
  )
156
158
 
157
- unless env_v.has_key?('value')
158
- raise Prefab::Error, "Feature flag config `#{env_k}` #{file} must have a `value`"
159
+ unless value.has_key?('value')
160
+ raise Prefab::Error, "Feature flag config `#{key}` #{file} must have a `value`"
159
161
  end
160
162
 
161
163
  {
162
164
  source: file,
163
- match: k,
165
+ match: key,
164
166
  config: Prefab::Config.new(
165
- key: env_k,
166
- variants: [Prefab::FeatureFlagVariant.new(value_from(env_v['value']))],
167
+ key: key,
168
+ variants: [Prefab::FeatureFlagVariant.new(value_from(value['value']))],
167
169
  rows: [row]
168
170
  )
169
171
  }
@@ -14,7 +14,7 @@ module Prefab
14
14
  attr_reader :on_init_failure
15
15
  attr_reader :prefab_config_override_dir
16
16
  attr_reader :prefab_config_classpath_dir
17
- attr_reader :defaults_env
17
+ attr_reader :prefab_envs
18
18
 
19
19
  DEFAULT_LOG_FORMATTER = proc { |severity, datetime, progname, msg|
20
20
  "#{severity.ljust(5)} #{datetime}: #{progname} #{msg}\n"
@@ -50,7 +50,7 @@ module Prefab
50
50
  prefab_datasources: ENV['PREFAB_DATASOURCES'] == "LOCAL_ONLY" ? DATASOURCES::LOCAL_ONLY : DATASOURCES::ALL,
51
51
  prefab_config_override_dir: Dir.home,
52
52
  prefab_config_classpath_dir: ".",
53
- defaults_env: ""
53
+ prefab_envs: ENV['PREFAB_ENVS'].nil? ? [] : ENV['PREFAB_ENVS'].split(",")
54
54
  )
55
55
  # debugger
56
56
  @api_key = api_key
@@ -67,7 +67,7 @@ module Prefab
67
67
  @prefab_datasources = prefab_datasources
68
68
  @prefab_config_classpath_dir = prefab_config_classpath_dir
69
69
  @prefab_config_override_dir = prefab_config_override_dir
70
- @defaults_env = defaults_env
70
+ @prefab_envs = Array(prefab_envs)
71
71
  end
72
72
 
73
73
  def local_only?
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: prefab-cloud-ruby 0.13.3 ruby lib
5
+ # stub: prefab-cloud-ruby 0.14.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "prefab-cloud-ruby".freeze
9
- s.version = "0.13.3"
9
+ s.version = "0.14.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
13
  s.authors = ["Jeff Dwyer".freeze]
14
- s.date = "2022-08-12"
14
+ s.date = "2022-08-15"
15
15
  s.description = "RateLimits & Config as a service".freeze
16
16
  s.email = "jdwyer@prefab.cloud".freeze
17
17
  s.extra_rdoc_files = [
@@ -54,7 +54,8 @@ Gem::Specification.new do |s|
54
54
  "lib/prefab_services_pb.rb",
55
55
  "prefab-cloud-ruby.gemspec",
56
56
  "run_test_harness_server.sh",
57
- "test/.prefab.test.config.yaml",
57
+ "test/.prefab.default.config.yaml",
58
+ "test/.prefab.unit_tests.config.yaml",
58
59
  "test/harness_server.rb",
59
60
  "test/test_client.rb",
60
61
  "test/test_config_client.rb",
@@ -0,0 +1,2 @@
1
+ sample: default sample value
2
+ sample_bool: true
@@ -0,0 +1,25 @@
1
+ sample_int: 123
2
+ sample_double: 12.12
3
+ sample_bool: true
4
+ false_value: false
5
+ zero_value: 0
6
+ sample_to_override: Foo
7
+ prefab.log_level: debug
8
+ sample: test sample value
9
+ enabled_flag: true
10
+ disabled_flag: false
11
+ flag_with_a_value: { "feature_flag": "true", value: "all-features" }
12
+ in_lookup_key: { "feature_flag": "true", value: true, criteria: { operator: LOOKUP_KEY_IN, values: [ "abc123", "xyz987" ] } }
13
+ just_my_domain: { "feature_flag": "true", value: "new-version", criteria: { operator: PROP_IS_ONE_OF, property: "domain", values: [ "prefab.cloud", "example.com" ] } }
14
+ nested:
15
+ values:
16
+ _: top level
17
+ string: nested value
18
+
19
+ logging:
20
+ app:
21
+ _: error
22
+ controller:
23
+ hello:
24
+ _: warn
25
+ index: info
data/test/test_client.rb CHANGED
@@ -89,7 +89,7 @@ class TestClient < Minitest::Test
89
89
  options = Prefab::Options.new(**{
90
90
  prefab_config_override_dir: "none",
91
91
  prefab_config_classpath_dir: "test",
92
- defaults_env: "unit_tests",
92
+ prefab_envs: ["unit_tests"],
93
93
  prefab_datasources: Prefab::Options::DATASOURCES::LOCAL_ONLY
94
94
  }.merge(overrides))
95
95
 
@@ -6,7 +6,7 @@ class TestConfigClient < Minitest::Test
6
6
  options = Prefab::Options.new(
7
7
  prefab_config_override_dir: "none",
8
8
  prefab_config_classpath_dir: "test",
9
- defaults_env: "unit_tests",
9
+ prefab_envs: "unit_tests",
10
10
  prefab_datasources: Prefab::Options::DATASOURCES::LOCAL_ONLY
11
11
  )
12
12
 
@@ -32,6 +32,21 @@ class TestConfigClient < Minitest::Test
32
32
  assert_match(/couldn't initialize in 0.01 second timeout/, err.message)
33
33
  end
34
34
 
35
+ def test_prefab_envs_is_forgiving
36
+ assert_equal ["my_env"], Prefab::Options.new(
37
+ prefab_envs: "my_env",
38
+ ).prefab_envs
39
+
40
+ assert_equal ["my_env", "a_second_env"], Prefab::Options.new(
41
+ prefab_envs: ["my_env", "a_second_env"],
42
+ ).prefab_envs
43
+ end
44
+
45
+ def test_prefab_envs_env_var
46
+ ENV["PREFAB_ENVS"] = "one,two"
47
+ assert_equal ["one", "two"], Prefab::Options.new().prefab_envs
48
+ end
49
+
35
50
  def test_invalid_api_key_error
36
51
  options = Prefab::Options.new(
37
52
  api_key: "",
@@ -6,7 +6,7 @@ class TestConfigLoader < Minitest::Test
6
6
  options = Prefab::Options.new(
7
7
  prefab_config_override_dir: "none",
8
8
  prefab_config_classpath_dir: "test",
9
- defaults_env: "unit_tests"
9
+ prefab_envs: "unit_tests"
10
10
  )
11
11
  @loader = Prefab::ConfigLoader.new(MockBaseClient.new(options))
12
12
  end
@@ -18,11 +18,19 @@ class TestConfigLoader < Minitest::Test
18
18
  should_be :double, 12.12, "sample_double"
19
19
  end
20
20
 
21
- def test_load_in_no_default_env
21
+ def test_nested
22
+ should_be :string, "nested value", "nested.values.string"
23
+ should_be :string, "top level", "nested.values"
24
+ should_be :string, "error", "logging.app"
25
+ should_be :string, "warn", "logging.app.controller.hello"
26
+ should_be :string, "info", "logging.app.controller.hello.index"
27
+ end
28
+
29
+ def test_load_without_unit_test_env
22
30
  options = Prefab::Options.new(
23
31
  prefab_config_override_dir: "none",
24
32
  prefab_config_classpath_dir: "test",
25
- # no defaults_env
33
+ # no prefab_envs
26
34
  )
27
35
  @loader = Prefab::ConfigLoader.new(MockBaseClient.new(options))
28
36
  should_be :string, "default sample value", "sample"
data/test/test_helper.rb CHANGED
@@ -81,7 +81,7 @@ def new_client(overrides = {})
81
81
  options = Prefab::Options.new(**{
82
82
  prefab_config_override_dir: "none",
83
83
  prefab_config_classpath_dir: "test",
84
- defaults_env: "unit_tests",
84
+ prefab_envs: ["unit_tests"],
85
85
  prefab_datasources: Prefab::Options::DATASOURCES::LOCAL_ONLY
86
86
  }.merge(overrides))
87
87
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prefab-cloud-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.3
4
+ version: 0.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Dwyer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-12 00:00:00.000000000 Z
11
+ date: 2022-08-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -227,7 +227,8 @@ files:
227
227
  - lib/prefab_services_pb.rb
228
228
  - prefab-cloud-ruby.gemspec
229
229
  - run_test_harness_server.sh
230
- - test/.prefab.test.config.yaml
230
+ - test/.prefab.default.config.yaml
231
+ - test/.prefab.unit_tests.config.yaml
231
232
  - test/harness_server.rb
232
233
  - test/test_client.rb
233
234
  - test/test_config_client.rb
@@ -1,32 +0,0 @@
1
- sample: default sample value
2
- sample_int: 123
3
- sample_double: 12.12
4
- sample_bool: true
5
- false_value: false
6
- zero_value: 0
7
- sample_to_override: Foo
8
- prefab.log_level: debug
9
- unit_tests:
10
- sample: test sample value
11
- enabled_flag: true
12
- disabled_flag: false
13
- flag_with_a_value:
14
- feature_flag: true
15
- value: "all-features"
16
- in_lookup_key:
17
- feature_flag: true
18
- value: true
19
- criteria:
20
- operator: LOOKUP_KEY_IN
21
- values:
22
- - abc123
23
- - xyz987
24
- just_my_domain:
25
- feature_flag: true
26
- value: new-version
27
- criteria:
28
- operator: PROP_IS_ONE_OF
29
- property: domain
30
- values: ["prefab.cloud", "example.com"]
31
- ignored_env:
32
- sample: ignored value