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 +4 -4
- data/VERSION +1 -1
- data/lib/prefab/config_client.rb +0 -15
- data/lib/prefab/config_loader.rb +45 -43
- data/lib/prefab/options.rb +3 -3
- data/prefab-cloud-ruby.gemspec +5 -4
- data/test/.prefab.default.config.yaml +2 -0
- data/test/.prefab.unit_tests.config.yaml +25 -0
- data/test/test_client.rb +1 -1
- data/test/test_config_client.rb +16 -1
- data/test/test_config_loader.rb +11 -3
- data/test/test_helper.rb +1 -1
- metadata +4 -3
- data/test/.prefab.test.config.yaml +0 -32
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2fef66a6ac50710f11854f9168c30573ef3fea74acd9089308d1a70ac754f584
|
4
|
+
data.tar.gz: 7b424813748667165d263f0869cf0a93c56d9f0fdafe60f22799b358f3f5688a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 03d9230267363cc51962c3a244f39cc9b6e6bda7da3c6e9b460ed195330d3035840f69fc2837f66b86a4c05d6b830a14db56aee4578fa5e13e580c7be89fa6c8
|
7
|
+
data.tar.gz: 1b084b6f4b8180069a214a6edcaeb5d23c1afb234f5161870a6b11d5d2841a1d05683f65eeb94c9cd6b92cd02d70296e2abb9d430d2f1c6143ee2d0224ae3b85
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.14.0
|
data/lib/prefab/config_client.rb
CHANGED
@@ -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
|
data/lib/prefab/config_loader.rb
CHANGED
@@ -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
|
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
|
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
|
-
|
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,
|
135
|
+
def feature_flag_config(file, key, value)
|
134
136
|
criteria = Prefab::Criteria.new(operator: 'ALWAYS_TRUE')
|
135
137
|
|
136
|
-
if
|
137
|
-
criteria = Prefab::Criteria.new(criteria_values(
|
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
|
158
|
-
raise Prefab::Error, "Feature flag config `#{
|
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:
|
165
|
+
match: key,
|
164
166
|
config: Prefab::Config.new(
|
165
|
-
key:
|
166
|
-
variants: [Prefab::FeatureFlagVariant.new(value_from(
|
167
|
+
key: key,
|
168
|
+
variants: [Prefab::FeatureFlagVariant.new(value_from(value['value']))],
|
167
169
|
rows: [row]
|
168
170
|
)
|
169
171
|
}
|
data/lib/prefab/options.rb
CHANGED
@@ -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 :
|
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
|
-
|
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
|
-
@
|
70
|
+
@prefab_envs = Array(prefab_envs)
|
71
71
|
end
|
72
72
|
|
73
73
|
def local_only?
|
data/prefab-cloud-ruby.gemspec
CHANGED
@@ -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.
|
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.
|
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-
|
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.
|
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,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
|
-
|
92
|
+
prefab_envs: ["unit_tests"],
|
93
93
|
prefab_datasources: Prefab::Options::DATASOURCES::LOCAL_ONLY
|
94
94
|
}.merge(overrides))
|
95
95
|
|
data/test/test_config_client.rb
CHANGED
@@ -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
|
-
|
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: "",
|
data/test/test_config_loader.rb
CHANGED
@@ -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
|
-
|
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
|
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
|
-
|
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
|
-
|
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.
|
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-
|
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.
|
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
|