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
@@ -97,4 +97,11 @@ class Puppet::Pops::Evaluator::CallableSignature
|
|
97
97
|
def infinity?(x)
|
98
98
|
x == Float::INFINITY
|
99
99
|
end
|
100
|
+
|
101
|
+
# @return [Boolean] true if this signature represents an argument mismatch, false otherwise
|
102
|
+
#
|
103
|
+
# @api private
|
104
|
+
def argument_mismatch_handler?
|
105
|
+
false
|
106
|
+
end
|
100
107
|
end
|
@@ -21,15 +21,24 @@ class Dispatch < Evaluator::CallableSignature
|
|
21
21
|
# @api public
|
22
22
|
attr_reader :block_name
|
23
23
|
|
24
|
+
# @param type [Puppet::Pops::Types::PArrayType, Puppet::Pops::Types::PTupleType] - type describing signature
|
25
|
+
# @param method_name [String] the name of the method that will be called when type matches given arguments
|
26
|
+
# @param param_names [Array<String>] names matching the number of parameters specified by type (or empty array)
|
27
|
+
# @param block_name [String,nil] name of block parameter, no nil
|
28
|
+
# @param injections [Array<Array>] injection data for weaved parameters
|
29
|
+
# @param weaving [Array<Integer,Array>] weaving knits
|
30
|
+
# @param last_captures [Boolean] true if last parameter is captures rest
|
31
|
+
# @param argument_mismatch_handler [Boolean] true if this is a dispatch for an argument mismatch
|
24
32
|
# @api private
|
25
|
-
def initialize(type, method_name, param_names, block_name, injections, weaving,
|
33
|
+
def initialize(type, method_name, param_names, last_captures = false, block_name = nil, injections = EMPTY_ARRAY, weaving = EMPTY_ARRAY, argument_mismatch_handler = false)
|
26
34
|
@type = type
|
27
35
|
@method_name = method_name
|
28
|
-
@param_names = param_names
|
36
|
+
@param_names = param_names
|
37
|
+
@last_captures = last_captures
|
29
38
|
@block_name = block_name
|
30
|
-
@injections = injections
|
39
|
+
@injections = injections
|
31
40
|
@weaving = weaving
|
32
|
-
@
|
41
|
+
@argument_mismatch_handler = argument_mismatch_handler
|
33
42
|
end
|
34
43
|
|
35
44
|
# @api private
|
@@ -39,7 +48,11 @@ class Dispatch < Evaluator::CallableSignature
|
|
39
48
|
|
40
49
|
# @api private
|
41
50
|
def last_captures_rest?
|
42
|
-
|
51
|
+
@last_captures
|
52
|
+
end
|
53
|
+
|
54
|
+
def argument_mismatch_handler?
|
55
|
+
@argument_mismatch_handler
|
43
56
|
end
|
44
57
|
|
45
58
|
# @api private
|
@@ -31,7 +31,12 @@ class Puppet::Pops::Functions::Dispatcher
|
|
31
31
|
found = @dispatchers.find { |d| d.type.callable_with?(args, block) }
|
32
32
|
unless found
|
33
33
|
args_type = Puppet::Pops::Types::TypeCalculator.singleton.infer_set(block_given? ? args + [block] : args)
|
34
|
-
raise ArgumentError, Puppet::Pops::Types::TypeMismatchDescriber.describe_signatures(instance.class.name,
|
34
|
+
raise ArgumentError, Puppet::Pops::Types::TypeMismatchDescriber.describe_signatures(instance.class.name, signatures, args_type)
|
35
|
+
end
|
36
|
+
|
37
|
+
if found.argument_mismatch_handler?
|
38
|
+
msg = found.invoke(instance, calling_scope, args)
|
39
|
+
raise ArgumentError, "'#{instance.class.name}' #{msg}"
|
35
40
|
end
|
36
41
|
|
37
42
|
catch(:next) do
|
@@ -39,17 +44,6 @@ class Puppet::Pops::Functions::Dispatcher
|
|
39
44
|
end
|
40
45
|
end
|
41
46
|
|
42
|
-
# Adds a regular dispatch for one method name
|
43
|
-
#
|
44
|
-
# @param type [Puppet::Pops::Types::PArrayType, Puppet::Pops::Types::PTupleType] - type describing signature
|
45
|
-
# @param method_name [String] - the name of the method that will be called when type matches given arguments
|
46
|
-
# @param names [Array<String>] - array with names matching the number of parameters specified by type (or empty array)
|
47
|
-
#
|
48
|
-
# @api private
|
49
|
-
def add_dispatch(type, method_name, param_names, block_name, injections, weaving, last_captures)
|
50
|
-
add(Puppet::Pops::Functions::Dispatch.new(type, method_name, param_names, block_name, injections, weaving, last_captures))
|
51
|
-
end
|
52
|
-
|
53
47
|
# Adds a dispatch directly to the set of dispatchers.
|
54
48
|
# @api private
|
55
49
|
def add(a_dispatch)
|
@@ -72,6 +66,6 @@ class Puppet::Pops::Functions::Dispatcher
|
|
72
66
|
|
73
67
|
# @api private
|
74
68
|
def signatures
|
75
|
-
@dispatchers
|
69
|
+
@dispatchers.reject { |dispatcher| dispatcher.argument_mismatch_handler? }
|
76
70
|
end
|
77
71
|
end
|
@@ -69,7 +69,7 @@ class IssueReporter
|
|
69
69
|
break if emitted >= max_errors
|
70
70
|
end
|
71
71
|
warnings_message = (emit_warnings && warnings.size > 0) ? ", and #{warnings.size} warnings" : ""
|
72
|
-
giving_up_message = "
|
72
|
+
giving_up_message = "Language validation logged #{errors.size} errors#{warnings_message}. Giving up"
|
73
73
|
exception = emit_exception.new(giving_up_message)
|
74
74
|
exception.file = errors[0].file
|
75
75
|
raise exception
|
data/lib/puppet/pops/issues.rb
CHANGED
@@ -738,5 +738,89 @@ module Issues
|
|
738
738
|
ILLEGAL_BOM = hard_issue :ILLEGAL_BOM, :format_name, :bytes do
|
739
739
|
"Illegal #{format_name} Byte Order mark at beginning of input: #{bytes} - remove these from the puppet source"
|
740
740
|
end
|
741
|
+
|
742
|
+
HIERA_UNSUPPORTED_VERSION = hard_issue :HIERA_UNSUPPORTED_VERSION, :version do
|
743
|
+
"This runtime does not support hiera.yaml version #{version}"
|
744
|
+
end
|
745
|
+
|
746
|
+
HIERA_VERSION_3_NOT_GLOBAL = hard_issue :HIERA_VERSION_3_NOT_GLOBAL, :where do
|
747
|
+
"hiera.yaml version 3 cannot be used in #{label.a_an(where)}"
|
748
|
+
end
|
749
|
+
|
750
|
+
HIERA_UNSUPPORTED_VERSION_IN_GLOBAL = hard_issue :HIERA_UNSUPPORTED_VERSION_IN_GLOBAL do
|
751
|
+
'hiera.yaml version 4 cannot be used in the global layer'
|
752
|
+
end
|
753
|
+
|
754
|
+
HIERA_UNDEFINED_VARIABLE = hard_issue :HIERA_UNDEFINED_VARIABLE, :name do
|
755
|
+
"Undefined variable '#{name}'"
|
756
|
+
end
|
757
|
+
|
758
|
+
HIERA_BACKEND_MULTIPLY_DEFINED = hard_issue :HIERA_BACKEND_MULTIPLY_DEFINED, :name, :first_line do
|
759
|
+
msg = "Backend '#{name}' is defined more than once"
|
760
|
+
fl = first_line
|
761
|
+
fl ? "#{msg}. First defined at line #{fl}" : msg
|
762
|
+
end
|
763
|
+
|
764
|
+
HIERA_NO_PROVIDER_FOR_BACKEND = hard_issue :HIERA_NO_PROVIDER_FOR_BACKEND, :name do
|
765
|
+
"No data provider is registered for backend '#{name}'"
|
766
|
+
end
|
767
|
+
|
768
|
+
HIERA_HIERARCHY_NAME_MULTIPLY_DEFINED = hard_issue :HIERA_HIERARCHY_NAME_MULTIPLY_DEFINED, :name, :first_line do
|
769
|
+
msg = "Hierarchy name '#{name}' defined more than once"
|
770
|
+
fl = first_line
|
771
|
+
fl ? "#{msg}. First defined at line #{fl}" : msg
|
772
|
+
end
|
773
|
+
|
774
|
+
HIERA_V3_BACKEND_NOT_GLOBAL = hard_issue :HIERA_V3_BACKEND_NOT_GLOBAL do
|
775
|
+
"'hiera3_backend' is only allowed in the global layer"
|
776
|
+
end
|
777
|
+
|
778
|
+
HIERA_DEFAULT_HIERARCHY_NOT_IN_MODULE = hard_issue :HIERA_DEFAULT_HIERARCHY_NOT_IN_MODULE do
|
779
|
+
"'default_hierarchy' is only allowed in the module layer"
|
780
|
+
end
|
781
|
+
|
782
|
+
HIERA_V3_BACKEND_REPLACED_BY_DATA_HASH = hard_issue :HIERA_V3_BACKEND_REPLACED_BY_DATA_HASH, :function_name do
|
783
|
+
"Use \"data_hash: #{function_name}_data\" instead of \"hiera3_backend: #{function_name}\""
|
784
|
+
end
|
785
|
+
|
786
|
+
HIERA_MISSING_DATA_PROVIDER_FUNCTION = hard_issue :HIERA_MISSING_DATA_PROVIDER_FUNCTION, :name do
|
787
|
+
"One of #{label.combine_strings(Lookup::HieraConfig::FUNCTION_KEYS)} must be defined in hierarchy '#{name}'"
|
788
|
+
end
|
789
|
+
|
790
|
+
HIERA_MULTIPLE_DATA_PROVIDER_FUNCTIONS = hard_issue :HIERA_MULTIPLE_DATA_PROVIDER_FUNCTIONS, :name do
|
791
|
+
"Only one of #{label.combine_strings(Lookup::HieraConfig::FUNCTION_KEYS)} can be defined in hierarchy '#{name}'"
|
792
|
+
end
|
793
|
+
|
794
|
+
HIERA_MULTIPLE_DATA_PROVIDER_FUNCTIONS_IN_DEFAULT = hard_issue :HIERA_MULTIPLE_DATA_PROVIDER_FUNCTIONS_IN_DEFAULT do
|
795
|
+
"Only one of #{label.combine_strings(Lookup::HieraConfig::FUNCTION_KEYS)} can be defined in defaults"
|
796
|
+
end
|
797
|
+
|
798
|
+
HIERA_MULTIPLE_LOCATION_SPECS = hard_issue :HIERA_MULTIPLE_LOCATION_SPECS, :name do
|
799
|
+
"Only one of #{label.combine_strings(Lookup::HieraConfig::LOCATION_KEYS)} can be defined in hierarchy '#{name}'"
|
800
|
+
end
|
801
|
+
|
802
|
+
HIERA_OPTION_RESERVED_BY_PUPPET = hard_issue :HIERA_OPTION_RESERVED_BY_PUPPET, :key, :name do
|
803
|
+
"Option key '#{key}' used in hierarchy '#{name}' is reserved by Puppet"
|
804
|
+
end
|
805
|
+
|
806
|
+
HIERA_DEFAULT_OPTION_RESERVED_BY_PUPPET = hard_issue :HIERA_DEFAULT_OPTION_RESERVED_BY_PUPPET, :key do
|
807
|
+
"Option key '#{key}' used in defaults is reserved by Puppet"
|
808
|
+
end
|
809
|
+
|
810
|
+
HIERA_DATA_PROVIDER_FUNCTION_NOT_FOUND = hard_issue :HIERA_DATA_PROVIDER_FUNCTION_NOT_FOUND, :function_type, :function_name do
|
811
|
+
"Unable to find '#{function_type}' function named '#{function_name}'"
|
812
|
+
end
|
813
|
+
|
814
|
+
HIERA_INTERPOLATION_ALIAS_NOT_ENTIRE_STRING = hard_issue :HIERA_INTERPOLATION_ALIAS_NOT_ENTIRE_STRING do
|
815
|
+
"'alias' interpolation is only permitted if the expression is equal to the entire string"
|
816
|
+
end
|
817
|
+
|
818
|
+
HIERA_INTERPOLATION_UNKNOWN_INTERPOLATION_METHOD = hard_issue :HIERA_INTERPOLATION_UNKNOWN_INTERPOLATION_METHOD, :name do
|
819
|
+
"Unknown interpolation method '#{name}'"
|
820
|
+
end
|
821
|
+
|
822
|
+
HIERA_INTERPOLATION_METHOD_SYNTAX_NOT_ALLOWED = hard_issue :HIERA_INTERPOLATION_METHOD_SYNTAX_NOT_ALLOWED do
|
823
|
+
'Interpolation using method syntax is not allowed in this context'
|
824
|
+
end
|
741
825
|
end
|
742
826
|
end
|
@@ -136,13 +136,21 @@ class BaseLoader < Loader
|
|
136
136
|
# 4. give up
|
137
137
|
#
|
138
138
|
def internal_load(typed_name)
|
139
|
-
# avoid calling get_entry
|
139
|
+
# avoid calling get_entry by looking it up
|
140
140
|
te = @named_values[typed_name]
|
141
|
-
te
|
142
|
-
|
143
|
-
te
|
144
|
-
|
141
|
+
return te unless te.nil? || te.value.nil?
|
142
|
+
|
143
|
+
te = parent.load_typed(typed_name)
|
144
|
+
return te unless te.nil? || te.value.nil?
|
145
145
|
|
146
|
+
# Under some circumstances, the call to the parent loader will have resulted in files being
|
147
|
+
# parsed that in turn contained references to the requested entity and hence, caused a
|
148
|
+
# recursive call into this loader. This means that the entry might be present now, so a new
|
149
|
+
# check must be made.
|
150
|
+
te = @named_values[typed_name]
|
151
|
+
te.nil? || te.value.nil? ? find(typed_name) : te
|
152
|
+
end
|
146
153
|
end
|
147
154
|
end
|
148
155
|
end
|
156
|
+
|
@@ -13,7 +13,13 @@ class ConfiguredDataProvider
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def config(lookup_invocation)
|
16
|
-
@config ||= assert_config_version(HieraConfig.create(lookup_invocation, configuration_path(lookup_invocation)))
|
16
|
+
@config ||= assert_config_version(HieraConfig.create(lookup_invocation, configuration_path(lookup_invocation), self))
|
17
|
+
end
|
18
|
+
|
19
|
+
# Needed to assign generated version 4 config
|
20
|
+
# @deprecated
|
21
|
+
def config=(config)
|
22
|
+
@config = config
|
17
23
|
end
|
18
24
|
|
19
25
|
# @return [Pathname] the path to the configuration
|
@@ -46,7 +52,7 @@ class ConfiguredDataProvider
|
|
46
52
|
lookup_invocation.report_not_found(key)
|
47
53
|
throw :no_such_key
|
48
54
|
end
|
49
|
-
merge_strategy.lookup(
|
55
|
+
merge_strategy.lookup(dps, lookup_invocation) do |data_provider|
|
50
56
|
data_provider.unchecked_key_lookup(key, lookup_invocation, merge_strategy)
|
51
57
|
end
|
52
58
|
end
|
@@ -14,42 +14,132 @@ class DataDigFunctionProvider < FunctionProvider
|
|
14
14
|
# @return [Object] the found object
|
15
15
|
# @throw :no_such_key when the object is not found
|
16
16
|
def unchecked_key_lookup(key, lookup_invocation, merge)
|
17
|
-
segments = key.to_a
|
18
17
|
lookup_invocation.with(:data_provider, self) do
|
19
18
|
MergeStrategy.strategy(merge).lookup(locations, lookup_invocation) do |location|
|
20
|
-
|
21
|
-
value = data_dig(key, segments, lookup_invocation, nil)
|
22
|
-
lookup_invocation.report_found(key, validate_data_value(self, value))
|
23
|
-
key.undig(value)
|
24
|
-
else
|
25
|
-
lookup_invocation.with(:location, location) do
|
26
|
-
if location.exist?
|
27
|
-
value = data_dig(key, segments, lookup_invocation, location.location)
|
28
|
-
lookup_invocation.report_found(key, validate_data_value(self, value))
|
29
|
-
key.undig(value)
|
30
|
-
else
|
31
|
-
lookup_invocation.report_path_not_found
|
32
|
-
throw :no_such_key
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
19
|
+
invoke_with_location(lookup_invocation, location, key, merge)
|
36
20
|
end
|
37
21
|
end
|
38
22
|
end
|
39
23
|
|
24
|
+
def invoke_with_location(lookup_invocation, location, key, merge)
|
25
|
+
if location.nil?
|
26
|
+
key.undig(lookup_invocation.report_found(key, validated_data_dig(key, lookup_invocation, nil, merge)))
|
27
|
+
else
|
28
|
+
lookup_invocation.with(:location, location) do
|
29
|
+
key.undig(lookup_invocation.report_found(key, validated_data_dig(key, lookup_invocation, location, merge)))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def label
|
35
|
+
'Data Dig'
|
36
|
+
end
|
37
|
+
|
38
|
+
def validated_data_dig(key, lookup_invocation, location, merge)
|
39
|
+
validate_data_value(data_dig(key, lookup_invocation, location, merge)) do
|
40
|
+
msg = "Value for key '#{key}', returned from #{full_name}"
|
41
|
+
location.nil? ? msg : "#{msg}, when using location '#{location}',"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
40
45
|
private
|
41
46
|
|
42
|
-
def data_dig(key,
|
47
|
+
def data_dig(key, lookup_invocation, location, merge)
|
48
|
+
unless location.nil? || location.exist?
|
49
|
+
lookup_invocation.report_location_not_found
|
50
|
+
throw :no_such_key
|
51
|
+
end
|
43
52
|
ctx = function_context(lookup_invocation, location)
|
44
53
|
ctx.data_hash ||= {}
|
45
54
|
catch(:no_such_key) do
|
46
55
|
hash = ctx.data_hash
|
47
|
-
hash[key] = ctx.function.call(lookup_invocation.scope,
|
56
|
+
hash[key] = ctx.function.call(lookup_invocation.scope, key.to_a, options(location), Context.new(ctx, lookup_invocation)) unless hash.include?(key)
|
48
57
|
return hash[key]
|
49
58
|
end
|
50
59
|
lookup_invocation.report_not_found(key)
|
51
60
|
throw :no_such_key
|
52
61
|
end
|
53
62
|
end
|
63
|
+
|
64
|
+
# @api private
|
65
|
+
class V3BackendFunctionProvider < DataDigFunctionProvider
|
66
|
+
TAG = 'hiera3_backend'.freeze
|
67
|
+
|
68
|
+
def data_dig(key, lookup_invocation, location, merge)
|
69
|
+
@backend ||= instantiate_backend(lookup_invocation)
|
70
|
+
|
71
|
+
# A merge_behavior retrieved from hiera.yaml must not be converted here. Instead, passing the symbol :hash
|
72
|
+
# tells the V3 backend to pick it up from the config.
|
73
|
+
resolution_type = lookup_invocation.hiera_v3_merge_behavior? ? :hash : convert_merge(merge)
|
74
|
+
@backend.lookup(key.to_s, lookup_invocation.scope, lookup_invocation.hiera_v3_location_overrides, resolution_type, context = {:recurse_guard => nil})
|
75
|
+
end
|
76
|
+
|
77
|
+
def full_name
|
78
|
+
"hiera version 3 backend '#{options[HieraConfig::KEY_BACKEND]}'"
|
79
|
+
end
|
80
|
+
|
81
|
+
def value_is_validated?
|
82
|
+
false
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def instantiate_backend(lookup_invocation)
|
88
|
+
backend_name = options[HieraConfig::KEY_BACKEND]
|
89
|
+
begin
|
90
|
+
require 'hiera/backend'
|
91
|
+
require "hiera/backend/#{backend_name.downcase}_backend"
|
92
|
+
backend = Hiera::Backend.const_get("#{backend_name.capitalize}_backend").new
|
93
|
+
return backend.method(:lookup).arity == 4 ? Hiera::Backend::Backend1xWrapper.new(backend) : backend
|
94
|
+
rescue LoadError => e
|
95
|
+
lookup_invocation.report_text { "Unable to load backend '#{backend_name}': #{e.message}" }
|
96
|
+
throw :no_such_key
|
97
|
+
rescue NameError => e
|
98
|
+
lookup_invocation.report_text { "Unable to instantiate backend '#{backend_name}': #{e.message}" }
|
99
|
+
throw :no_such_key
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Converts a lookup 'merge' parameter argument into a Hiera 'resolution_type' argument.
|
104
|
+
#
|
105
|
+
# @param merge [String,Hash,nil] The lookup 'merge' argument
|
106
|
+
# @return [Symbol,Hash,nil] The Hiera 'resolution_type'
|
107
|
+
def convert_merge(merge)
|
108
|
+
case merge
|
109
|
+
when nil
|
110
|
+
when 'first', 'default'
|
111
|
+
# Nil is OK. Defaults to Hiera :priority
|
112
|
+
nil
|
113
|
+
when Puppet::Pops::MergeStrategy
|
114
|
+
convert_merge(merge.configuration)
|
115
|
+
when 'unique'
|
116
|
+
# Equivalent to Hiera :array
|
117
|
+
:array
|
118
|
+
when 'hash'
|
119
|
+
# Equivalent to Hiera :hash with default :native merge behavior. A Hash must be passed here
|
120
|
+
# to override possible Hiera deep merge config settings.
|
121
|
+
{ :behavior => :native }
|
122
|
+
when 'deep', 'unconstrained_deep'
|
123
|
+
# Equivalent to Hiera :hash with :deeper merge behavior.
|
124
|
+
{ :behavior => :deeper }
|
125
|
+
when 'reverse_deep'
|
126
|
+
# Equivalent to Hiera :hash with :deep merge behavior.
|
127
|
+
{ :behavior => :deep }
|
128
|
+
when Hash
|
129
|
+
strategy = merge['strategy']
|
130
|
+
case strategy
|
131
|
+
when 'deep', 'unconstrained_deep', 'reverse_deep'
|
132
|
+
result = { :behavior => strategy == 'reverse_deep' ? :deep : :deeper }
|
133
|
+
# Remaining entries must have symbolic keys
|
134
|
+
merge.each_pair { |k,v| result[k.to_sym] = v unless k == 'strategy' }
|
135
|
+
result
|
136
|
+
else
|
137
|
+
convert_merge(strategy)
|
138
|
+
end
|
139
|
+
else
|
140
|
+
raise Puppet::DataBinding::LookupError, "Unrecognized value for request 'merge' parameter: '#{merge}'"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
54
144
|
end
|
55
145
|
end
|
@@ -10,6 +10,10 @@ class DataHashFunctionProvider < FunctionProvider
|
|
10
10
|
|
11
11
|
TAG = 'data_hash'.freeze
|
12
12
|
|
13
|
+
def self.trusted_return_type
|
14
|
+
@trusted_return_type ||= Types::PHashType.new(DataProvider.key_type, DataProvider.value_type)
|
15
|
+
end
|
16
|
+
|
13
17
|
# Performs a lookup with the assumption that a recursive check has been made.
|
14
18
|
#
|
15
19
|
# @param key [LookupKey] The key to lookup
|
@@ -34,7 +38,7 @@ class DataHashFunctionProvider < FunctionProvider
|
|
34
38
|
else
|
35
39
|
lookup_invocation.with(:location, location) do
|
36
40
|
if location.exist?
|
37
|
-
lookup_key(lookup_invocation, location
|
41
|
+
lookup_key(lookup_invocation, location, root_key)
|
38
42
|
else
|
39
43
|
lookup_invocation.report_location_not_found
|
40
44
|
throw :no_such_key
|
@@ -54,12 +58,19 @@ class DataHashFunctionProvider < FunctionProvider
|
|
54
58
|
lookup_invocation.report_not_found(root_key)
|
55
59
|
throw :no_such_key
|
56
60
|
end
|
57
|
-
|
61
|
+
value = validate_data_value(value) do
|
62
|
+
msg = "Value for key '#{root_key}', in hash returned from #{full_name}"
|
63
|
+
location.nil? ? msg : "#{msg}, when using location '#{location}',"
|
64
|
+
end
|
65
|
+
interpolate(value, lookup_invocation, true)
|
58
66
|
end
|
59
67
|
|
60
68
|
def data_hash(lookup_invocation, location)
|
61
69
|
ctx = function_context(lookup_invocation, location)
|
62
|
-
ctx.data_hash ||= parent_data_provider.validate_data_hash(
|
70
|
+
ctx.data_hash ||= parent_data_provider.validate_data_hash(call_data_hash_function(ctx, lookup_invocation, location)) do
|
71
|
+
msg = "Value returned from #{full_name}"
|
72
|
+
location.nil? ? msg : "#{msg}, when using location '#{location}',"
|
73
|
+
end
|
63
74
|
end
|
64
75
|
|
65
76
|
def call_data_hash_function(ctx, lookup_invocation, location)
|
@@ -100,7 +111,11 @@ class V4DataHashFunctionProvider < DataHashFunctionProvider
|
|
100
111
|
TAG = 'v4_data_hash'.freeze
|
101
112
|
|
102
113
|
def name
|
103
|
-
"
|
114
|
+
"Deprecated API function \"#{function_name}\""
|
115
|
+
end
|
116
|
+
|
117
|
+
def full_name
|
118
|
+
"deprecated API function '#{function_name}'"
|
104
119
|
end
|
105
120
|
|
106
121
|
def call_data_hash_function(ctx, lookup_invocation, location)
|