configuration_service 2.2.0 → 2.3.1
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/.gemspec +2 -0
- data/.travis.yml +2 -3
- data/lib/configuration_service/factory/context.rb +14 -2
- data/lib/configuration_service/factory/environment_context.rb +38 -35
- data/lib/configuration_service/factory/environment_context_backward_compatibility.rb +75 -0
- data/lib/configuration_service/factory/yaml_file_context.rb +39 -0
- data/lib/configuration_service/version.rb +1 -1
- metadata +6 -5
- data/lib/configuration_service/factory/environment_context/backward_compatibility.rb +0 -89
- data/lib/configuration_service/factory/environment_context/env_dict.rb +0 -108
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5547c75cb69883e74a7327fe86914d6b9294b3db
|
4
|
+
data.tar.gz: b53686e2e3557309781fa691081fbbde1682b2c7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f925edffb72981b4d10ebfb4330d89ff4065361a9091bf41f8aa05107a25c602c7ef22a2598cae704c2d40c55e9aedf06d7ce94e606b4ca98fe91ce6d3549425
|
7
|
+
data.tar.gz: bd35e4fdf79ea9cfe602c51b74a3fa24dca6318fd9975b2e61a2728bd8441ea13df555fd47ce1d3b2d91bf212265d985cc9cf747af57067239e4abc4d29c01a3
|
data/.gemspec
CHANGED
@@ -18,6 +18,8 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
+
spec.required_ruby_version = '>= 2.1'
|
22
|
+
|
21
23
|
spec.add_development_dependency "bundler", "~> 1.7"
|
22
24
|
spec.add_development_dependency "rake", "~> 11.1"
|
23
25
|
spec.add_development_dependency "cucumber", "~> 2.0"
|
data/.travis.yml
CHANGED
@@ -69,12 +69,24 @@ module ConfigurationService
|
|
69
69
|
end
|
70
70
|
|
71
71
|
##
|
72
|
-
#
|
72
|
+
# Deletes the internal copy of the +source+
|
73
73
|
#
|
74
|
-
#
|
74
|
+
# Called by the {ConfigurationService::Factory} after the client is created,
|
75
|
+
# to prevent in-process compromise of the context (e.g. by an exception handler
|
76
|
+
# that dumps the environment in a web application).
|
77
|
+
#
|
78
|
+
# The original +source+ remains untouched. It is assumed to be secure. However, subclasses such as
|
79
|
+
# {ConfigurationService::Factory::EnvironmentContext} should scrub sources as well.
|
80
|
+
#
|
81
|
+
# Sources such as the process +ENV+ and (on JRuby) system properties
|
75
82
|
# should not be used with this class; instead, they should be accessed through {ConfigurationService::Factory::EnvironmentContext}.
|
83
|
+
# Temporary YAML file sources should be accessed through {ConfigurationService::Factory::YamlFileContext}.
|
84
|
+
#
|
85
|
+
# Attempts to read context properties after scrubbing will raise a +SecurityError+.
|
76
86
|
#
|
77
87
|
def scrub!
|
88
|
+
@env = Hash.new { raise SecurityError, "can't access scrubbed environment context" }
|
89
|
+
nil
|
78
90
|
end
|
79
91
|
|
80
92
|
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
require "configuration_service/factory/context"
|
2
|
+
require "configuration_service/factory/environment_context_backward_compatibility"
|
2
3
|
|
3
4
|
module ConfigurationService
|
4
5
|
|
@@ -13,12 +14,12 @@ module ConfigurationService
|
|
13
14
|
#
|
14
15
|
# Prior to version 2.2.0, this class provided factory functionality.
|
15
16
|
# Use of this class as a factory is deprecated, supported through the
|
16
|
-
# {ConfigurationService::Factory::
|
17
|
+
# {ConfigurationService::Factory::EnvironmentContextBackwardCompatibility} module.
|
17
18
|
# Consumers should use {ConfigurationService::Factory} instead.
|
18
19
|
#
|
19
|
-
class EnvironmentContext
|
20
|
+
class EnvironmentContext < Context
|
20
21
|
|
21
|
-
include
|
22
|
+
include EnvironmentContextBackwardCompatibility
|
22
23
|
|
23
24
|
attr_reader :prefix
|
24
25
|
|
@@ -51,44 +52,40 @@ module ConfigurationService
|
|
51
52
|
# the environment variable is preferred.
|
52
53
|
#
|
53
54
|
def initialize(sources = default_sources, prefix = DEFAULT_PREFIX)
|
54
|
-
@
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
##
|
76
|
-
# @see ConfigurationService::Factory::Context#provider_config
|
77
|
-
def provider_config
|
78
|
-
@env.subslice(:provider)
|
55
|
+
@sources = [sources].flatten
|
56
|
+
@prefix = prefix
|
57
|
+
@scrub_keys = []
|
58
|
+
env = Hash.new { |_, k| raise KeyError, "missing environment variable #{k}" }
|
59
|
+
|
60
|
+
merged_sources = @sources.inject { |m, e| m.merge(e) }
|
61
|
+
{
|
62
|
+
to_envvar("IDENTIFIER") => :identifier,
|
63
|
+
to_envvar("TOKEN") => :token,
|
64
|
+
to_envvar("PROVIDER") => :provider_id
|
65
|
+
}.each do |envvar, key|
|
66
|
+
env[key] = merged_sources[envvar]
|
67
|
+
@scrub_keys << envvar
|
68
|
+
end
|
69
|
+
config_prefix = to_envvar("PROVIDER_")
|
70
|
+
env[:provider_config] = merged_sources
|
71
|
+
.select { |envvar| envvar.start_with?(config_prefix) && @scrub_keys << envvar }
|
72
|
+
.map { |envvar, value| [envvar.sub(config_prefix, "").downcase.intern, value] }
|
73
|
+
.to_h
|
74
|
+
@env = SymbolicAccessWrapper.new(env)
|
79
75
|
end
|
80
76
|
|
81
77
|
##
|
82
|
-
# Scrub sources
|
83
|
-
#
|
84
|
-
# Called by the {ConfigurationService::Factory} after the client is created,
|
85
|
-
# to prevent in-process compromise of the context (e.g. by an exception handler
|
86
|
-
# that dumps the environment in a web application).
|
78
|
+
# Scrub +sources+
|
87
79
|
#
|
88
80
|
# Every property that matches the prefix is removed from all sources.
|
89
81
|
#
|
82
|
+
# @see ConfigurationService::Factory::Context#scrub!
|
83
|
+
#
|
90
84
|
def scrub!
|
91
|
-
@
|
85
|
+
@scrub_keys.each do |k|
|
86
|
+
@sources.each { |s| s.delete(k) }
|
87
|
+
end
|
88
|
+
super
|
92
89
|
end
|
93
90
|
|
94
91
|
private
|
@@ -97,6 +94,12 @@ module ConfigurationService
|
|
97
94
|
(RUBY_PLATFORM == "java" ? [java.lang.System.properties, ENV] : ENV)
|
98
95
|
end
|
99
96
|
|
97
|
+
def to_envvar(k = "")
|
98
|
+
s = k.to_s.upcase
|
99
|
+
(@prefix and @prefix.size > 0) ? "#{@prefix}_#{s}" : s
|
100
|
+
end
|
101
|
+
|
102
|
+
|
100
103
|
end
|
101
104
|
|
102
105
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module ConfigurationService
|
2
|
+
|
3
|
+
module Factory
|
4
|
+
|
5
|
+
##
|
6
|
+
# Support {ConfigurationService::Factory::EnvironmentContext}'s deprecated use as a factory
|
7
|
+
#
|
8
|
+
# New code should use {ConfigurationService::Factory} instead.
|
9
|
+
#
|
10
|
+
module EnvironmentContextBackwardCompatibility
|
11
|
+
|
12
|
+
def self.included(base)
|
13
|
+
base.extend(ClassMethods)
|
14
|
+
end
|
15
|
+
|
16
|
+
##
|
17
|
+
# Create a configuration service bootstrapped with environmental configuration
|
18
|
+
#
|
19
|
+
# The environment is scanned for {EnvironmentContext#prefix} matches, within which the following variables are used:
|
20
|
+
#
|
21
|
+
# [IDENTIFIER] the unique identity of the configuration data
|
22
|
+
# (see {ConfigurationService::Base#initialize})
|
23
|
+
# [TOKEN] authorization token for the identified configuration data
|
24
|
+
# (see {ConfigurationService::Base#initialize})
|
25
|
+
# [PROVIDER] the unique identity of the service provider
|
26
|
+
# (see {ConfigurationService::ProviderRegistry})
|
27
|
+
# [PROVIDER_*] configuration options for the service provider
|
28
|
+
# (see service provider documentation)
|
29
|
+
#
|
30
|
+
# On JRuby, system properties are also scanned. Where a system property and environment variable of the
|
31
|
+
# same name exist, the environment variable is preferred.
|
32
|
+
#
|
33
|
+
# The service provider class is fetched from the {ConfigurationService::ProviderRegistry} using +PROVIDER+.
|
34
|
+
# A service provider instance is then constructed with a dictionary of the +PROVIDER_*+ variables,
|
35
|
+
# in which the keys are the name of the variable without +PROVIDER_+, downcased and intern'd.
|
36
|
+
#
|
37
|
+
# Then a service {ConfigurationService::Base} is constructed with the +IDENTIFIER+, +TOKEN+ and service provider instance.
|
38
|
+
#
|
39
|
+
# And finally, the environment is scrubbed of the variables used, to protect them from accidental exposure
|
40
|
+
# (e.g. in an exception handler that prints the environment). On JRuby, system properties are scrubbed of variables used as well,
|
41
|
+
# regardless of whether they were overridden by environment variables.
|
42
|
+
#
|
43
|
+
# @return [ConfigurationService::Base] the configuration service instance created
|
44
|
+
# @raise [ProviderNotFoundError] if no service provider has been registered with the name given by +PROVIDER+
|
45
|
+
#
|
46
|
+
# @deprecated Use {ConfigurationService::Factory} instead.
|
47
|
+
#
|
48
|
+
def create
|
49
|
+
$stderr.puts "warning: ConfigurationService::Factory::EnvironmentContext#create is deprecated: use ConfigurationService::Factory instead"
|
50
|
+
ConfigurationService::Factory.create_client(self)
|
51
|
+
end
|
52
|
+
|
53
|
+
module ClassMethods
|
54
|
+
|
55
|
+
##
|
56
|
+
# Return a configuration service bootstrapped with environmental configuration
|
57
|
+
#
|
58
|
+
# Instantiates a new factory with the process +ENV+ and the {EnvironmentContext::DEFAULT_PREFIX}
|
59
|
+
# and uses it to create a configuration service.
|
60
|
+
#
|
61
|
+
# @see ConfigurationService::Factory::EnvironmentContextBackwardCompatibility#create
|
62
|
+
#
|
63
|
+
# @deprecated Use {ConfigurationService::Factory} instead.
|
64
|
+
#
|
65
|
+
def create
|
66
|
+
new.create
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require "yaml"
|
2
|
+
|
3
|
+
require "configuration_service/factory/context"
|
4
|
+
|
5
|
+
module ConfigurationService
|
6
|
+
|
7
|
+
module Factory
|
8
|
+
|
9
|
+
class YamlFileContext < Context
|
10
|
+
|
11
|
+
##
|
12
|
+
# A factory context for a YAML file
|
13
|
+
#
|
14
|
+
# Note that {#scrub!} deletes the file. This context is intended to be used with
|
15
|
+
# a temporary file created by a bootstrapper.
|
16
|
+
#
|
17
|
+
# For a context for the process +ENV+ and (on JRuby) system properties,
|
18
|
+
# see {ConfigurationService::Factory::EnvironmentContext}.
|
19
|
+
#
|
20
|
+
def initialize(filename)
|
21
|
+
@filename = File.expand_path(filename)
|
22
|
+
@env = SymbolicAccessWrapper.new(YAML.load_file(@filename))
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Delete +filename+
|
27
|
+
#
|
28
|
+
# @see ConfigurationService::Factory::Context#scrub!
|
29
|
+
#
|
30
|
+
def scrub!
|
31
|
+
File.unlink(@filename) if File.exist?(@filename)
|
32
|
+
super
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: configuration_service
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sheldon Hearn
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-06-
|
11
|
+
date: 2016-06-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -115,8 +115,8 @@ files:
|
|
115
115
|
- lib/configuration_service/factory/context.rb
|
116
116
|
- lib/configuration_service/factory/context/symbolic_access_wrapper.rb
|
117
117
|
- lib/configuration_service/factory/environment_context.rb
|
118
|
-
- lib/configuration_service/factory/
|
119
|
-
- lib/configuration_service/factory/
|
118
|
+
- lib/configuration_service/factory/environment_context_backward_compatibility.rb
|
119
|
+
- lib/configuration_service/factory/yaml_file_context.rb
|
120
120
|
- lib/configuration_service/provider.rb
|
121
121
|
- lib/configuration_service/provider/broken.rb
|
122
122
|
- lib/configuration_service/provider/stub.rb
|
@@ -142,7 +142,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
142
142
|
requirements:
|
143
143
|
- - ">="
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version: '
|
145
|
+
version: '2.1'
|
146
146
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
147
|
requirements:
|
148
148
|
- - ">="
|
@@ -155,3 +155,4 @@ signing_key:
|
|
155
155
|
specification_version: 4
|
156
156
|
summary: Configuration service
|
157
157
|
test_files: []
|
158
|
+
has_rdoc:
|
@@ -1,89 +0,0 @@
|
|
1
|
-
module ConfigurationService
|
2
|
-
|
3
|
-
module Factory
|
4
|
-
|
5
|
-
class EnvironmentContext
|
6
|
-
|
7
|
-
##
|
8
|
-
# Support {ConfigurationService::Factory::EnvironmentContext}'s deprecated use as a factory
|
9
|
-
#
|
10
|
-
# New code should use {ConfigurationService::Factory} instead.
|
11
|
-
#
|
12
|
-
module BackwardCompatibility
|
13
|
-
|
14
|
-
def self.included(base)
|
15
|
-
base.extend(ClassMethods)
|
16
|
-
end
|
17
|
-
|
18
|
-
##
|
19
|
-
# Create a configuration service bootstrapped with environmental configuration
|
20
|
-
#
|
21
|
-
# The environment is scanned for {#prefix} matches, within which the following variables are used:
|
22
|
-
#
|
23
|
-
# [IDENTIFIER] the unique identity of the configuration data
|
24
|
-
# (see {ConfigurationService::Base#initialize})
|
25
|
-
# [TOKEN] authorization token for the identified configuration data
|
26
|
-
# (see {ConfigurationService::Base#initialize})
|
27
|
-
# [PROVIDER] the unique identity of the service provider
|
28
|
-
# (see {ConfigurationService::ProviderRegistry})
|
29
|
-
# [PROVIDER_*] configuration options for the service provider
|
30
|
-
# (see service provider documentation)
|
31
|
-
#
|
32
|
-
# On JRuby, system properties are also scanned. Where a system property and environment variable of the
|
33
|
-
# same name exist, the environment variable is preferred.
|
34
|
-
#
|
35
|
-
# The service provider class is fetched from the {ConfigurationService::ProviderRegistry} using +PROVIDER+.
|
36
|
-
# A service provider instance is then constructed with a dictionary of the +PROVIDER_*+ variables,
|
37
|
-
# in which the keys are the name of the variable without +PROVIDER_+, downcased and intern'd.
|
38
|
-
#
|
39
|
-
# Then a service {ConfigurationService::Base} is constructed with the +IDENTIFIER+, +TOKEN+ and service provider instance.
|
40
|
-
#
|
41
|
-
# And finally, the environment is scrubbed of the variables used, to protect them from accidental exposure
|
42
|
-
# (e.g. in an exception handler that prints the environment). On JRuby, system properties are scrubbed of variables used as well,
|
43
|
-
# regardless of whether they were overridden by environment variables.
|
44
|
-
#
|
45
|
-
# @return [ConfigurationService::Base] the configuration service instance created
|
46
|
-
# @raise [ProviderNotFoundError] if no service provider has been registered with the name given by +PROVIDER+
|
47
|
-
#
|
48
|
-
# @deprecated Use {ConfigurationService::Factory} instead.
|
49
|
-
#
|
50
|
-
def create
|
51
|
-
ConfigurationService.new(@env[:identifier], @env[:token], provider).tap do
|
52
|
-
scrub!
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
module ClassMethods
|
57
|
-
|
58
|
-
##
|
59
|
-
# Return a configuration service bootstrapped with environmental configuration
|
60
|
-
#
|
61
|
-
# Instantiates a new factory with the process +ENV+ and the {DEFAULT_PREFIX} and uses it to create a configuration service.
|
62
|
-
#
|
63
|
-
# @see ConfigurationService::Factory::EnvironmentContext::BackwardCompatibility#create
|
64
|
-
#
|
65
|
-
# @deprecated Use {ConfigurationService::Factory} instead.
|
66
|
-
#
|
67
|
-
def create
|
68
|
-
new.create
|
69
|
-
end
|
70
|
-
|
71
|
-
end
|
72
|
-
|
73
|
-
private
|
74
|
-
|
75
|
-
def provider
|
76
|
-
provider_id = @env[:provider]
|
77
|
-
provider_config = @env.subslice(:provider)
|
78
|
-
provider_class = ConfigurationService::ProviderRegistry.instance.lookup(provider_id)
|
79
|
-
provider_class or raise ProviderNotFoundError, "provider not registered: #{provider_id}"
|
80
|
-
provider_class.new(provider_config)
|
81
|
-
end
|
82
|
-
|
83
|
-
end
|
84
|
-
|
85
|
-
end
|
86
|
-
|
87
|
-
end
|
88
|
-
|
89
|
-
end
|
@@ -1,108 +0,0 @@
|
|
1
|
-
module ConfigurationService
|
2
|
-
|
3
|
-
module Factory
|
4
|
-
|
5
|
-
class EnvironmentContext
|
6
|
-
|
7
|
-
class EnvDict < Hash
|
8
|
-
|
9
|
-
def initialize(sources, *path)
|
10
|
-
@sources = sources.is_a?(Array) ? sources : [ sources ]
|
11
|
-
@env = @sources.inject { |m, e| m.merge(e) }
|
12
|
-
@path = build_path(*path)
|
13
|
-
|
14
|
-
env_keys.each do |k|
|
15
|
-
self.store(symbolic_key(k), @env[k])
|
16
|
-
end
|
17
|
-
|
18
|
-
self.default_proc = envdict_default_proc
|
19
|
-
end
|
20
|
-
|
21
|
-
def subslice(key)
|
22
|
-
EnvDict.new(@env, @path, key).tap do |s|
|
23
|
-
(@slices ||= []) << s
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def scrub!
|
28
|
-
@path or raise RuntimeError, "refusing to scrub without path"
|
29
|
-
|
30
|
-
scrub_env!
|
31
|
-
scrub_slices!
|
32
|
-
scrub_self!
|
33
|
-
|
34
|
-
@scrubbed = true
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
def envdict_default_proc
|
40
|
-
proc do |_, key|
|
41
|
-
assert_not_scrubbed!
|
42
|
-
try_string(key) or raise_key_error(key)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def try_string(k)
|
47
|
-
if (skey = k.intern rescue false) and self.include?(skey)
|
48
|
-
self.fetch(skey)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def raise_key_error(k)
|
53
|
-
envar = build_path(@path, k.to_s).upcase
|
54
|
-
raise KeyError, "missing environment variable #{envar}"
|
55
|
-
end
|
56
|
-
|
57
|
-
def env_keys(env = @env)
|
58
|
-
env.keys.select { |k| under_path?(k) }
|
59
|
-
end
|
60
|
-
|
61
|
-
def under_path?(k)
|
62
|
-
!!symbolic_key(k)
|
63
|
-
end
|
64
|
-
|
65
|
-
def symbolic_key(k)
|
66
|
-
prefix = build_path(@path, "")
|
67
|
-
s = k.downcase
|
68
|
-
if s.slice!(prefix) and !s.empty?
|
69
|
-
s.intern
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def build_path(*path)
|
74
|
-
path = path.compact
|
75
|
-
if path.empty?
|
76
|
-
nil
|
77
|
-
else
|
78
|
-
path.map { |p| p.to_s.downcase }.join("_")
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def assert_not_scrubbed!
|
83
|
-
!@scrubbed or raise SecurityError, "can't access scrubbed environment dictionary"
|
84
|
-
end
|
85
|
-
|
86
|
-
def scrub_env!
|
87
|
-
@sources.each do |env|
|
88
|
-
env_keys(env).each { |k| env.delete(k) }
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def scrub_slices!
|
93
|
-
@slices.each { |s| s.scrub! } if @slices
|
94
|
-
end
|
95
|
-
|
96
|
-
def scrub_self!
|
97
|
-
self.keys.each do |k|
|
98
|
-
self.delete(k)
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
end
|
103
|
-
|
104
|
-
end
|
105
|
-
|
106
|
-
end
|
107
|
-
|
108
|
-
end
|