prefab-cloud-ruby 0.13.3 → 0.14.0

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