bolt 0.23.0 → 0.24.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of bolt might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb +5 -2
- data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_query.rb +5 -1
- data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +5 -8
- data/lib/bolt/applicator.rb +11 -8
- data/lib/bolt/boltdir.rb +13 -5
- data/lib/bolt/catalog.rb +22 -47
- data/lib/bolt/config.rb +1 -26
- data/lib/bolt/executor.rb +1 -1
- data/lib/bolt/outputter.rb +0 -9
- data/lib/bolt/outputter/human.rb +29 -14
- data/lib/bolt/outputter/json.rb +12 -1
- data/lib/bolt/pal.rb +12 -10
- data/lib/bolt/target.rb +0 -6
- data/lib/bolt/task.rb +53 -10
- data/lib/bolt/transport/base.rb +1 -6
- data/lib/bolt/transport/local.rb +11 -13
- data/lib/bolt/transport/local/shell.rb +2 -2
- data/lib/bolt/transport/ssh.rb +16 -11
- data/lib/bolt/transport/winrm.rb +8 -11
- data/lib/bolt/version.rb +1 -1
- data/lib/bolt_ext/schemas/task.json +12 -5
- data/libexec/apply_catalog.rb +3 -1
- data/libexec/bolt_catalog +4 -0
- data/vendored/puppet/lib/puppet.rb +2 -1
- data/vendored/puppet/lib/puppet/application/agent.rb +2 -6
- data/vendored/puppet/lib/puppet/application/apply.rb +100 -60
- data/vendored/puppet/lib/puppet/application/cert.rb +26 -291
- data/vendored/puppet/lib/puppet/application/device.rb +0 -5
- data/vendored/puppet/lib/puppet/application/lookup.rb +1 -1
- data/vendored/puppet/lib/puppet/application/ssl.rb +133 -0
- data/vendored/puppet/lib/puppet/application_support.rb +1 -2
- data/vendored/puppet/lib/puppet/configurer.rb +34 -50
- data/vendored/puppet/lib/puppet/configurer/downloader.rb +1 -1
- data/vendored/puppet/lib/puppet/configurer/plugin_handler.rb +1 -1
- data/vendored/puppet/lib/puppet/daemon.rb +1 -1
- data/vendored/puppet/lib/puppet/defaults.rb +40 -117
- data/vendored/puppet/lib/puppet/face/epp.rb +2 -2
- data/vendored/puppet/lib/puppet/face/help.rb +21 -7
- data/vendored/puppet/lib/puppet/face/node/clean.rb +14 -10
- data/vendored/puppet/lib/puppet/feature/base.rb +7 -23
- data/vendored/puppet/lib/puppet/feature/eventlog.rb +1 -1
- data/vendored/puppet/lib/puppet/file_serving/base.rb +2 -2
- data/vendored/puppet/lib/puppet/file_serving/fileset.rb +1 -1
- data/vendored/puppet/lib/puppet/file_serving/metadata.rb +2 -2
- data/vendored/puppet/lib/puppet/functions.rb +133 -0
- data/vendored/puppet/lib/puppet/functions/eyaml_lookup_key.rb +4 -5
- data/vendored/puppet/lib/puppet/functions/filter.rb +7 -6
- data/vendored/puppet/lib/puppet/functions/new.rb +37 -53
- data/vendored/puppet/lib/puppet/functions/warning.rb +1 -1
- data/vendored/puppet/lib/puppet/functions/yaml_data.rb +4 -5
- data/vendored/puppet/lib/puppet/gettext/config.rb +1 -1
- data/vendored/puppet/lib/puppet/graph.rb +0 -2
- data/vendored/puppet/lib/puppet/indirector/catalog/json.rb +14 -3
- data/vendored/puppet/lib/puppet/indirector/catalog/yaml.rb +0 -16
- data/vendored/puppet/lib/puppet/indirector/certificate/file.rb +0 -1
- data/vendored/puppet/lib/puppet/indirector/facts/yaml.rb +4 -2
- data/vendored/puppet/lib/puppet/indirector/key/file.rb +1 -6
- data/vendored/puppet/lib/puppet/indirector/node/exec.rb +1 -3
- data/vendored/puppet/lib/puppet/indirector/node/yaml.rb +0 -6
- data/vendored/puppet/lib/puppet/indirector/request.rb +1 -1
- data/vendored/puppet/lib/puppet/indirector/ssl_file.rb +3 -44
- data/vendored/puppet/lib/puppet/indirector/yaml.rb +4 -4
- data/vendored/puppet/lib/puppet/info_service/task_information_service.rb +7 -3
- data/vendored/puppet/lib/puppet/loaders.rb +1 -0
- data/vendored/puppet/lib/puppet/module/task.rb +198 -29
- data/vendored/puppet/lib/puppet/module_tool/applications/unpacker.rb +1 -1
- data/vendored/puppet/lib/puppet/network/format_support.rb +13 -8
- data/vendored/puppet/lib/puppet/network/formats.rb +93 -2
- data/vendored/puppet/lib/puppet/network/http/api/indirected_routes.rb +10 -3
- data/vendored/puppet/lib/puppet/node/facts.rb +11 -1
- data/vendored/puppet/lib/puppet/parser/catalog_compiler.rb +56 -0
- data/vendored/puppet/lib/puppet/parser/compiler.rb +3 -1
- data/vendored/puppet/lib/puppet/parser/functions.rb +3 -1
- data/vendored/puppet/lib/puppet/parser/functions/filter.rb +1 -1
- data/vendored/puppet/lib/puppet/parser/functions/generate.rb +1 -1
- data/vendored/puppet/lib/puppet/parser/functions/sprintf.rb +12 -1
- data/vendored/puppet/lib/puppet/parser/functions/tagged.rb +1 -4
- data/vendored/puppet/lib/puppet/parser/scope.rb +1 -1
- data/vendored/puppet/lib/puppet/parser/script_compiler.rb +7 -2
- data/vendored/puppet/lib/puppet/pops/evaluator/deferred_resolver.rb +5 -3
- data/vendored/puppet/lib/puppet/pops/evaluator/runtime3_converter.rb +23 -4
- data/vendored/puppet/lib/puppet/pops/evaluator/runtime3_support.rb +3 -4
- data/vendored/puppet/lib/puppet/pops/functions/dispatch.rb +4 -0
- data/vendored/puppet/lib/puppet/pops/issues.rb +8 -0
- data/vendored/puppet/lib/puppet/pops/loader/loader.rb +2 -2
- data/vendored/puppet/lib/puppet/pops/loader/loader_paths.rb +3 -1
- data/vendored/puppet/lib/puppet/pops/loader/module_loaders.rb +30 -9
- data/vendored/puppet/lib/puppet/pops/loader/ruby_legacy_function_instantiator.rb +62 -0
- data/vendored/puppet/lib/puppet/pops/loader/static_loader.rb +0 -1
- data/vendored/puppet/lib/puppet/pops/loader/task_instantiator.rb +13 -70
- data/vendored/puppet/lib/puppet/pops/loaders.rb +19 -29
- data/vendored/puppet/lib/puppet/pops/lookup/hiera_config.rb +1 -1
- data/vendored/puppet/lib/puppet/pops/model/model_label_provider.rb +4 -1
- data/vendored/puppet/lib/puppet/pops/pcore.rb +10 -33
- data/vendored/puppet/lib/puppet/pops/serialization.rb +2 -0
- data/vendored/puppet/lib/puppet/pops/serialization/from_data_converter.rb +2 -1
- data/vendored/puppet/lib/puppet/pops/serialization/to_data_converter.rb +11 -3
- data/vendored/puppet/lib/puppet/pops/serialization/to_stringified_converter.rb +226 -0
- data/vendored/puppet/lib/puppet/pops/types/p_object_type.rb +3 -0
- data/vendored/puppet/lib/puppet/pops/validation/checker4_0.rb +97 -47
- data/vendored/puppet/lib/puppet/pops/validation/validator_factory_4_0.rb +7 -8
- data/vendored/puppet/lib/puppet/property/keyvalue.rb +70 -8
- data/vendored/puppet/lib/puppet/provider/aix_object.rb +483 -0
- data/vendored/puppet/lib/puppet/provider/file/windows.rb +1 -1
- data/vendored/puppet/lib/puppet/provider/group/aix.rb +51 -112
- data/vendored/puppet/lib/puppet/provider/package/gem.rb +1 -1
- data/vendored/puppet/lib/puppet/provider/package/pip.rb +1 -1
- data/vendored/puppet/lib/puppet/provider/package/puppet_gem.rb +1 -1
- data/vendored/puppet/lib/puppet/provider/package/rpm.rb +1 -1
- data/vendored/puppet/lib/puppet/provider/package/windows/package.rb +1 -1
- data/vendored/puppet/lib/puppet/provider/package/zypper.rb +1 -1
- data/vendored/puppet/lib/puppet/provider/service/systemd.rb +1 -1
- data/vendored/puppet/lib/puppet/provider/service/windows.rb +37 -40
- data/vendored/puppet/lib/puppet/provider/user/aix.rb +142 -254
- data/vendored/puppet/lib/puppet/resource.rb +20 -3
- data/vendored/puppet/lib/puppet/resource/catalog.rb +2 -12
- data/vendored/puppet/lib/puppet/rest/routes.rb +97 -34
- data/vendored/puppet/lib/puppet/settings.rb +1 -1
- data/vendored/puppet/lib/puppet/settings/file_setting.rb +1 -1
- data/vendored/puppet/lib/puppet/ssl/base.rb +1 -9
- data/vendored/puppet/lib/puppet/ssl/certificate_request.rb +1 -13
- data/vendored/puppet/lib/puppet/ssl/certificate_request_attributes.rb +1 -1
- data/vendored/puppet/lib/puppet/ssl/host.rb +114 -232
- data/vendored/puppet/lib/puppet/ssl/key.rb +1 -5
- data/vendored/puppet/lib/puppet/ssl/oids.rb +1 -1
- data/vendored/puppet/lib/puppet/test/test_helper.rb +0 -4
- data/vendored/puppet/lib/puppet/transaction/event.rb +3 -7
- data/vendored/puppet/lib/puppet/transaction/persistence.rb +1 -1
- data/vendored/puppet/lib/puppet/type/exec.rb +18 -16
- data/vendored/puppet/lib/puppet/type/file.rb +3 -3
- data/vendored/puppet/lib/puppet/type/file/source.rb +20 -7
- data/vendored/puppet/lib/puppet/type/group.rb +3 -5
- data/vendored/puppet/lib/puppet/type/notify.rb +1 -1
- data/vendored/puppet/lib/puppet/type/package.rb +2 -5
- data/vendored/puppet/lib/puppet/type/schedule.rb +1 -1
- data/vendored/puppet/lib/puppet/type/service.rb +3 -6
- data/vendored/puppet/lib/puppet/type/tidy.rb +1 -1
- data/vendored/puppet/lib/puppet/type/user.rb +13 -20
- data/vendored/puppet/lib/puppet/util.rb +8 -9
- data/vendored/puppet/lib/puppet/util/execution.rb +3 -3
- data/vendored/puppet/lib/puppet/util/feature.rb +61 -39
- data/vendored/puppet/lib/puppet/util/log/destinations.rb +1 -1
- data/vendored/puppet/lib/puppet/util/rdoc.rb +1 -1
- data/vendored/puppet/lib/puppet/util/run_mode.rb +1 -1
- data/vendored/puppet/lib/puppet/util/storage.rb +1 -1
- data/vendored/puppet/lib/puppet/util/suidmanager.rb +7 -5
- data/vendored/puppet/lib/puppet/util/tag_set.rb +1 -1
- data/vendored/puppet/lib/puppet/util/tagging.rb +1 -1
- data/vendored/puppet/lib/puppet/util/windows.rb +18 -2
- data/vendored/puppet/lib/puppet/util/windows/adsi.rb +154 -205
- data/vendored/puppet/lib/puppet/util/windows/service.rb +770 -0
- data/vendored/puppet/lib/puppet/util/yaml.rb +41 -5
- data/vendored/puppet/lib/puppet/version.rb +1 -1
- data/vendored/puppet/lib/puppet_pal.rb +280 -24
- metadata +8 -38
- data/lib/bolt/catalog/compiler.rb +0 -48
- data/lib/bolt/catalog/loaders.rb +0 -19
- data/vendored/puppet/lib/puppet/application/ca.rb +0 -11
- data/vendored/puppet/lib/puppet/application/certificate.rb +0 -17
- data/vendored/puppet/lib/puppet/application/certificate_request.rb +0 -7
- data/vendored/puppet/lib/puppet/application/certificate_revocation_list.rb +0 -7
- data/vendored/puppet/lib/puppet/face/ca.rb +0 -266
- data/vendored/puppet/lib/puppet/face/certificate.rb +0 -167
- data/vendored/puppet/lib/puppet/face/certificate_request.rb +0 -56
- data/vendored/puppet/lib/puppet/face/certificate_revocation_list.rb +0 -56
- data/vendored/puppet/lib/puppet/graph/random_prioritizer.rb +0 -16
- data/vendored/puppet/lib/puppet/graph/title_hash_prioritizer.rb +0 -16
- data/vendored/puppet/lib/puppet/indirector/certificate/ca.rb +0 -9
- data/vendored/puppet/lib/puppet/indirector/certificate/disabled_ca.rb +0 -22
- data/vendored/puppet/lib/puppet/indirector/certificate_request/ca.rb +0 -22
- data/vendored/puppet/lib/puppet/indirector/certificate_request/disabled_ca.rb +0 -22
- data/vendored/puppet/lib/puppet/indirector/certificate_revocation_list/ca.rb +0 -8
- data/vendored/puppet/lib/puppet/indirector/certificate_revocation_list/disabled_ca.rb +0 -22
- data/vendored/puppet/lib/puppet/indirector/certificate_revocation_list/file.rb +0 -8
- data/vendored/puppet/lib/puppet/indirector/certificate_revocation_list/rest.rb +0 -11
- data/vendored/puppet/lib/puppet/indirector/certificate_status.rb +0 -4
- data/vendored/puppet/lib/puppet/indirector/certificate_status/file.rb +0 -91
- data/vendored/puppet/lib/puppet/indirector/certificate_status/rest.rb +0 -11
- data/vendored/puppet/lib/puppet/indirector/key/ca.rb +0 -16
- data/vendored/puppet/lib/puppet/indirector/key/disabled_ca.rb +0 -22
- data/vendored/puppet/lib/puppet/indirector/ldap.rb +0 -86
- data/vendored/puppet/lib/puppet/indirector/node/ldap.rb +0 -275
- data/vendored/puppet/lib/puppet/provider/aixobject.rb +0 -392
- data/vendored/puppet/lib/puppet/provider/cron/crontab.rb +0 -297
- data/vendored/puppet/lib/puppet/ssl/certificate_authority.rb +0 -475
- data/vendored/puppet/lib/puppet/ssl/certificate_authority/autosign_command.rb +0 -45
- data/vendored/puppet/lib/puppet/ssl/certificate_authority/interface.rb +0 -324
- data/vendored/puppet/lib/puppet/ssl/certificate_factory.rb +0 -219
- data/vendored/puppet/lib/puppet/ssl/certificate_revocation_list.rb +0 -111
- data/vendored/puppet/lib/puppet/ssl/inventory.rb +0 -55
- data/vendored/puppet/lib/puppet/type/cron.rb +0 -480
@@ -132,7 +132,7 @@ class HieraConfig
|
|
132
132
|
if config_path.exist?
|
133
133
|
env_context = EnvironmentContext.adapt(lookup_invocation.scope.compiler.environment)
|
134
134
|
loaded_config = env_context.cached_file_data(config_path) do |content|
|
135
|
-
parsed =
|
135
|
+
parsed = Puppet::Util::Yaml.safe_load(content, [Symbol], config_path)
|
136
136
|
|
137
137
|
# For backward compatibility, we must treat an empty file, or a yaml that doesn't
|
138
138
|
# produce a Hash as Hiera version 3 default.
|
@@ -128,7 +128,10 @@ class ModelLabelProvider
|
|
128
128
|
simple_name[1..-5] + "-Type"
|
129
129
|
else
|
130
130
|
n = o.name
|
131
|
-
n.nil?
|
131
|
+
if n.nil?
|
132
|
+
n = o.respond_to?(:_pcore_type) ? o._pcore_type.name : 'Anonymous Class'
|
133
|
+
end
|
134
|
+
n
|
132
135
|
end
|
133
136
|
end
|
134
137
|
end
|
@@ -39,39 +39,16 @@ module Pcore
|
|
39
39
|
# Fully qualified name of the task
|
40
40
|
name => { type => Pattern[/\\A[a-z][a-z0-9_]*(?:::[a-z][a-z0-9_]*)*\\z/] },
|
41
41
|
|
42
|
-
# List of
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
parameters => {
|
53
|
-
type => Optional[Hash[
|
54
|
-
Pattern[/\\A[a-z][a-z0-9_]*\\z/],
|
55
|
-
Struct[
|
56
|
-
Optional[description] => String,
|
57
|
-
Optional[sensitive] => Boolean,
|
58
|
-
type => Type]]],
|
59
|
-
value => undef
|
60
|
-
},
|
61
|
-
|
62
|
-
# Type, description, and sensitive property of each output
|
63
|
-
output => {
|
64
|
-
type => Optional[Hash[
|
65
|
-
Pattern[/\\A[a-z][a-z0-9_]*\\z/],
|
66
|
-
Struct[
|
67
|
-
Optional[description] => String,
|
68
|
-
Optional[sensitive] => Boolean,
|
69
|
-
type => Type]]],
|
70
|
-
value => undef
|
71
|
-
},
|
72
|
-
|
73
|
-
supports_noop => { type => Boolean, value => false },
|
74
|
-
input_method => { type => Optional[String] },
|
42
|
+
# List of file references referenced by metadata and their paths on disk.
|
43
|
+
# If there are no implementations listed in metadata, the first file is always
|
44
|
+
# the task executable.
|
45
|
+
files => { type => Array[Struct[name => String, path => String]] },
|
46
|
+
|
47
|
+
# Task metadata
|
48
|
+
metadata => { type => Hash[String, Any] },
|
49
|
+
|
50
|
+
# Map parameter names to their parsed data type
|
51
|
+
parameters => { type => Optional[Hash[Pattern[/\\A[a-z][a-z0-9_]*\\z/], Type]], value => undef },
|
75
52
|
}
|
76
53
|
}
|
77
54
|
PUPPET
|
@@ -19,6 +19,7 @@ module Serialization
|
|
19
19
|
|
20
20
|
# Type key used for symbols
|
21
21
|
PCORE_TYPE_SENSITIVE = 'Sensitive'.freeze
|
22
|
+
PCORE_TYPE_BINARY = 'Binary'.freeze
|
22
23
|
|
23
24
|
# Type key used for symbols
|
24
25
|
PCORE_TYPE_SYMBOL = 'Symbol'.freeze
|
@@ -34,6 +35,7 @@ end
|
|
34
35
|
require_relative 'serialization/json_path'
|
35
36
|
require_relative 'serialization/from_data_converter'
|
36
37
|
require_relative 'serialization/to_data_converter'
|
38
|
+
require_relative 'serialization/to_stringified_converter'
|
37
39
|
require_relative 'serialization/serializer'
|
38
40
|
require_relative 'serialization/deserializer'
|
39
41
|
require_relative 'serialization/json'
|
@@ -135,6 +135,7 @@ module Serialization
|
|
135
135
|
end
|
136
136
|
hash
|
137
137
|
else
|
138
|
+
# not a string
|
138
139
|
pcore_type_hash_to_value(type, value)
|
139
140
|
end
|
140
141
|
end
|
@@ -150,7 +151,7 @@ module Serialization
|
|
150
151
|
def convert(value)
|
151
152
|
if value.is_a?(Hash)
|
152
153
|
pcore_type = value[PCORE_TYPE_KEY]
|
153
|
-
if pcore_type
|
154
|
+
if pcore_type && (pcore_type.is_a?(String) || pcore_type.is_a?(Hash))
|
154
155
|
@pcore_type_procs[pcore_type].call(value, pcore_type)
|
155
156
|
else
|
156
157
|
build({}) { value.each_pair { |key, elem| with(key) { convert(elem) }}}
|
@@ -11,10 +11,10 @@ module Serialization
|
|
11
11
|
# @param value [Object] the value to convert
|
12
12
|
# @param options {Symbol => <Boolean,String>} options hash
|
13
13
|
# @option options [Boolean] :rich_data `true` if rich data is enabled
|
14
|
-
# @option options [Boolean] :
|
14
|
+
# @option options [Boolean] :local_reference use local references instead of duplicating complex entries
|
15
15
|
# @option options [Boolean] :type_by_reference `true` if Object types are converted to references rather than embedded.
|
16
16
|
# @option options [Boolean] :symbol_as_string `true` if Symbols should be converted to strings (with type loss)
|
17
|
-
# @option options [String] :
|
17
|
+
# @option options [String] :message_prefix String to prepend to in warnings and errors
|
18
18
|
# @return [Data] the processed result. An object assignable to `Data`.
|
19
19
|
#
|
20
20
|
# @api public
|
@@ -70,7 +70,15 @@ module Serialization
|
|
70
70
|
|
71
71
|
def to_data(value)
|
72
72
|
if value.nil? || Types::PScalarDataType::DEFAULT.instance?(value)
|
73
|
-
value
|
73
|
+
if @rich_data && value.is_a?(String) && value.encoding == Encoding::ASCII_8BIT
|
74
|
+
# Transform the binary string to rich Binary
|
75
|
+
{
|
76
|
+
PCORE_TYPE_KEY => PCORE_TYPE_BINARY,
|
77
|
+
PCORE_VALUE_KEY => Puppet::Pops::Types::PBinaryType::Binary.from_binary_string(value).to_s
|
78
|
+
}
|
79
|
+
else
|
80
|
+
value
|
81
|
+
end
|
74
82
|
elsif :default == value
|
75
83
|
if @rich_data
|
76
84
|
{ PCORE_TYPE_KEY => PCORE_TYPE_DEFAULT }
|
@@ -0,0 +1,226 @@
|
|
1
|
+
module Puppet::Pops
|
2
|
+
module Serialization
|
3
|
+
|
4
|
+
# Class that can process an arbitrary object into a value that is assignable to `Data`
|
5
|
+
# and where contents is converted from rich data to one of:
|
6
|
+
# * Numeric (Integer, Float)
|
7
|
+
# * Boolean
|
8
|
+
# * Undef (nil)
|
9
|
+
# * String
|
10
|
+
# * Array
|
11
|
+
# * Hash
|
12
|
+
#
|
13
|
+
# The conversion is lossy - the result cannot be deserialized to produce the original data types.
|
14
|
+
# All rich values are transformed to strings..
|
15
|
+
# Hashes with rich keys are transformed to use string representation of such keys.
|
16
|
+
#
|
17
|
+
# @api public
|
18
|
+
class ToStringifiedConverter
|
19
|
+
include Evaluator::Runtime3Support
|
20
|
+
|
21
|
+
# Converts the given _value_ according to the given _options_ and return the result of the conversion
|
22
|
+
#
|
23
|
+
# @param value [Object] the value to convert
|
24
|
+
# @param options {Symbol => <Boolean,String>} options hash
|
25
|
+
# @option options [String] :message_prefix String to prepend to in warnings and errors
|
26
|
+
# @option options [String] :semantic object (AST) to pass to the issue reporter
|
27
|
+
# @return [Data] the processed result. An object assignable to `Data` with rich data stringified.
|
28
|
+
#
|
29
|
+
# @api public
|
30
|
+
def self.convert(value, options = EMPTY_HASH)
|
31
|
+
new(options).convert(value)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Creates a new instance of the processor
|
35
|
+
#
|
36
|
+
# @param options {Symbol => Object} options hash
|
37
|
+
# @option options [String] :message_prefix String to prepend to path in warnings and errors
|
38
|
+
# @option semantic [Object] :semantic object to pass to the issue reporter
|
39
|
+
def initialize(options = EMPTY_HASH)
|
40
|
+
@message_prefix = options[:message_prefix]
|
41
|
+
@semantic = options[:semantic]
|
42
|
+
end
|
43
|
+
|
44
|
+
# Converts the given _value_
|
45
|
+
#
|
46
|
+
# @param value [Object] the value to convert
|
47
|
+
# @return [Data] the processed result. An object assignable to `Data` with rich data stringified.
|
48
|
+
#
|
49
|
+
# @api public
|
50
|
+
def convert(value)
|
51
|
+
@path = []
|
52
|
+
@values = {}
|
53
|
+
to_data(value)
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def path_to_s
|
59
|
+
s = @message_prefix || ''
|
60
|
+
s << JsonPath.to_json_path(@path)[1..-1]
|
61
|
+
s
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_data(value)
|
65
|
+
if value.is_a?(String)
|
66
|
+
to_string_or_binary(value)
|
67
|
+
elsif value.nil? || Types::PScalarDataType::DEFAULT.instance?(value)
|
68
|
+
value
|
69
|
+
elsif :default == value
|
70
|
+
'default'
|
71
|
+
elsif value.is_a?(Symbol)
|
72
|
+
value.to_s
|
73
|
+
elsif value.instance_of?(Array)
|
74
|
+
process(value) do
|
75
|
+
result = []
|
76
|
+
value.each_with_index do |elem, index|
|
77
|
+
with(index) { result << to_data(elem) }
|
78
|
+
end
|
79
|
+
result
|
80
|
+
end
|
81
|
+
elsif value.instance_of?(Hash)
|
82
|
+
process(value) do
|
83
|
+
if value.keys.all? { |key| key.is_a?(String) && key != PCORE_TYPE_KEY && key != PCORE_VALUE_KEY }
|
84
|
+
result = {}
|
85
|
+
value.each_pair { |key, elem| with(key) { result[key] = to_data(elem) } }
|
86
|
+
result
|
87
|
+
else
|
88
|
+
non_string_keyed_hash_to_data(value)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
else
|
92
|
+
unknown_to_string(value)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Turns an ASCII-8BIT encoded string into a Binary, returns US_ASCII encoded and transforms all other strings to UTF-8
|
97
|
+
# with replacements for non Unicode characters.
|
98
|
+
# If String cannot be represented as UTF-8
|
99
|
+
def to_string_or_binary(value)
|
100
|
+
encoding = value.encoding
|
101
|
+
if encoding == Encoding::ASCII_8BIT
|
102
|
+
Puppet::Pops::Types::PBinaryType::Binary.from_binary_string(value).to_s
|
103
|
+
else
|
104
|
+
# Transform to UTF-8 (do not assume UTF-8 is correct) with source invalid byte
|
105
|
+
# sequences and UTF-8 undefined characters replaced by the default unicode uFFFD character
|
106
|
+
# (black diamond with question mark).
|
107
|
+
value.encode(Encoding::UTF_8, encoding, :invalid => :replace, :undef => :replace)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# Performs a check for endless recursion before
|
112
|
+
# it yields to the given block. The result of yielding is returned.
|
113
|
+
#
|
114
|
+
# @param value [Object] the value
|
115
|
+
# @yield The block that will produce the data for the value
|
116
|
+
# @return [Data] the result of yielding to the given block, or a hash denoting a reference
|
117
|
+
#
|
118
|
+
# @api private
|
119
|
+
def process(value, &block)
|
120
|
+
with_recursive_guard(value, &block)
|
121
|
+
end
|
122
|
+
|
123
|
+
# Pushes `key` to the end of the path and yields to the given block. The
|
124
|
+
# `key` is popped when the yield returns.
|
125
|
+
# @param key [Object] the key to push on the current path
|
126
|
+
# @yield The block that will produce the returned value
|
127
|
+
# @return [Object] the result of yielding to the given block
|
128
|
+
#
|
129
|
+
# @api private
|
130
|
+
def with(key)
|
131
|
+
@path.push(key)
|
132
|
+
value = yield
|
133
|
+
@path.pop
|
134
|
+
value
|
135
|
+
end
|
136
|
+
|
137
|
+
# @param value [Object] the value to use when checking endless recursion
|
138
|
+
# @yield The block that will produce the data
|
139
|
+
# @return [Data] the result of yielding to the given block
|
140
|
+
def with_recursive_guard(value)
|
141
|
+
id = value.object_id
|
142
|
+
if @recursive_lock
|
143
|
+
if @recursive_lock.include?(id)
|
144
|
+
serialization_issue(Issues::SERIALIZATION_ENDLESS_RECURSION, :type_name => value.class.name)
|
145
|
+
end
|
146
|
+
@recursive_lock[id] = true
|
147
|
+
else
|
148
|
+
@recursive_lock = { id => true }
|
149
|
+
end
|
150
|
+
v = yield
|
151
|
+
@recursive_lock.delete(id)
|
152
|
+
v
|
153
|
+
end
|
154
|
+
|
155
|
+
# A hash key that is non conforming
|
156
|
+
def unknown_key_to_string(value)
|
157
|
+
unknown_to_string(value)
|
158
|
+
end
|
159
|
+
|
160
|
+
def unknown_to_string(value)
|
161
|
+
if value.is_a?(Regexp)
|
162
|
+
return Puppet::Pops::Types::PRegexpType.regexp_to_s_with_delimiters(value)
|
163
|
+
|
164
|
+
elsif value.instance_of?(Types::PSensitiveType::Sensitive)
|
165
|
+
# to_s does not differentiate between instances - if they were used as keys in a hash
|
166
|
+
# the stringified result would override all Sensitive keys with the last such key's value
|
167
|
+
# this adds object_id.
|
168
|
+
#
|
169
|
+
return "#<#{value}:#{value.object_id}>"
|
170
|
+
|
171
|
+
elsif value.is_a?(Puppet::Pops::Types::PObjectType)
|
172
|
+
# regular to_s on an ObjectType gives the entire definition
|
173
|
+
return value.name
|
174
|
+
|
175
|
+
end
|
176
|
+
|
177
|
+
# Do a to_s on anything else
|
178
|
+
result = value.to_s
|
179
|
+
|
180
|
+
# The result may be ascii-8bit encoded without being a binary (low level object.inspect returns ascii-8bit string)
|
181
|
+
# This can be the case if runtime objects have very simple implementation (no to_s or inspect method).
|
182
|
+
# They are most likely not of Binary nature. Therefore the encoding is forced and only if it errors
|
183
|
+
# will the result be taken as binary and encoded as base64 string.
|
184
|
+
if result.encoding == Encoding::ASCII_8BIT
|
185
|
+
begin
|
186
|
+
result.force_encoding(Encoding::UTF_8)
|
187
|
+
rescue
|
188
|
+
# The result cannot be represented in UTF-8, make it a binary Base64 encoded string
|
189
|
+
Puppet::Pops::Types::PBinaryType::Binary.from_binary_string(result).to_s
|
190
|
+
end
|
191
|
+
end
|
192
|
+
result
|
193
|
+
end
|
194
|
+
|
195
|
+
def non_string_keyed_hash_to_data(hash)
|
196
|
+
result = {}
|
197
|
+
hash.each_pair do |key, value|
|
198
|
+
if key.is_a?(Symbol)
|
199
|
+
key = key.to_s
|
200
|
+
elsif !key.is_a?(String)
|
201
|
+
key = unknown_key_to_string(key)
|
202
|
+
end
|
203
|
+
if key == "__ptype" || key =="__pvalue"
|
204
|
+
key = "reserved key: #{key}"
|
205
|
+
end
|
206
|
+
with(key) { result[key] = to_data(value) }
|
207
|
+
end
|
208
|
+
result
|
209
|
+
end
|
210
|
+
|
211
|
+
def serialization_issue(issue, options = EMPTY_HASH)
|
212
|
+
semantic = @semantic
|
213
|
+
if semantic.nil?
|
214
|
+
tos = Puppet::Pops::PuppetStack.top_of_stack
|
215
|
+
if tos.empty?
|
216
|
+
semantic = Puppet::Pops::SemanticError.new(issue, nil, EMPTY_HASH)
|
217
|
+
else
|
218
|
+
file, line = stacktrace
|
219
|
+
semantic = Puppet::Pops::SemanticError.new(issue, nil, {:file => file, :line => line})
|
220
|
+
end
|
221
|
+
end
|
222
|
+
optionally_fail(issue, semantic, options)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
@@ -284,6 +284,9 @@ class PObjectType < PMetaType
|
|
284
284
|
# @api public
|
285
285
|
def initialize(name, container, init_hash)
|
286
286
|
super(name, container, TypeAsserter.assert_instance_of(nil, TYPE_ATTRIBUTE, init_hash) { "initializer for #{self.class.label(container, name)}" })
|
287
|
+
if name == Serialization::PCORE_TYPE_KEY || name == Serialization::PCORE_VALUE_KEY
|
288
|
+
raise Puppet::ParseError, _("The attribute '%{name}' is reserved and cannot be used") % { name: name}
|
289
|
+
end
|
287
290
|
@kind = init_hash[KEY_KIND]
|
288
291
|
if @kind == ATTRIBUTE_KIND_CONSTANT # final is implied
|
289
292
|
if init_hash.include?(KEY_FINAL) && !@final
|
@@ -35,7 +35,6 @@ class Checker4_0 < Evaluator::LiteralEvaluator
|
|
35
35
|
|
36
36
|
@check_visitor = self.class.check_visitor
|
37
37
|
@acceptor = diagnostics_producer
|
38
|
-
@file_to_namespace = {}
|
39
38
|
|
40
39
|
# Use null migration checker unless given in context
|
41
40
|
@migration_checker = (Puppet.lookup(:migration_checker) { Migration::MigrationChecker.new() })
|
@@ -49,6 +48,7 @@ class Checker4_0 < Evaluator::LiteralEvaluator
|
|
49
48
|
# tree iterate the model, and call check for each element
|
50
49
|
@path = []
|
51
50
|
check(model)
|
51
|
+
internal_check_top_construct_in_module(model)
|
52
52
|
model._pcore_all_contents(@path) { |element| check(element) }
|
53
53
|
end
|
54
54
|
|
@@ -397,7 +397,7 @@ class Checker4_0 < Evaluator::LiteralEvaluator
|
|
397
397
|
acceptor.accept(Issues::ILLEGAL_DEFINITION_NAME, o, {:name=>o.name})
|
398
398
|
end
|
399
399
|
|
400
|
-
internal_check_file_namespace(o
|
400
|
+
internal_check_file_namespace(o)
|
401
401
|
internal_check_reserved_type_name(o, o.name)
|
402
402
|
internal_check_future_reserved_word(o, o.name)
|
403
403
|
end
|
@@ -533,75 +533,125 @@ class Checker4_0 < Evaluator::LiteralEvaluator
|
|
533
533
|
end
|
534
534
|
end
|
535
535
|
|
536
|
-
|
537
|
-
|
536
|
+
NO_NAMESPACE = :no_namespace
|
537
|
+
NO_PATH = :no_path
|
538
|
+
BAD_MODULE_FILE = :bad_module_file
|
539
|
+
|
540
|
+
def internal_check_file_namespace(o)
|
541
|
+
file = o.locator.file
|
542
|
+
return if file.nil? || file == '' #e.g. puppet apply -e '...'
|
538
543
|
|
539
|
-
|
544
|
+
file_namespace = namespace_for_file(file)
|
545
|
+
return if file_namespace == NO_NAMESPACE
|
540
546
|
|
541
|
-
|
542
|
-
if file_namespace.
|
543
|
-
|
544
|
-
file_namespace = @file_to_namespace[lc_file] = namespace_for_file(lc_file)
|
545
|
-
return if file_namespace.nil?
|
547
|
+
# Downcasing here because check is case-insensitive
|
548
|
+
if file_namespace == BAD_MODULE_FILE || !o.name.downcase.start_with?(file_namespace)
|
549
|
+
acceptor.accept(Issues::ILLEGAL_DEFINITION_LOCATION, o, {:name => o.name, :file => file})
|
546
550
|
end
|
551
|
+
end
|
552
|
+
|
553
|
+
def internal_check_top_construct_in_module(prog)
|
554
|
+
return unless prog.is_a?(Model::Program) && !prog.body.nil?
|
555
|
+
|
556
|
+
#Check that this is a module autoloaded file
|
557
|
+
file = prog.locator.file
|
558
|
+
return if file.nil?
|
559
|
+
return if namespace_for_file(file) == NO_NAMESPACE
|
547
560
|
|
548
|
-
|
549
|
-
|
561
|
+
body = prog.body
|
562
|
+
if(body.is_a?(Model::BlockExpression))
|
563
|
+
body.statements.each { |s| acceptor.accept(Issues::ILLEGAL_TOP_CONSTRUCT_LOCATION, s) unless valid_top_construct?(s) }
|
564
|
+
else
|
565
|
+
acceptor.accept(Issues::ILLEGAL_TOP_CONSTRUCT_LOCATION, body) unless valid_top_construct?(body)
|
550
566
|
end
|
551
567
|
end
|
552
568
|
|
553
|
-
|
569
|
+
def valid_top_construct?(o)
|
570
|
+
o.is_a?(Model::Definition) && !o.is_a?(Model::NodeDefinition)
|
571
|
+
end
|
572
|
+
|
573
|
+
# @api private
|
574
|
+
class Puppet::Util::FileNamespaceAdapter < Puppet::Pops::Adaptable::Adapter
|
575
|
+
attr_accessor :file_to_namespace
|
576
|
+
end
|
554
577
|
|
555
578
|
def namespace_for_file(file)
|
556
|
-
|
579
|
+
env = Puppet.lookup(:current_environment)
|
580
|
+
return NO_NAMESPACE if env.nil?
|
557
581
|
|
558
|
-
|
582
|
+
Puppet::Util::FileNamespaceAdapter.adapt(env) do |adapter|
|
583
|
+
adapter.file_to_namespace ||= {}
|
559
584
|
|
560
|
-
|
585
|
+
file_namespace = adapter.file_to_namespace[file]
|
586
|
+
return file_namespace unless file_namespace.nil? # No cache entry, so we do the calculation
|
561
587
|
|
562
|
-
|
588
|
+
path = Pathname.new(file)
|
563
589
|
|
564
|
-
|
565
|
-
# <modules dir>/<module name>/manifests/<module subdir>/<classfile>.pp
|
566
|
-
definition_dir_index = find_module_definition_dir(path)
|
590
|
+
return adapter.file_to_namespace[file] = NO_NAMESPACE if path.extname != ".pp"
|
567
591
|
|
568
|
-
|
569
|
-
# If it is not an initial manifest, it must come from a module,
|
570
|
-
# and from the manifests dir there. This may never get used...
|
571
|
-
return NEVER_MATCH if definition_dir_index.nil? || definition_dir_index == 0
|
592
|
+
path = path.expand_path
|
572
593
|
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
594
|
+
return adapter.file_to_namespace[file] = NO_NAMESPACE if initial_manifest?(path, env.manifest)
|
595
|
+
|
596
|
+
#All auto-loaded files from modules come from a module search path dir
|
597
|
+
relative_path = get_module_relative_path(path, env.full_modulepath)
|
598
|
+
|
599
|
+
return adapter.file_to_namespace[file] = NO_NAMESPACE if relative_path == NO_PATH
|
600
|
+
|
601
|
+
#If a file comes from a module, but isn't in the right place, always error
|
602
|
+
names = dir_to_names(relative_path)
|
603
|
+
|
604
|
+
return adapter.file_to_namespace[file] = (names == BAD_MODULE_FILE ? BAD_MODULE_FILE : names.join("::").freeze)
|
581
605
|
end
|
606
|
+
end
|
607
|
+
|
608
|
+
def initial_manifest?(path, manifest_setting)
|
609
|
+
return false if manifest_setting.nil? || manifest_setting == :no_manifest
|
582
610
|
|
583
|
-
|
611
|
+
string_path = path.to_s
|
612
|
+
|
613
|
+
string_path == manifest_setting || string_path.start_with?(manifest_setting)
|
584
614
|
end
|
585
615
|
|
586
|
-
def
|
587
|
-
|
616
|
+
def get_module_relative_path(file_path, modulepath_directories)
|
617
|
+
clean_file = file_path.cleanpath
|
618
|
+
parent_path = modulepath_directories.find { |path_dir| is_parent_dir_of(path_dir, clean_file) }
|
619
|
+
return NO_PATH if parent_path.nil?
|
588
620
|
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
621
|
+
file_path.relative_path_from(Pathname.new(parent_path))
|
622
|
+
end
|
623
|
+
|
624
|
+
def is_parent_dir_of(parent_dir, child_dir)
|
625
|
+
parent_dir_path = Pathname.new(parent_dir)
|
626
|
+
clean_parent = parent_dir_path.cleanpath
|
593
627
|
|
594
|
-
|
595
|
-
full_path == manifest_setting || full_path.start_with?(manifest_setting)
|
628
|
+
return child_dir.to_s.start_with?(clean_parent.to_s)
|
596
629
|
end
|
597
630
|
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
631
|
+
def dir_to_names(relative_path)
|
632
|
+
# Downcasing here because check is case-insensitive
|
633
|
+
path_components = relative_path.to_s.downcase.split(File::SEPARATOR)
|
634
|
+
|
635
|
+
# Example definition dir: manifests in this path:
|
636
|
+
# <module name>/manifests/<module subdir>/<classfile>.pp
|
637
|
+
dir = path_components[1]
|
638
|
+
|
639
|
+
# How can we get this result?
|
640
|
+
# If it is not an initial manifest, it must come from a module,
|
641
|
+
# and from the manifests dir there. This may never get used...
|
642
|
+
return BAD_MODULE_FILE unless dir == 'manifests' || dir == 'functions' || dir == 'types' || dir == 'plans'
|
643
|
+
|
644
|
+
names = path_components[2 .. -2] # Directories inside module
|
645
|
+
names.unshift(path_components[0]) # Name of the module itself
|
646
|
+
|
647
|
+
# Do not include name of module init file at top level of module
|
648
|
+
# e.g. <module name>/manifests/init.pp
|
649
|
+
filename = path_components[-1]
|
650
|
+
if !(path_components.length == 3 && filename == 'init.pp')
|
651
|
+
names.push(filename[0 .. -4]) # Remove .pp from filename
|
603
652
|
end
|
604
|
-
|
653
|
+
|
654
|
+
names
|
605
655
|
end
|
606
656
|
|
607
657
|
RESERVED_PARAMETERS = {
|