puppet 4.9.4 → 4.10.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/Rakefile +6 -0
- data/ext/project_data.yaml +2 -2
- data/lib/hiera/puppet_function.rb +1 -1
- data/lib/puppet.rb +1 -0
- data/lib/puppet/application.rb +14 -0
- data/lib/puppet/application/inspect.rb +3 -0
- data/lib/puppet/defaults.rb +12 -2
- data/lib/puppet/etc.rb +125 -0
- data/lib/puppet/face/help.rb +1 -1
- data/lib/puppet/functions.rb +49 -4
- data/lib/puppet/functions/eyaml_lookup_key.rb +12 -3
- data/lib/puppet/functions/hocon_data.rb +9 -0
- data/lib/puppet/functions/json_data.rb +9 -0
- data/lib/puppet/functions/yaml_data.rb +9 -0
- data/lib/puppet/indirector/file_bucket_file/file.rb +69 -22
- data/lib/puppet/indirector/key/file.rb +2 -1
- data/lib/puppet/indirector/ssl_file.rb +24 -3
- data/lib/puppet/module.rb +28 -22
- data/lib/puppet/network/http/compression.rb +2 -1
- data/lib/puppet/parser/compiler.rb +15 -38
- data/lib/puppet/parser/functions/hiera.rb +1 -1
- data/lib/puppet/parser/functions/hiera_array.rb +1 -1
- data/lib/puppet/parser/functions/hiera_hash.rb +1 -1
- data/lib/puppet/parser/functions/hiera_include.rb +1 -1
- data/lib/puppet/parser/scope.rb +59 -17
- data/lib/puppet/pops/evaluator/callable_signature.rb +7 -0
- data/lib/puppet/pops/functions/dispatch.rb +18 -5
- data/lib/puppet/pops/functions/dispatcher.rb +7 -13
- data/lib/puppet/pops/issue_reporter.rb +1 -1
- data/lib/puppet/pops/issues.rb +84 -0
- data/lib/puppet/pops/loader/base_loader.rb +13 -5
- data/lib/puppet/pops/lookup/configured_data_provider.rb +8 -2
- data/lib/puppet/pops/lookup/data_dig_function_provider.rb +109 -19
- data/lib/puppet/pops/lookup/data_hash_function_provider.rb +19 -4
- data/lib/puppet/pops/lookup/data_provider.rb +43 -29
- data/lib/puppet/pops/lookup/environment_data_provider.rb +1 -1
- data/lib/puppet/pops/lookup/explainer.rb +1 -0
- data/lib/puppet/pops/lookup/function_provider.rb +36 -11
- data/lib/puppet/pops/lookup/global_data_provider.rb +18 -5
- data/lib/puppet/pops/lookup/hiera_config.rb +203 -84
- data/lib/puppet/pops/lookup/interpolation.rb +21 -6
- data/lib/puppet/pops/lookup/invocation.rb +14 -9
- data/lib/puppet/pops/lookup/location_resolver.rb +27 -0
- data/lib/puppet/pops/lookup/lookup_adapter.rb +59 -6
- data/lib/puppet/pops/lookup/lookup_key_function_provider.rb +9 -77
- data/lib/puppet/pops/lookup/module_data_provider.rb +27 -4
- data/lib/puppet/pops/parser/lexer2.rb +1 -1
- data/lib/puppet/pops/pcore.rb +3 -3
- data/lib/puppet/pops/types/p_object_type.rb +4 -6
- data/lib/puppet/pops/types/ruby_generator.rb +2 -2
- data/lib/puppet/pops/types/type_asserter.rb +3 -3
- data/lib/puppet/pops/types/type_mismatch_describer.rb +25 -7
- data/lib/puppet/pops/types/types.rb +20 -29
- data/lib/puppet/provider/exec.rb +4 -2
- data/lib/puppet/provider/nameservice.rb +8 -8
- data/lib/puppet/provider/selmodule/semodule.rb +20 -16
- data/lib/puppet/provider/service/src.rb +39 -39
- data/lib/puppet/provider/service/systemd.rb +1 -1
- data/lib/puppet/provider/user/aix.rb +7 -2
- data/lib/puppet/settings.rb +30 -17
- data/lib/puppet/ssl/base.rb +14 -1
- data/lib/puppet/ssl/certificate_authority.rb +4 -2
- data/lib/puppet/ssl/configuration.rb +4 -1
- data/lib/puppet/ssl/inventory.rb +10 -3
- data/lib/puppet/ssl/key.rb +7 -3
- data/lib/puppet/test/test_helper.rb +3 -0
- data/lib/puppet/type.rb +13 -1
- data/lib/puppet/type/exec.rb +16 -1
- data/lib/puppet/type/group.rb +17 -11
- data/lib/puppet/type/user.rb +3 -1
- data/lib/puppet/util.rb +1 -0
- data/lib/puppet/util/character_encoding.rb +95 -0
- data/lib/puppet/util/execution.rb +9 -6
- data/lib/puppet/util/reference.rb +4 -2
- data/lib/puppet/util/windows/file.rb +5 -1
- data/lib/puppet/version.rb +6 -2
- data/locales/config.yaml +1 -1
- data/locales/puppet.pot +18 -4
- data/spec/integration/ssl/autosign_spec.rb +18 -3
- data/spec/integration/ssl/key_spec.rb +104 -0
- data/spec/integration/type/user_spec.rb +13 -6
- data/spec/spec_helper.rb +7 -0
- data/spec/unit/application/inspect_spec.rb +9 -2
- data/spec/unit/data_providers/function_data_provider_spec.rb +2 -2
- data/spec/unit/etc_spec.rb +234 -0
- data/spec/unit/face/certificate_spec.rb +10 -2
- data/spec/unit/functions/dig_spec.rb +1 -1
- data/spec/unit/functions/hiera_spec.rb +40 -1
- data/spec/unit/functions/lookup_fixture_spec.rb +10 -10
- data/spec/unit/functions/lookup_spec.rb +1217 -357
- data/spec/unit/functions4_spec.rb +37 -1
- data/spec/unit/indirector/file_bucket_file/file_spec.rb +33 -2
- data/spec/unit/indirector/key/file_spec.rb +1 -1
- data/spec/unit/indirector/ssl_file_spec.rb +3 -3
- data/spec/unit/module_spec.rb +52 -59
- data/spec/unit/network/http/compression_spec.rb +39 -8
- data/spec/unit/parser/compiler_spec.rb +14 -0
- data/spec/unit/pops/loaders/loaders_spec.rb +21 -3
- data/spec/unit/pops/loaders/module_loaders_spec.rb +61 -0
- data/spec/unit/pops/lookup/context_spec.rb +56 -8
- data/spec/unit/pops/lookup/lookup_spec.rb +32 -1
- data/spec/unit/pops/parser/lexer2_spec.rb +8 -0
- data/spec/unit/pops/types/ruby_generator_spec.rb +48 -0
- data/spec/unit/pops/types/type_mismatch_describer_spec.rb +12 -3
- data/spec/unit/pops/types/types_spec.rb +6 -7
- data/spec/unit/provider/nameservice_spec.rb +12 -12
- data/spec/unit/provider/package/pkg_spec.rb +2 -0
- data/spec/unit/provider/service/src_spec.rb +5 -0
- data/spec/unit/ssl/base_spec.rb +9 -0
- data/spec/unit/ssl/certificate_authority_spec.rb +2 -2
- data/spec/unit/ssl/certificate_request_attributes_spec.rb +6 -0
- data/spec/unit/ssl/certificate_request_spec.rb +1 -1
- data/spec/unit/ssl/certificate_spec.rb +1 -1
- data/spec/unit/ssl/configuration_spec.rb +11 -2
- data/spec/unit/ssl/inventory_spec.rb +27 -3
- data/spec/unit/ssl/key_spec.rb +7 -7
- data/spec/unit/type/exec_spec.rb +41 -4
- data/spec/unit/type/file_spec.rb +4 -1
- data/spec/unit/util/character_encoding_spec.rb +88 -0
- data/spec/unit/util/execution_spec.rb +12 -0
- data/spec/unit/version_spec.rb +4 -0
- metadata +3803 -3808
- data/tasks/i18n.rake +0 -20
@@ -3,36 +3,32 @@ module Lookup
|
|
3
3
|
# @api private
|
4
4
|
module DataProvider
|
5
5
|
def self.key_type
|
6
|
-
ensure_types_initialized
|
7
6
|
@key_type
|
8
7
|
end
|
9
8
|
|
10
9
|
def self.value_type
|
11
|
-
ensure_types_initialized
|
12
10
|
@value_type
|
13
11
|
end
|
14
12
|
|
15
|
-
def self.
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
'Puppet::LookupKey' => 'Variant[String,Numeric]',
|
13
|
+
def self.register_types(loader)
|
14
|
+
(@key_type, @value_type) = Pcore::register_aliases({
|
15
|
+
# The Pcore type for all keys and subkeys in a data hash.
|
16
|
+
'Puppet::LookupKey' => 'Variant[String,Numeric]',
|
20
17
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
18
|
+
# The Pcore type for all values and sub-values in a data hash. The
|
19
|
+
# type is self-recursive to enforce the same constraint on values contained
|
20
|
+
# in arrays and hashes
|
21
|
+
'Puppet::LookupValue' => <<-PUPPET
|
22
|
+
Variant[
|
23
|
+
Scalar,
|
24
|
+
Undef,
|
25
|
+
Sensitive,
|
26
|
+
Type,
|
27
|
+
Hash[Puppet::LookupKey, Puppet::LookupValue],
|
28
|
+
Array[Puppet::LookupValue]
|
29
|
+
]
|
33
30
|
PUPPET
|
34
|
-
|
35
|
-
end
|
31
|
+
}, Pcore::RUNTIME_NAME_AUTHORITY, loader)
|
36
32
|
end
|
37
33
|
|
38
34
|
# Performs a lookup with an endless recursion check.
|
@@ -45,6 +41,17 @@ module DataProvider
|
|
45
41
|
lookup_invocation.check(key.to_s) { unchecked_key_lookup(key, lookup_invocation, merge) }
|
46
42
|
end
|
47
43
|
|
44
|
+
# Performs a lookup using a module default hierarchy with an endless recursion check. All providers except
|
45
|
+
# the `ModuleDataProvider` will throw `:no_such_key` if this method is called.
|
46
|
+
#
|
47
|
+
# @param key [LookupKey] The key to lookup
|
48
|
+
# @param lookup_invocation [Invocation] The current lookup invocation
|
49
|
+
# @param merge [MergeStrategy,String,Hash{String=>Object},nil] Merge strategy or hash with strategy and options
|
50
|
+
#
|
51
|
+
def key_lookup_in_default(key, lookup_invocation, merge)
|
52
|
+
throw :no_such_key
|
53
|
+
end
|
54
|
+
|
48
55
|
def lookup(key, lookup_invocation, merge)
|
49
56
|
lookup_invocation.check(key.to_s) { unchecked_key_lookup(key, lookup_invocation, merge) }
|
50
57
|
end
|
@@ -70,23 +77,30 @@ module DataProvider
|
|
70
77
|
raise NotImplementedError, "Subclass of #{DataProvider.name} must implement 'name' method"
|
71
78
|
end
|
72
79
|
|
73
|
-
#
|
80
|
+
# @returns `true` if the value provided by this instance can always be trusted, `false` otherwise
|
81
|
+
def value_is_validated?
|
82
|
+
false
|
83
|
+
end
|
84
|
+
|
85
|
+
# Asserts that _data_hash_ is a hash. Will yield to obtain origin of value in case an error is produced
|
74
86
|
#
|
75
|
-
# @param data_provider [DataProvider] The data provider that produced the hash
|
76
87
|
# @param data_hash [Hash{String=>Object}] The data hash
|
77
88
|
# @return [Hash{String=>Object}] The data hash
|
78
|
-
def validate_data_hash(
|
79
|
-
Types::TypeAsserter.assert_instance_of(nil, Types::PHashType::DEFAULT, data_hash)
|
89
|
+
def validate_data_hash(data_hash, &block)
|
90
|
+
Types::TypeAsserter.assert_instance_of(nil, Types::PHashType::DEFAULT, data_hash, &block)
|
80
91
|
end
|
81
92
|
|
82
|
-
# Asserts that _data_value_ is of valid type.
|
93
|
+
# Asserts that _data_value_ is of valid type. Will yield to obtain origin of value in case an error is produced
|
83
94
|
#
|
84
95
|
# @param data_provider [DataProvider] The data provider that produced the hash
|
85
|
-
# @param data_value [Object] The data value
|
86
96
|
# @return [Object] The data value
|
87
|
-
def validate_data_value(
|
97
|
+
def validate_data_value(value, &block)
|
88
98
|
# The DataProvider.value_type is self recursive so further recursive check of collections is needed here
|
89
|
-
|
99
|
+
unless value_is_validated? || DataProvider.value_type.instance?(value)
|
100
|
+
actual_type = Types::TypeCalculator.singleton.infer(value)
|
101
|
+
raise Types::TypeAssertionError.new("#{yield} has wrong type, expects Puppet::LookupValue, got #{actual_type}", DataProvider.value_type, actual_type)
|
102
|
+
end
|
103
|
+
value
|
90
104
|
end
|
91
105
|
end
|
92
106
|
end
|
@@ -15,7 +15,7 @@ class EnvironmentDataProvider < ConfiguredDataProvider
|
|
15
15
|
config
|
16
16
|
else
|
17
17
|
if Puppet[:strict] == :error
|
18
|
-
|
18
|
+
config.fail(Issues::HIERA_VERSION_3_NOT_GLOBAL, :where => 'environment')
|
19
19
|
else
|
20
20
|
Puppet.warn_once(:hiera_v3_at_env_root, config.config_path, 'hiera.yaml version 3 found at the environment root was ignored')
|
21
21
|
end
|
@@ -10,6 +10,15 @@ class FunctionProvider
|
|
10
10
|
|
11
11
|
attr_reader :parent_data_provider, :function_name, :locations
|
12
12
|
|
13
|
+
# Returns the type that all the return type of all functions must be assignable to.
|
14
|
+
# For `lookup_key` and `data_dig`, that will be the `Puppet::LookupValue` type. For
|
15
|
+
# `data_hash` it will be a Hash[Puppet::LookupKey,Puppet::LookupValue]`
|
16
|
+
#
|
17
|
+
# @return [Type] the trusted return type
|
18
|
+
def self.trusted_return_type
|
19
|
+
DataProvider.value_type
|
20
|
+
end
|
21
|
+
|
13
22
|
def initialize(name, parent_data_provider, function_name, options, locations)
|
14
23
|
@name = name
|
15
24
|
@parent_data_provider = parent_data_provider
|
@@ -25,8 +34,7 @@ class FunctionProvider
|
|
25
34
|
end
|
26
35
|
|
27
36
|
def create_function_context(lookup_invocation)
|
28
|
-
scope
|
29
|
-
FunctionContext.new(EnvironmentContext.adapt(scope.compiler.environment), module_name, function(scope))
|
37
|
+
FunctionContext.new(EnvironmentContext.adapt(lookup_invocation.scope.compiler.environment), module_name, function(lookup_invocation))
|
30
38
|
end
|
31
39
|
|
32
40
|
def module_name
|
@@ -37,6 +45,10 @@ class FunctionProvider
|
|
37
45
|
"Hierarchy entry \"#{@name}\""
|
38
46
|
end
|
39
47
|
|
48
|
+
def full_name
|
49
|
+
"#{self.class::TAG} function '#{@function_name}'"
|
50
|
+
end
|
51
|
+
|
40
52
|
def to_s
|
41
53
|
name
|
42
54
|
end
|
@@ -46,9 +58,8 @@ class FunctionProvider
|
|
46
58
|
# @param [Pathname,URI] location The location to add to the options
|
47
59
|
# @return [Hash{String => Object}] The options hash
|
48
60
|
def options(location = nil)
|
61
|
+
location = location.location unless location.nil?
|
49
62
|
case location
|
50
|
-
when nil
|
51
|
-
@options
|
52
63
|
when Pathname
|
53
64
|
@options.merge(HieraConfig::KEY_PATH => location.to_s)
|
54
65
|
when URI
|
@@ -58,14 +69,18 @@ class FunctionProvider
|
|
58
69
|
end
|
59
70
|
end
|
60
71
|
|
72
|
+
def value_is_validated?
|
73
|
+
@value_is_validated
|
74
|
+
end
|
75
|
+
|
61
76
|
private
|
62
77
|
|
63
|
-
def function(
|
64
|
-
@function ||= load_function(
|
78
|
+
def function(lookup_invocation)
|
79
|
+
@function ||= load_function(lookup_invocation)
|
65
80
|
end
|
66
81
|
|
67
|
-
def load_function(
|
68
|
-
loaders = scope.compiler.loaders
|
82
|
+
def load_function(lookup_invocation)
|
83
|
+
loaders = lookup_invocation.scope.compiler.loaders
|
69
84
|
typed_name = Loader::TypedName.new(:function, @function_name)
|
70
85
|
loader = if typed_name.qualified?
|
71
86
|
qualifier = typed_name.name_parts[0]
|
@@ -75,10 +90,20 @@ class FunctionProvider
|
|
75
90
|
end
|
76
91
|
te = loader.load_typed(typed_name)
|
77
92
|
if te.nil? || te.value.nil?
|
78
|
-
|
79
|
-
|
93
|
+
@parent_data_provider.config(lookup_invocation).fail(Issues::HIERA_DATA_PROVIDER_FUNCTION_NOT_FOUND,
|
94
|
+
:function_type => self.class::TAG, :function_name => @function_name)
|
95
|
+
end
|
96
|
+
func = te.value
|
97
|
+
@value_is_validated = func.class.dispatcher.dispatchers.all? do |dispatcher|
|
98
|
+
rt = dispatcher.type.return_type
|
99
|
+
if rt.nil?
|
100
|
+
false
|
101
|
+
else
|
102
|
+
Types::TypeAsserter.assert_assignable(nil, self.class.trusted_return_type, rt) { "Return type of '#{self.class::TAG}' function named '#{function_name}'" }
|
103
|
+
true
|
104
|
+
end
|
80
105
|
end
|
81
|
-
|
106
|
+
func
|
82
107
|
end
|
83
108
|
end
|
84
109
|
end
|
@@ -15,11 +15,16 @@ class GlobalDataProvider < ConfiguredDataProvider
|
|
15
15
|
# Hiera version 3 needs access to special scope variables
|
16
16
|
scope = lookup_invocation.scope
|
17
17
|
unless scope.is_a?(Hiera::Scope)
|
18
|
-
|
18
|
+
hiera_invocation = Invocation.new(
|
19
19
|
Hiera::Scope.new(scope),
|
20
20
|
lookup_invocation.override_values,
|
21
21
|
lookup_invocation.default_values,
|
22
22
|
lookup_invocation.explainer)
|
23
|
+
|
24
|
+
# Confine to global scope unless an environment data provider has been defined (same as for hiera_xxx functions)
|
25
|
+
adapter = lookup_invocation.lookup_adapter
|
26
|
+
hiera_invocation.set_global_only unless adapter.global_only? || adapter.has_environment_data_provider?(lookup_invocation)
|
27
|
+
lookup_invocation = hiera_invocation
|
23
28
|
end
|
24
29
|
|
25
30
|
merge = MergeStrategy.strategy(merge)
|
@@ -32,9 +37,17 @@ class GlobalDataProvider < ConfiguredDataProvider
|
|
32
37
|
end
|
33
38
|
|
34
39
|
value = super(key, lookup_invocation, merge)
|
35
|
-
if lookup_invocation.hiera_xxx_call?
|
36
|
-
|
37
|
-
|
40
|
+
if lookup_invocation.hiera_xxx_call?
|
41
|
+
if merge.is_a?(HashMergeStrategy) || merge.is_a?(DeepMergeStrategy)
|
42
|
+
# hiera_hash calls should error when found values are not hashes
|
43
|
+
Types::TypeAsserter.assert_instance_of('value', Types::PHashType::DEFAULT, value)
|
44
|
+
end
|
45
|
+
if !key.segments.nil? && (merge.is_a?(HashMergeStrategy) || merge.is_a?(UniqueMergeStrategy))
|
46
|
+
strategy = merge.is_a?(HashMergeStrategy) ? 'hash' : 'array'
|
47
|
+
|
48
|
+
# Fail with old familiar message from Hiera 3
|
49
|
+
raise Puppet::DataBinding::LookupError, "Resolution type :#{strategy} is illegal when accessing values using dotted keys. Offending key was '#{key}'"
|
50
|
+
end
|
38
51
|
end
|
39
52
|
value
|
40
53
|
else
|
@@ -45,7 +58,7 @@ class GlobalDataProvider < ConfiguredDataProvider
|
|
45
58
|
protected
|
46
59
|
|
47
60
|
def assert_config_version(config)
|
48
|
-
|
61
|
+
config.fail(Issues::HIERA_UNSUPPORTED_VERSION_IN_GLOBAL) if config.version == 4
|
49
62
|
config
|
50
63
|
end
|
51
64
|
|
@@ -22,6 +22,16 @@ class ScopeLookupCollectingInvocation < Invocation
|
|
22
22
|
@scope_interpolations.uniq! { |si| si[0] }
|
23
23
|
@scope_interpolations
|
24
24
|
end
|
25
|
+
|
26
|
+
# Yield invocation that remembers all but the given name
|
27
|
+
def with_local_memory_eluding(name)
|
28
|
+
save_si = @scope_interpolations
|
29
|
+
@scope_interpolations = []
|
30
|
+
result = yield
|
31
|
+
save_si.concat(@scope_interpolations.reject { |entry| entry[1] == name })
|
32
|
+
@scope_interpolations = save_si
|
33
|
+
result
|
34
|
+
end
|
25
35
|
end
|
26
36
|
|
27
37
|
# @api private
|
@@ -34,11 +44,13 @@ class HieraConfig
|
|
34
44
|
KEY_NAME = 'name'.freeze
|
35
45
|
KEY_VERSION = 'version'.freeze
|
36
46
|
KEY_DATADIR = 'datadir'.freeze
|
47
|
+
KEY_DEFAULT_HIERARCHY = 'default_hierarchy'.freeze
|
37
48
|
KEY_HIERARCHY = 'hierarchy'.freeze
|
38
49
|
KEY_LOGGER = 'logger'.freeze
|
39
50
|
KEY_OPTIONS = 'options'.freeze
|
40
51
|
KEY_PATH = 'path'.freeze
|
41
52
|
KEY_PATHS = 'paths'.freeze
|
53
|
+
KEY_MAPPED_PATHS = 'mapped_paths'.freeze
|
42
54
|
KEY_GLOB = 'glob'.freeze
|
43
55
|
KEY_GLOBS = 'globs'.freeze
|
44
56
|
KEY_URI = 'uri'.freeze
|
@@ -56,7 +68,7 @@ class HieraConfig
|
|
56
68
|
|
57
69
|
FUNCTION_KEYS = [KEY_DATA_HASH, KEY_LOOKUP_KEY, KEY_DATA_DIG, KEY_V3_BACKEND]
|
58
70
|
ALL_FUNCTION_KEYS = FUNCTION_KEYS + [KEY_V4_DATA_HASH]
|
59
|
-
LOCATION_KEYS = [KEY_PATH, KEY_PATHS, KEY_GLOB, KEY_GLOBS, KEY_URI, KEY_URIS]
|
71
|
+
LOCATION_KEYS = [KEY_PATH, KEY_PATHS, KEY_GLOB, KEY_GLOBS, KEY_URI, KEY_URIS, KEY_MAPPED_PATHS]
|
60
72
|
FUNCTION_PROVIDERS = {
|
61
73
|
KEY_DATA_HASH => DataHashFunctionProvider,
|
62
74
|
KEY_DATA_DIG => DataDigFunctionProvider,
|
@@ -67,7 +79,7 @@ class HieraConfig
|
|
67
79
|
KEY_V4_DATA_HASH => V4DataHashFunctionProvider
|
68
80
|
}
|
69
81
|
|
70
|
-
def self.v4_function_config(config_root, function_name)
|
82
|
+
def self.v4_function_config(config_root, function_name, owner)
|
71
83
|
unless Puppet[:strict] == :off
|
72
84
|
Puppet.warn_once(:deprecation, 'legacy_provider_function',
|
73
85
|
"Using of legacy data provider function '#{function_name}'. Please convert to a 'data_hash' function")
|
@@ -81,7 +93,8 @@ class HieraConfig
|
|
81
93
|
KEY_V4_DATA_HASH => function_name
|
82
94
|
}
|
83
95
|
]
|
84
|
-
}.freeze
|
96
|
+
}.freeze,
|
97
|
+
owner
|
85
98
|
)
|
86
99
|
end
|
87
100
|
|
@@ -106,8 +119,9 @@ class HieraConfig
|
|
106
119
|
#
|
107
120
|
# @param lookup_invocation [Invocation] Invocation data containing scope, overrides, and defaults
|
108
121
|
# @param config_path [Pathname] Absolute path to the configuration file
|
122
|
+
# @param owner [ConfiguredDataProvider] The data provider that will own the created configuration
|
109
123
|
# @return [LookupConfiguration] the configuration
|
110
|
-
def self.create(lookup_invocation, config_path)
|
124
|
+
def self.create(lookup_invocation, config_path, owner)
|
111
125
|
if config_path.is_a?(Hash)
|
112
126
|
config_path = nil
|
113
127
|
loaded_config = config_path
|
@@ -137,13 +151,15 @@ class HieraConfig
|
|
137
151
|
version = version.nil? ? 3 : version.to_i
|
138
152
|
case version
|
139
153
|
when 5
|
140
|
-
HieraConfigV5.new(config_root, config_path, loaded_config)
|
154
|
+
HieraConfigV5.new(config_root, config_path, loaded_config, owner)
|
141
155
|
when 4
|
142
|
-
HieraConfigV4.new(config_root, config_path, loaded_config)
|
156
|
+
HieraConfigV4.new(config_root, config_path, loaded_config, owner)
|
143
157
|
when 3
|
144
|
-
HieraConfigV3.new(config_root, config_path, loaded_config)
|
158
|
+
HieraConfigV3.new(config_root, config_path, loaded_config, owner)
|
145
159
|
else
|
146
|
-
|
160
|
+
issue = Issues::HIERA_UNSUPPORTED_VERSION
|
161
|
+
raise Puppet::DataBinding::LookupError.new(
|
162
|
+
issue.format(:version => version), config_path, nil, nil, nil, issue.issue_code)
|
147
163
|
end
|
148
164
|
end
|
149
165
|
|
@@ -154,29 +170,76 @@ class HieraConfig
|
|
154
170
|
#
|
155
171
|
# @param config_path [Pathname] Absolute path to the configuration
|
156
172
|
# @param loaded_config [Hash] the loaded configuration
|
157
|
-
def initialize(config_root, config_path, loaded_config)
|
173
|
+
def initialize(config_root, config_path, loaded_config, owner)
|
158
174
|
@config_root = config_root
|
159
175
|
@config_path = config_path
|
160
176
|
@loaded_config = loaded_config
|
161
|
-
@config = validate_config(self.class.symkeys_to_string(@loaded_config))
|
177
|
+
@config = validate_config(self.class.symkeys_to_string(@loaded_config), owner)
|
162
178
|
@data_providers = nil
|
163
179
|
end
|
164
180
|
|
181
|
+
def fail(issue, args = EMPTY_HASH, line = nil)
|
182
|
+
raise Puppet::DataBinding::LookupError.new(
|
183
|
+
issue.format(args.merge(:label => self)), @config_path, line, nil, nil, issue.issue_code)
|
184
|
+
end
|
185
|
+
|
186
|
+
def has_default_hierarchy?
|
187
|
+
false
|
188
|
+
end
|
189
|
+
|
165
190
|
# Returns the data providers for this config
|
166
191
|
#
|
167
192
|
# @param lookup_invocation [Invocation] Invocation data containing scope, overrides, and defaults
|
168
193
|
# @param parent_data_provider [DataProvider] The data provider that loaded this configuration
|
169
194
|
# @return [Array<DataProvider>] the data providers
|
170
|
-
def configured_data_providers(lookup_invocation, parent_data_provider)
|
195
|
+
def configured_data_providers(lookup_invocation, parent_data_provider, use_default_hierarchy = false)
|
171
196
|
unless @data_providers && scope_interpolations_stable?(lookup_invocation)
|
172
197
|
if @data_providers
|
173
198
|
lookup_invocation.report_text { 'Hiera configuration recreated due to change of scope variables used in interpolation expressions' }
|
174
199
|
end
|
175
200
|
slc_invocation = ScopeLookupCollectingInvocation.new(lookup_invocation.scope)
|
176
|
-
|
201
|
+
begin
|
202
|
+
@data_providers = create_configured_data_providers(slc_invocation, parent_data_provider, false)
|
203
|
+
if has_default_hierarchy?
|
204
|
+
@default_data_providers = create_configured_data_providers(slc_invocation, parent_data_provider, true)
|
205
|
+
end
|
206
|
+
rescue StandardError => e
|
207
|
+
# Raise a LookupError with a RUNTIME_ERROR issue to prevent this being translated to an evaluation error triggered in the pp file
|
208
|
+
# where the lookup started
|
209
|
+
if e.message =~ /^Undefined variable '([^']+)'/
|
210
|
+
var = $1
|
211
|
+
fail(Issues::HIERA_UNDEFINED_VARIABLE, { :name => var }, find_line_matching(/%\{['"]?#{var}['"]?}/))
|
212
|
+
end
|
213
|
+
raise e
|
214
|
+
end
|
177
215
|
@scope_interpolations = slc_invocation.scope_interpolations
|
178
216
|
end
|
179
|
-
@data_providers
|
217
|
+
use_default_hierarchy ? @default_data_providers : @data_providers
|
218
|
+
end
|
219
|
+
|
220
|
+
# Find first line in configuration that matches regexp after given line. Comments are stripped
|
221
|
+
def find_line_matching(regexp, start_line = 1)
|
222
|
+
line_number = 0
|
223
|
+
File.foreach(@config_path) do |line|
|
224
|
+
line_number += 1
|
225
|
+
next if line_number < start_line
|
226
|
+
quote = nil
|
227
|
+
stripped = ''
|
228
|
+
line.each_codepoint do |cp|
|
229
|
+
if cp == 0x22 || cp == 0x27 # double or single quote
|
230
|
+
if quote == cp
|
231
|
+
quote = nil
|
232
|
+
elsif quote.nil?
|
233
|
+
quote = cp
|
234
|
+
end
|
235
|
+
elsif cp == 0x23 # unquoted hash mark
|
236
|
+
break
|
237
|
+
end
|
238
|
+
stripped << cp
|
239
|
+
end
|
240
|
+
return line_number if stripped =~ regexp
|
241
|
+
end
|
242
|
+
nil
|
180
243
|
end
|
181
244
|
|
182
245
|
def scope_interpolations_stable?(lookup_invocation)
|
@@ -188,7 +251,7 @@ class HieraConfig
|
|
188
251
|
@scope_interpolations.all? do |key, root_key, segments, old_value|
|
189
252
|
value = scope[root_key]
|
190
253
|
unless value.nil? || segments.empty?
|
191
|
-
found =
|
254
|
+
found = nil;
|
192
255
|
catch(:no_such_key) { found = sub_lookup(key, lookup_invocation, segments, value) }
|
193
256
|
value = found;
|
194
257
|
end
|
@@ -199,11 +262,11 @@ class HieraConfig
|
|
199
262
|
end
|
200
263
|
|
201
264
|
# @api private
|
202
|
-
def create_configured_data_providers(lookup_invocation, parent_data_provider)
|
265
|
+
def create_configured_data_providers(lookup_invocation, parent_data_provider, use_default_hierarchy)
|
203
266
|
self.class.not_implemented(self, 'create_configured_data_providers')
|
204
267
|
end
|
205
268
|
|
206
|
-
def validate_config(config)
|
269
|
+
def validate_config(config, owner)
|
207
270
|
self.class.not_implemented(self, 'validate_config')
|
208
271
|
end
|
209
272
|
|
@@ -298,7 +361,7 @@ class HieraConfigV3 < HieraConfig
|
|
298
361
|
}
|
299
362
|
end
|
300
363
|
|
301
|
-
def create_configured_data_providers(lookup_invocation, parent_data_provider)
|
364
|
+
def create_configured_data_providers(lookup_invocation, parent_data_provider, _)
|
302
365
|
scope = lookup_invocation.scope
|
303
366
|
unless scope.is_a?(Hiera::Scope)
|
304
367
|
lookup_invocation = Invocation.new(
|
@@ -312,7 +375,15 @@ class HieraConfigV3 < HieraConfig
|
|
312
375
|
data_providers = {}
|
313
376
|
|
314
377
|
[@config[KEY_BACKENDS]].flatten.each do |backend|
|
315
|
-
|
378
|
+
if data_providers.include?(backend)
|
379
|
+
first_line = find_line_matching(/[^\w]#{backend}(?:[^\w]|$)/)
|
380
|
+
line = find_line_matching(/[^\w]#{backend}(?:[^\w]|$)/, first_line + 1) if first_line
|
381
|
+
unless line
|
382
|
+
line = first_line
|
383
|
+
first_line = nil
|
384
|
+
end
|
385
|
+
fail(Issues::HIERA_BACKEND_MULTIPLY_DEFINED, { :name => backend, :first_line => first_line }, line)
|
386
|
+
end
|
316
387
|
original_paths = [@config[KEY_HIERARCHY]].flatten
|
317
388
|
backend_config = @config[backend]
|
318
389
|
if backend_config.nil?
|
@@ -348,7 +419,7 @@ class HieraConfigV3 < HieraConfig
|
|
348
419
|
KEY_MERGE_BEHAVIOR => 'native'
|
349
420
|
}
|
350
421
|
|
351
|
-
def validate_config(config)
|
422
|
+
def validate_config(config, owner)
|
352
423
|
unless Puppet[:strict] == :off
|
353
424
|
Puppet.warn_once(:deprecation, 'hiera.yaml',
|
354
425
|
"#{@config_path}: Use of 'hiera.yaml' version 3 is deprecated. It should be converted to version 5", config_path.to_s)
|
@@ -423,7 +494,9 @@ class HieraConfigV4 < HieraConfig
|
|
423
494
|
def factory_create_data_provider(lookup_invocation, name, parent_data_provider, provider_name, datadir, original_paths)
|
424
495
|
service_type = Registry.hash_of_path_based_data_provider_factories
|
425
496
|
provider_factory = Puppet.lookup(:injector).lookup(nil, service_type, PATH_BASED_DATA_PROVIDER_FACTORIES_KEY)[provider_name]
|
426
|
-
|
497
|
+
unless provider_factory
|
498
|
+
fail(Issues::HIERA_NO_PROVIDER_FOR_BACKEND, { :name => provider_name }, find_line_matching(/[^\w]#{provider_name}(?:[^\w]|$)/))
|
499
|
+
end
|
427
500
|
|
428
501
|
paths = original_paths.map { |path| interpolate(path, lookup_invocation, false) }
|
429
502
|
paths = provider_factory.resolve_paths(datadir, original_paths, paths, lookup_invocation)
|
@@ -437,13 +510,21 @@ class HieraConfigV4 < HieraConfig
|
|
437
510
|
end
|
438
511
|
end
|
439
512
|
|
440
|
-
def create_configured_data_providers(lookup_invocation, parent_data_provider)
|
513
|
+
def create_configured_data_providers(lookup_invocation, parent_data_provider, _)
|
441
514
|
default_datadir = @config[KEY_DATADIR]
|
442
515
|
data_providers = {}
|
443
516
|
|
444
517
|
@config[KEY_HIERARCHY].each do |he|
|
445
518
|
name = he[KEY_NAME]
|
446
|
-
|
519
|
+
if data_providers.include?(name)
|
520
|
+
first_line = find_line_matching(/\s+name:\s+['"]?#{name}(?:[^\w]|$)/)
|
521
|
+
line = find_line_matching(/\s+name:\s+['"]?#{name}(?:[^\w]|$)/, first_line + 1) if first_line
|
522
|
+
unless line
|
523
|
+
line = first_line
|
524
|
+
first_line = nil
|
525
|
+
end
|
526
|
+
fail(Issues::HIERA_HIERARCHY_NAME_MULTIPLY_DEFINED, { :name => name, :first_line => first_line }, line)
|
527
|
+
end
|
447
528
|
original_paths = he[KEY_PATHS] || [he[KEY_PATH] || name]
|
448
529
|
datadir = @config_root + (he[KEY_DATADIR] || default_datadir)
|
449
530
|
provider_name = he[KEY_BACKEND]
|
@@ -461,7 +542,7 @@ class HieraConfigV4 < HieraConfig
|
|
461
542
|
data_providers.values
|
462
543
|
end
|
463
544
|
|
464
|
-
def validate_config(config)
|
545
|
+
def validate_config(config, owner)
|
465
546
|
unless Puppet[:strict] == :off
|
466
547
|
Puppet.warn_once(:deprecation, 'hiera.yaml',
|
467
548
|
"#{@config_path}: Use of 'hiera.yaml' version 4 is deprecated. It should be converted to version 5", config_path.to_s)
|
@@ -489,6 +570,25 @@ class HieraConfigV5 < HieraConfig
|
|
489
570
|
# The option name must start with a letter and end with a letter or digit. May contain underscore and dash.
|
490
571
|
option_name_t = tf.pattern(/\A[A-Za-z](:?[0-9A-Za-z_-]*[0-9A-Za-z])?\z/)
|
491
572
|
|
573
|
+
hierarchy_t = tf.array_of(tf.struct(
|
574
|
+
{
|
575
|
+
KEY_NAME => nes_t,
|
576
|
+
tf.optional(KEY_OPTIONS) => tf.hash_kv(option_name_t, tf.data),
|
577
|
+
tf.optional(KEY_DATA_HASH) => nes_t,
|
578
|
+
tf.optional(KEY_LOOKUP_KEY) => nes_t,
|
579
|
+
tf.optional(KEY_V3_BACKEND) => nes_t,
|
580
|
+
tf.optional(KEY_V4_DATA_HASH) => nes_t,
|
581
|
+
tf.optional(KEY_DATA_DIG) => nes_t,
|
582
|
+
tf.optional(KEY_PATH) => nes_t,
|
583
|
+
tf.optional(KEY_PATHS) => tf.array_of(nes_t, tf.range(1, :default)),
|
584
|
+
tf.optional(KEY_GLOB) => nes_t,
|
585
|
+
tf.optional(KEY_GLOBS) => tf.array_of(nes_t, tf.range(1, :default)),
|
586
|
+
tf.optional(KEY_URI) => uri_t,
|
587
|
+
tf.optional(KEY_URIS) => tf.array_of(uri_t, tf.range(1, :default)),
|
588
|
+
tf.optional(KEY_MAPPED_PATHS) => tf.array_of(nes_t, tf.range(3, 3)),
|
589
|
+
tf.optional(KEY_DATADIR) => nes_t
|
590
|
+
}))
|
591
|
+
|
492
592
|
@@CONFIG_TYPE = tf.struct({
|
493
593
|
KEY_VERSION => tf.range(5, 5),
|
494
594
|
tf.optional(KEY_DEFAULTS) => tf.struct(
|
@@ -496,38 +596,41 @@ class HieraConfigV5 < HieraConfig
|
|
496
596
|
tf.optional(KEY_DATA_HASH) => nes_t,
|
497
597
|
tf.optional(KEY_LOOKUP_KEY) => nes_t,
|
498
598
|
tf.optional(KEY_DATA_DIG) => nes_t,
|
499
|
-
tf.optional(KEY_DATADIR) => nes_t
|
500
|
-
}),
|
501
|
-
tf.optional(KEY_HIERARCHY) => tf.array_of(tf.struct(
|
502
|
-
{
|
503
|
-
KEY_NAME => nes_t,
|
599
|
+
tf.optional(KEY_DATADIR) => nes_t,
|
504
600
|
tf.optional(KEY_OPTIONS) => tf.hash_kv(option_name_t, tf.data),
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
tf.optional(KEY_V4_DATA_HASH) => nes_t,
|
509
|
-
tf.optional(KEY_DATA_DIG) => nes_t,
|
510
|
-
tf.optional(KEY_PATH) => nes_t,
|
511
|
-
tf.optional(KEY_PATHS) => tf.array_of(nes_t, tf.range(1, :default)),
|
512
|
-
tf.optional(KEY_GLOB) => nes_t,
|
513
|
-
tf.optional(KEY_GLOBS) => tf.array_of(nes_t, tf.range(1, :default)),
|
514
|
-
tf.optional(KEY_URI) => uri_t,
|
515
|
-
tf.optional(KEY_URIS) => tf.array_of(uri_t, tf.range(1, :default)),
|
516
|
-
tf.optional(KEY_DATADIR) => nes_t
|
517
|
-
}))
|
601
|
+
}),
|
602
|
+
tf.optional(KEY_HIERARCHY) => hierarchy_t,
|
603
|
+
tf.optional(KEY_DEFAULT_HIERARCHY) => hierarchy_t
|
518
604
|
})
|
519
605
|
end
|
520
606
|
|
521
|
-
def create_configured_data_providers(lookup_invocation, parent_data_provider)
|
607
|
+
def create_configured_data_providers(lookup_invocation, parent_data_provider, use_default_hierarchy)
|
522
608
|
defaults = @config[KEY_DEFAULTS] || EMPTY_HASH
|
523
609
|
datadir = defaults[KEY_DATADIR] || 'data'
|
524
610
|
|
525
611
|
# Hashes enumerate their values in the order that the corresponding keys were inserted so it's safe to use
|
526
612
|
# a hash for the data_providers.
|
527
613
|
data_providers = {}
|
528
|
-
|
614
|
+
|
615
|
+
if @config.include?(KEY_DEFAULT_HIERARCHY)
|
616
|
+
unless parent_data_provider.is_a?(ModuleDataProvider)
|
617
|
+
fail(Issues::HIERA_DEFAULT_HIERARCHY_NOT_IN_MODULE, EMPTY_HASH, find_line_matching(/\s+default_hierarchy:/))
|
618
|
+
end
|
619
|
+
elsif use_default_hierarchy
|
620
|
+
return data_providers
|
621
|
+
end
|
622
|
+
|
623
|
+
@config[use_default_hierarchy ? KEY_DEFAULT_HIERARCHY : KEY_HIERARCHY].each do |he|
|
529
624
|
name = he[KEY_NAME]
|
530
|
-
|
625
|
+
if data_providers.include?(name)
|
626
|
+
first_line = find_line_matching(/\s+name:\s+['"]?#{name}(?:[^\w]|$)/)
|
627
|
+
line = find_line_matching(/\s+name:\s+['"]?#{name}(?:[^\w]|$)/, first_line + 1) if first_line
|
628
|
+
unless line
|
629
|
+
line = first_line
|
630
|
+
first_line = nil
|
631
|
+
end
|
632
|
+
fail(Issues::HIERA_HIERARCHY_NAME_MULTIPLY_DEFINED, { :name => name, :first_line => first_line }, line)
|
633
|
+
end
|
531
634
|
function_kind = ALL_FUNCTION_KEYS.find { |key| he.include?(key) }
|
532
635
|
if function_kind.nil?
|
533
636
|
function_kind = FUNCTION_KEYS.find { |key| defaults.include?(key) }
|
@@ -552,22 +655,15 @@ class HieraConfigV5 < HieraConfig
|
|
552
655
|
expand_uris(he[location_key], lookup_invocation)
|
553
656
|
when KEY_URI
|
554
657
|
expand_uris([he[location_key]], lookup_invocation)
|
658
|
+
when KEY_MAPPED_PATHS
|
659
|
+
expand_mapped_paths(entry_datadir, he[location_key], lookup_invocation)
|
555
660
|
else
|
556
661
|
nil
|
557
662
|
end
|
558
663
|
next if @config_path.nil? && !locations.nil? && locations.empty? # Default config and no existing paths found
|
559
|
-
options = he[KEY_OPTIONS]
|
664
|
+
options = he[KEY_OPTIONS] || defaults[KEY_OPTIONS]
|
560
665
|
options = options.nil? ? EMPTY_HASH : interpolate(options, lookup_invocation, false)
|
561
666
|
if(function_kind == KEY_V3_BACKEND)
|
562
|
-
unless parent_data_provider.is_a?(GlobalDataProvider)
|
563
|
-
# hiera3_backend is not allowed in environments and modules
|
564
|
-
raise Puppet::DataBinding::LookupError, "#{@config_path}: '#{KEY_V3_BACKEND}' is only allowed in the global layer"
|
565
|
-
end
|
566
|
-
|
567
|
-
if function_name == 'json' || function_name == 'yaml' || function_name == 'hocon' && Puppet.features.hocon?
|
568
|
-
# Disallow use of backends that have corresponding "data_hash" functions in version 5
|
569
|
-
raise Puppet::DataBinding::LookupError, "#{@config_path}: Use \"#{KEY_DATA_HASH}: #{function_name}_data\" instead of \"#{KEY_V3_BACKEND}: #{function_name}\""
|
570
|
-
end
|
571
667
|
v3options = { :datadir => entry_datadir.to_s }
|
572
668
|
options.each_pair { |k, v| v3options[k.to_sym] = v }
|
573
669
|
data_providers[name] = create_hiera3_backend_provider(name, function_name, parent_data_provider, entry_datadir, locations, {
|
@@ -587,6 +683,10 @@ class HieraConfigV5 < HieraConfig
|
|
587
683
|
data_providers.values
|
588
684
|
end
|
589
685
|
|
686
|
+
def has_default_hierarchy?
|
687
|
+
@config.include?(KEY_DEFAULT_HIERARCHY)
|
688
|
+
end
|
689
|
+
|
590
690
|
RESERVED_OPTION_KEYS = ['path', 'uri'].freeze
|
591
691
|
|
592
692
|
DEFAULT_CONFIG_HASH = {
|
@@ -603,46 +703,59 @@ class HieraConfigV5 < HieraConfig
|
|
603
703
|
]
|
604
704
|
}.freeze
|
605
705
|
|
606
|
-
def validate_config(config)
|
706
|
+
def validate_config(config, owner)
|
607
707
|
config[KEY_DEFAULTS] ||= DEFAULT_CONFIG_HASH[KEY_DEFAULTS]
|
608
708
|
config[KEY_HIERARCHY] ||= DEFAULT_CONFIG_HASH[KEY_HIERARCHY]
|
609
709
|
|
610
710
|
Types::TypeAsserter.assert_instance_of(["The Lookup Configuration at '%s'", @config_path], self.class.config_type, config)
|
611
711
|
defaults = config[KEY_DEFAULTS]
|
612
712
|
validate_defaults(defaults) unless defaults.nil?
|
613
|
-
config[KEY_HIERARCHY].each
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
713
|
+
config[KEY_HIERARCHY].each { |he| validate_hierarchy(he, defaults, owner) }
|
714
|
+
|
715
|
+
if config.include?(KEY_DEFAULT_HIERARCHY)
|
716
|
+
unless owner.is_a?(ModuleDataProvider)
|
717
|
+
fail(Issues::HIERA_DEFAULT_HIERARCHY_NOT_IN_MODULE, EMPTY_HASH, find_line_matching(/(?:^|\s+)#{KEY_DEFAULT_HIERARCHY}:/))
|
718
|
+
end
|
719
|
+
config[KEY_DEFAULT_HIERARCHY].each { |he| validate_hierarchy(he, defaults, owner) }
|
720
|
+
end
|
721
|
+
config
|
722
|
+
end
|
723
|
+
|
724
|
+
def validate_hierarchy(he, defaults, owner)
|
725
|
+
name = he[KEY_NAME]
|
726
|
+
case ALL_FUNCTION_KEYS.count { |key| he.include?(key) }
|
727
|
+
when 0
|
728
|
+
if defaults.nil? || FUNCTION_KEYS.count { |key| defaults.include?(key) } == 0
|
729
|
+
fail(Issues::HIERA_MISSING_DATA_PROVIDER_FUNCTION, :name => name)
|
629
730
|
end
|
731
|
+
when 1
|
732
|
+
# OK
|
733
|
+
else
|
734
|
+
fail(Issues::HIERA_MULTIPLE_DATA_PROVIDER_FUNCTIONS, :name => name)
|
735
|
+
end
|
630
736
|
|
631
|
-
|
632
|
-
|
633
|
-
|
737
|
+
v3_backend = he[KEY_V3_BACKEND]
|
738
|
+
unless v3_backend.nil?
|
739
|
+
unless owner.is_a?(GlobalDataProvider)
|
740
|
+
fail(Issues::HIERA_V3_BACKEND_NOT_GLOBAL, EMPTY_HASH, find_line_matching(/\s+#{KEY_V3_BACKEND}:/))
|
634
741
|
end
|
742
|
+
if v3_backend == 'json' || v3_backend == 'yaml' || v3_backend == 'hocon' && Puppet.features.hocon?
|
743
|
+
# Disallow use of backends that have corresponding "data_hash" functions in version 5
|
744
|
+
fail(Issues::HIERA_V3_BACKEND_REPLACED_BY_DATA_HASH, { :function_name => v3_backend },
|
745
|
+
find_line_matching(/\s+#{KEY_V3_BACKEND}:\s*['"]?#{v3_backend}(?:[^\w]|$)/))
|
746
|
+
end
|
747
|
+
end
|
635
748
|
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
749
|
+
if LOCATION_KEYS.count { |key| he.include?(key) } > 1
|
750
|
+
fail(Issues::HIERA_MULTIPLE_LOCATION_SPECS, :name => name)
|
751
|
+
end
|
752
|
+
|
753
|
+
options = he[KEY_OPTIONS]
|
754
|
+
unless options.nil?
|
755
|
+
RESERVED_OPTION_KEYS.each do |key|
|
756
|
+
fail(Issues::HIERA_OPTION_RESERVED_BY_PUPPET, :key => key, :name => name) if options.include?(key)
|
643
757
|
end
|
644
758
|
end
|
645
|
-
config
|
646
759
|
end
|
647
760
|
|
648
761
|
def validate_defaults(defaults)
|
@@ -650,8 +763,14 @@ class HieraConfigV5 < HieraConfig
|
|
650
763
|
when 0, 1
|
651
764
|
# OK
|
652
765
|
else
|
653
|
-
|
654
|
-
|
766
|
+
fail(Issues::HIERA_MULTIPLE_DATA_PROVIDER_FUNCTIONS_IN_DEFAULT)
|
767
|
+
end
|
768
|
+
|
769
|
+
options = defaults[KEY_OPTIONS]
|
770
|
+
unless options.nil?
|
771
|
+
RESERVED_OPTION_KEYS.each do |key|
|
772
|
+
fail(Issues::HIERA_DEFAULT_OPTION_RESERVED_BY_PUPPET, :key => key) if options.include?(key)
|
773
|
+
end
|
655
774
|
end
|
656
775
|
end
|
657
776
|
|