puppet 6.0.0 → 6.0.1
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 +4 -4
- data/Gemfile.lock +4 -4
- data/lib/puppet/application/apply.rb +99 -59
- data/lib/puppet/application/cert.rb +2 -112
- data/lib/puppet/configurer.rb +2 -3
- data/lib/puppet/defaults.rb +14 -1
- data/lib/puppet/etc.rb +20 -0
- data/lib/puppet/module/task.rb +29 -38
- data/lib/puppet/parser/catalog_compiler.rb +24 -0
- data/lib/puppet/parser/compiler.rb +3 -1
- data/lib/puppet/pops/evaluator/deferred_resolver.rb +3 -0
- data/lib/puppet/pops/evaluator/runtime3_converter.rb +2 -2
- data/lib/puppet/pops/loader/ruby_legacy_function_instantiator.rb +18 -10
- data/lib/puppet/pops/loader/task_instantiator.rb +13 -70
- data/lib/puppet/pops/parser/heredoc_support.rb +1 -2
- data/lib/puppet/pops/parser/lexer2.rb +1 -1
- data/lib/puppet/pops/pcore.rb +10 -33
- data/lib/puppet/pops/serialization.rb +1 -0
- data/lib/puppet/pops/serialization/to_data_converter.rb +9 -1
- data/lib/puppet/provider/exec.rb +57 -57
- data/lib/puppet/provider/group/aix.rb +1 -15
- data/lib/puppet/provider/group/pw.rb +4 -8
- data/lib/puppet/provider/group/windows_adsi.rb +7 -4
- data/lib/puppet/provider/nameservice.rb +1 -25
- data/lib/puppet/provider/nameservice/directoryservice.rb +5 -3
- data/lib/puppet/provider/package/portage.rb +2 -2
- data/lib/puppet/provider/service/launchd.rb +19 -3
- data/lib/puppet/provider/user/aix.rb +48 -2
- data/lib/puppet/type/group.rb +62 -18
- data/lib/puppet/type/schedule.rb +7 -0
- data/lib/puppet/util/execution.rb +14 -1
- data/lib/puppet/util/posix.rb +15 -0
- data/lib/puppet/util/storage.rb +12 -0
- data/lib/puppet/util/windows/adsi.rb +60 -1
- data/lib/puppet/util/windows/process.rb +16 -1
- data/lib/puppet/util/windows/service.rb +68 -26
- data/lib/puppet/version.rb +1 -1
- data/lib/puppet_pal.rb +36 -3
- data/locales/ja/puppet.po +598 -861
- data/locales/puppet.pot +197 -160
- data/man/man5/puppet.conf.5 +12 -1
- data/man/man8/puppet.8 +1 -1
- data/spec/integration/application/apply_spec.rb +4 -1
- data/spec/integration/util/windows/adsi_spec.rb +2 -1
- data/spec/unit/application/apply_spec.rb +14 -0
- data/spec/unit/configurer_spec.rb +11 -0
- data/spec/unit/etc_spec.rb +25 -0
- data/spec/unit/indirector/catalog/json_spec.rb +9 -3
- data/spec/unit/pops/evaluator/runtime3_converter_spec.rb +22 -4
- data/spec/unit/pops/loaders/loader_spec.rb +3 -10
- data/spec/unit/pops/loaders/loaders_spec.rb +30 -0
- data/spec/unit/pops/loaders/module_loaders_spec.rb +7 -7
- data/spec/unit/pops/parser/parse_heredoc_spec.rb +16 -0
- data/spec/unit/pops/serialization/to_from_hr_spec.rb +9 -0
- data/spec/unit/pops/types/task_spec.rb +42 -116
- data/spec/unit/provider/group/aix_spec.rb +0 -19
- data/spec/unit/provider/group/pw_spec.rb +0 -6
- data/spec/unit/provider/group/windows_adsi_spec.rb +34 -35
- data/spec/unit/provider/nameservice/directoryservice_spec.rb +2 -2
- data/spec/unit/provider/service/launchd_spec.rb +19 -0
- data/spec/unit/provider/user/aix_spec.rb +43 -2
- data/spec/unit/provider/user/windows_adsi_spec.rb +1 -4
- data/spec/unit/puppet_pal_2pec.rb +6 -6
- data/spec/unit/puppet_pal_catalog_spec.rb +58 -0
- data/spec/unit/task_spec.rb +50 -5
- data/spec/unit/type/group_spec.rb +111 -13
- data/spec/unit/util/execution_spec.rb +59 -0
- data/spec/unit/util/posix_spec.rb +28 -0
- data/spec/unit/util/storage_spec.rb +107 -0
- data/spec/unit/util/windows/adsi_spec.rb +100 -5
- data/spec/unit/util/windows/service_spec.rb +100 -43
- metadata +2 -2
data/lib/puppet/module/task.rb
CHANGED
@@ -71,19 +71,22 @@ class Puppet::Module
|
|
71
71
|
|
72
72
|
{ "name" => name, "path" => path }
|
73
73
|
end
|
74
|
+
private_class_method :get_file_details
|
74
75
|
|
75
|
-
# Find task's required lib files and retrieve paths
|
76
|
-
|
77
|
-
|
78
|
-
env = mod.environment.respond_to?(:name) ? mod.environment.name : 'production'
|
76
|
+
# Find task's required lib files and retrieve paths for both 'files' and 'implementation:files' metadata keys
|
77
|
+
def self.find_extra_files(metadata, envname = nil)
|
78
|
+
return [] if metadata.nil?
|
79
79
|
|
80
|
-
|
80
|
+
files = metadata.fetch('files', []) +
|
81
|
+
metadata.fetch('implementations', []).flat_map { |impl| impl.fetch('files', []) }
|
82
|
+
|
83
|
+
files.uniq.flat_map do |file|
|
81
84
|
module_name, mount, endpath = file.split("/", 3)
|
82
85
|
# If there's a mount directory with no trailing slash this will be nil
|
83
86
|
# We want it to be empty to construct a path
|
84
87
|
endpath ||= ''
|
85
88
|
|
86
|
-
pup_module = Puppet::Module.find(module_name,
|
89
|
+
pup_module = Puppet::Module.find(module_name, envname)
|
87
90
|
if pup_module.nil?
|
88
91
|
msg = _("Could not find module %{module_name} containing task file %{filename}" %
|
89
92
|
{module_name: module_name, filename: endpath})
|
@@ -114,22 +117,18 @@ class Puppet::Module
|
|
114
117
|
raise InvalidMetadata.new(msg, 'puppet.tasks/invalid-metadata')
|
115
118
|
end
|
116
119
|
dir_files = Dir.glob("#{path}**/*").select { |f| File.file?(f) }
|
117
|
-
|
120
|
+
dir_files.map { |f| get_file_details(f, pup_module) }
|
118
121
|
else
|
119
122
|
if last_char
|
120
123
|
msg = _("Files specified in task metadata cannot include a trailing slash: %{file}" % { file: file } )
|
121
124
|
raise InvalidMetadata.new(msg, 'puppet.task/invalid-metadata')
|
122
125
|
end
|
123
|
-
|
126
|
+
get_file_details(path, pup_module)
|
124
127
|
end
|
125
|
-
|
126
|
-
files
|
127
128
|
end
|
128
|
-
return file_list
|
129
129
|
end
|
130
|
+
private_class_method :find_extra_files
|
130
131
|
|
131
|
-
# Copied from TaskInstantiator so we can use the Error classes here
|
132
|
-
# TODO: harmonize on one implementation
|
133
132
|
# Executables list should contain the full path of all possible implementation files
|
134
133
|
def self.find_implementations(name, directory, metadata, executables)
|
135
134
|
basename = name.split('::')[1] || 'init'
|
@@ -148,7 +147,7 @@ class Puppet::Module
|
|
148
147
|
msg = _("Task metadata for task %{name} specifies missing implementation %{implementation}" % { name: name, implementation: impl['name'] })
|
149
148
|
raise InvalidTask.new(msg, 'puppet.tasks/missing-implementation', { missing: [impl['name']] } )
|
150
149
|
end
|
151
|
-
{ "name" => impl['name'], "
|
150
|
+
{ "name" => impl['name'], "path" => path }
|
152
151
|
end
|
153
152
|
return implementations
|
154
153
|
end
|
@@ -166,7 +165,13 @@ class Puppet::Module
|
|
166
165
|
raise InvalidTask.new(msg, 'puppet.tasks/multiple-implementations')
|
167
166
|
end
|
168
167
|
|
169
|
-
[{ "name" => File.basename(implementations.first), "path" => implementations.first
|
168
|
+
[{ "name" => File.basename(implementations.first), "path" => implementations.first }]
|
169
|
+
end
|
170
|
+
private_class_method :find_implementations
|
171
|
+
|
172
|
+
def self.find_files(name, directory, metadata, executables, envname = nil)
|
173
|
+
# PXP agent relies on 'impls' (which is the task file) being first if there is no metadata
|
174
|
+
find_implementations(name, directory, metadata, executables) + find_extra_files(metadata, envname)
|
170
175
|
end
|
171
176
|
|
172
177
|
def self.is_tasks_metadata_filename?(name)
|
@@ -206,7 +211,7 @@ class Puppet::Module
|
|
206
211
|
@module_executables = module_executables || []
|
207
212
|
end
|
208
213
|
|
209
|
-
def read_metadata(file)
|
214
|
+
def self.read_metadata(file)
|
210
215
|
Puppet::Util::Json.load(Puppet::FileSystem.read(file, :encoding => 'utf-8')) if file
|
211
216
|
rescue SystemCallError, IOError => err
|
212
217
|
msg = _("Error reading metadata: %{message}" % {message: err.message})
|
@@ -216,34 +221,15 @@ class Puppet::Module
|
|
216
221
|
end
|
217
222
|
|
218
223
|
def metadata
|
219
|
-
@metadata ||= read_metadata(@metadata_file)
|
220
|
-
end
|
221
|
-
|
222
|
-
def implementations
|
223
|
-
@implementations ||= self.class.find_implementations(@name, @module.tasks_directory, metadata, @module_executables)
|
224
|
+
@metadata ||= self.class.read_metadata(@metadata_file)
|
224
225
|
end
|
225
226
|
|
226
227
|
def files
|
227
|
-
|
228
|
-
outer_files = []
|
229
|
-
impl_lib_files = []
|
230
|
-
lib_files = []
|
231
|
-
|
232
|
-
unless md.nil?
|
233
|
-
outer_files = md['files'] if md.key?('files')
|
234
|
-
# There's definitely a more elegant way to do this...
|
235
|
-
if md.key?('implementations')
|
236
|
-
md['implementations'].each { |impl| impl_lib_files << impl['files'] if impl.key?('files') }
|
237
|
-
end
|
238
|
-
lib_files = self.class.find_files((impl_lib_files.flatten.uniq + outer_files).uniq, @module)
|
239
|
-
end
|
240
|
-
task_file = implementations.map {|imp| { 'name' => imp['name'], 'path' => imp['path'] } }
|
241
|
-
# PXP agent relies on 'impls' (which is the task file) being first if there is no metadata
|
242
|
-
task_file + lib_files
|
228
|
+
@files ||= self.class.find_files(@name, @module.tasks_directory, metadata, @module_executables, environment_name)
|
243
229
|
end
|
244
230
|
|
245
231
|
def validate
|
246
|
-
|
232
|
+
files
|
247
233
|
true
|
248
234
|
end
|
249
235
|
|
@@ -252,6 +238,11 @@ class Puppet::Module
|
|
252
238
|
self.module == other.module
|
253
239
|
end
|
254
240
|
|
241
|
+
def environment_name
|
242
|
+
@module.environment.respond_to?(:name) ? @module.environment.name : 'production'
|
243
|
+
end
|
244
|
+
private :environment_name
|
245
|
+
|
255
246
|
def self.new_with_files(pup_module, name, task_files, module_executables)
|
256
247
|
metadata_file = task_files.find { |f| is_tasks_metadata_filename?(f) }
|
257
248
|
Puppet::Module::Task.new(pup_module, name, module_executables, metadata_file)
|
@@ -29,4 +29,28 @@ class Puppet::Parser::CatalogCompiler < Puppet::Parser::Compiler
|
|
29
29
|
raise Puppet::Error, message, detail.backtrace
|
30
30
|
end
|
31
31
|
|
32
|
+
# Evaluates all added constructs, and validates the resulting catalog.
|
33
|
+
# This can be called whenever a series of evaluation of puppet code strings
|
34
|
+
# have reached a stable state (essentially that there are no relationships to
|
35
|
+
# non-existing resources).
|
36
|
+
#
|
37
|
+
# Raises an error if validation fails.
|
38
|
+
#
|
39
|
+
def compile_additions
|
40
|
+
evaluate_additions
|
41
|
+
validate
|
42
|
+
end
|
43
|
+
|
44
|
+
# Evaluates added constructs that are lazily evaluated until all of them have been evaluated.
|
45
|
+
#
|
46
|
+
def evaluate_additions
|
47
|
+
evaluate_generators
|
48
|
+
finish
|
49
|
+
end
|
50
|
+
|
51
|
+
# Validates the current state of the catalog.
|
52
|
+
# Does not cause evaluation of lazy constructs.
|
53
|
+
def validate
|
54
|
+
validate_catalog(CatalogValidator::FINAL)
|
55
|
+
end
|
32
56
|
end
|
@@ -577,6 +577,7 @@ class Puppet::Parser::Compiler
|
|
577
577
|
end
|
578
578
|
end
|
579
579
|
end
|
580
|
+
protected :evaluate_generators
|
580
581
|
|
581
582
|
# Find and evaluate our main object, if possible.
|
582
583
|
def evaluate_main
|
@@ -641,6 +642,7 @@ class Puppet::Parser::Compiler
|
|
641
642
|
|
642
643
|
add_resource_metaparams
|
643
644
|
end
|
645
|
+
protected :finish
|
644
646
|
|
645
647
|
def add_resource_metaparams
|
646
648
|
unless main = catalog.resource(:class, :main)
|
@@ -780,8 +782,8 @@ class Puppet::Parser::Compiler
|
|
780
782
|
settings_resource = Puppet::Parser::Resource.new('class', SETTINGS, :scope => @topscope)
|
781
783
|
|
782
784
|
@catalog.add_resource(settings_resource)
|
783
|
-
|
784
785
|
settings_type.evaluate_code(settings_resource)
|
786
|
+
settings_resource.instance_variable_set(:@evaluated, true) # Prevents settings from being reevaluated
|
785
787
|
|
786
788
|
scope = @topscope.class_scope(settings_type)
|
787
789
|
scope.merge_settings(environment.name)
|
@@ -96,6 +96,9 @@ class DeferredResolver
|
|
96
96
|
elsif x.is_a?(Puppet::Pops::Types::PSensitiveType::Sensitive)
|
97
97
|
# rewrap in a new Sensitive after resolving any nested deferred values
|
98
98
|
Puppet::Pops::Types::PSensitiveType::Sensitive.new(resolve(x.unwrap))
|
99
|
+
elsif x.is_a?(Puppet::Pops::Types::PBinaryType::Binary)
|
100
|
+
# use the ASCII-8BIT string that it wraps
|
101
|
+
x.binary_buffer
|
99
102
|
else
|
100
103
|
x
|
101
104
|
end
|
@@ -105,8 +105,8 @@ class Runtime3Converter
|
|
105
105
|
end
|
106
106
|
|
107
107
|
def convert_Symbol(o, scope, undef_value)
|
108
|
-
o == :undef
|
109
|
-
|
108
|
+
return o unless o == :undef
|
109
|
+
!@inner ? undef_value : nil
|
110
110
|
end
|
111
111
|
|
112
112
|
def convert_PAnyType(o, scope, undef_value)
|
@@ -20,17 +20,25 @@ class Puppet::Pops::Loader::RubyLegacyFunctionInstantiator
|
|
20
20
|
loader_for_function = loader.private_loader
|
21
21
|
here = get_binding(loader_for_function)
|
22
22
|
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
|
23
|
+
# Avoid reloading the function if already loaded via one of the APIs that trigger 3x function loading
|
24
|
+
# Check if function is already loaded the 3x way (and obviously not the 4x way since we would not be here in the
|
25
|
+
# first place.
|
26
|
+
environment = Puppet.lookup(:current_environment)
|
27
|
+
func_info = Puppet::Parser::Functions.environment_module(environment).get_function_info(typed_name.name.to_sym)
|
28
|
+
if func_info.nil?
|
29
|
+
# This will to do the 3x loading and define the "function_<name>" and "real_function_<name>" methods
|
30
|
+
# in the anonymous module used to hold function definitions.
|
31
|
+
#
|
32
|
+
func_info = eval(ruby_code_string, here, source_ref, 1)
|
27
33
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
+
# Validate what was loaded
|
35
|
+
unless func_info.is_a?(Hash)
|
36
|
+
raise ArgumentError, _("The code loaded from %{source_ref} did not produce the expected 3x function info Hash when evaluated. Got '%{klass}'") % { source_ref: source_ref, klass: created.class }
|
37
|
+
end
|
38
|
+
unless func_info[:name] == "function_#{typed_name.name()}"
|
39
|
+
raise ArgumentError, _("The code loaded from %{source_ref} produced mis-matched name, expected 'function_%{type_name}', got %{created_name}") % {
|
40
|
+
source_ref: source_ref, type_name: typed_name.name, created_name: func_info[:name] }
|
41
|
+
end
|
34
42
|
end
|
35
43
|
|
36
44
|
created = Puppet::Functions::Function3x.create_function(typed_name.name(), func_info, loader_for_function)
|
@@ -1,58 +1,9 @@
|
|
1
1
|
# The TypeDefinitionInstantiator instantiates a type alias or a type definition
|
2
2
|
#
|
3
|
+
require 'puppet/module/task'
|
3
4
|
module Puppet::Pops
|
4
5
|
module Loader
|
5
6
|
class TaskInstantiator
|
6
|
-
def self.load_metadata(loader, metadata)
|
7
|
-
if metadata.nil?
|
8
|
-
EMPTY_HASH
|
9
|
-
else
|
10
|
-
json_text = loader.get_contents(metadata)
|
11
|
-
begin
|
12
|
-
Puppet::Util::Json.load(json_text).freeze || EMPTY_HASH
|
13
|
-
rescue Puppet::Util::Json::ParseError => ex
|
14
|
-
raise Puppet::ParseError.new(ex.message, metadata)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.validate_implementations(typed_name, directory, metadata, executables)
|
20
|
-
name = typed_name.name
|
21
|
-
basename = typed_name.name_parts[1] || 'init'
|
22
|
-
# If 'implementations' is defined, it needs to mention at least one
|
23
|
-
# implementation, and everything it mentions must exist.
|
24
|
-
if metadata.key?('implementations')
|
25
|
-
if metadata['implementations'].is_a?(Array)
|
26
|
-
metadata['implementations'].map do |impl|
|
27
|
-
path = executables.find { |real_impl| File.basename(real_impl) == impl['name'] }
|
28
|
-
if path
|
29
|
-
{ "name" => impl['name'], "requirements" => impl.fetch('requirements', []), "path" => path }
|
30
|
-
else
|
31
|
-
raise ArgumentError, _("Task metadata for task %{name} specifies missing implementation %{implementation}") %
|
32
|
-
{ name: name, implementation: impl['name'] }
|
33
|
-
end
|
34
|
-
end
|
35
|
-
else
|
36
|
-
# If 'implementations' is the wrong type, we just pass it through and
|
37
|
-
# let the task type definition reject it.
|
38
|
-
metadata['implementations']
|
39
|
-
end
|
40
|
-
# If implementations isn't defined, then we use executables matching the
|
41
|
-
# task name, and only one may exist.
|
42
|
-
else
|
43
|
-
implementations = executables.select { |impl| File.basename(impl, '.*') == basename }
|
44
|
-
if implementations.empty?
|
45
|
-
raise ArgumentError, _('No source besides task metadata was found in directory %{directory} for task %{name}') %
|
46
|
-
{ name: name, directory: directory }
|
47
|
-
elsif implementations.length > 1
|
48
|
-
raise ArgumentError, _("Multiple executables were found in directory %{directory} for task %{name}; define 'implementations' in metadata to differentiate between them") %
|
49
|
-
{ name: name, directory: implementations[0] }
|
50
|
-
end
|
51
|
-
|
52
|
-
[{ "name" => File.basename(implementations.first), "path" => implementations.first, "requirements" => [] }]
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
7
|
def self.create(loader, typed_name, source_refs)
|
57
8
|
name = typed_name.name
|
58
9
|
basename = typed_name.name_parts[1] || 'init'
|
@@ -60,31 +11,16 @@ class TaskInstantiator
|
|
60
11
|
metadata_files, executables = source_refs.partition { |source_ref| source_ref.end_with?('.json') }
|
61
12
|
metadata_file = metadata_files.find { |source_ref| File.basename(source_ref, '.json') == basename }
|
62
13
|
|
63
|
-
metadata =
|
14
|
+
metadata = Puppet::Module::Task.read_metadata(metadata_file) || {}
|
64
15
|
|
65
|
-
|
16
|
+
files = Puppet::Module::Task.find_files(name, dirname, metadata, executables)
|
66
17
|
|
67
|
-
|
68
|
-
'name' => name,
|
69
|
-
'implementations' => implementation_metadata
|
70
|
-
}
|
18
|
+
task = { 'name' => name, 'metadata' => metadata, 'files' => files }
|
71
19
|
|
72
20
|
begin
|
73
|
-
|
74
|
-
if %w[parameters output].include?(key)
|
75
|
-
ps = {}
|
76
|
-
value.each_pair do |k, v|
|
77
|
-
pd = v.dup
|
78
|
-
t = v['type']
|
79
|
-
pd['type'] = t.nil? ? Types::TypeFactory.data : Types::TypeParser.singleton.parse(t)
|
80
|
-
ps[k] = pd
|
81
|
-
end
|
82
|
-
value = ps
|
83
|
-
end
|
84
|
-
arguments[key] = value unless arguments.key?(key)
|
85
|
-
end
|
21
|
+
task['parameters'] = convert_types(metadata['parameters'])
|
86
22
|
|
87
|
-
Types::TypeFactory.task.from_hash(
|
23
|
+
Types::TypeFactory.task.from_hash(task)
|
88
24
|
rescue Types::TypeAssertionError => ex
|
89
25
|
# Not strictly a parser error but from the users perspective, the file content didn't parse properly. The
|
90
26
|
# ParserError also conveys file info (even though line is unknown)
|
@@ -92,6 +28,13 @@ class TaskInstantiator
|
|
92
28
|
raise Puppet::ParseError.new(msg, metadata_file)
|
93
29
|
end
|
94
30
|
end
|
31
|
+
|
32
|
+
def self.convert_types(args)
|
33
|
+
args.each_with_object({}) do |(k, v), hsh|
|
34
|
+
hsh[k] = v['type'].nil? ? Types::TypeFactory.data : Types::TypeParser.singleton.parse(v['type'])
|
35
|
+
end if args
|
36
|
+
end
|
37
|
+
private_class_method :convert_types
|
95
38
|
end
|
96
39
|
end
|
97
40
|
end
|
@@ -98,8 +98,7 @@ module HeredocSupport
|
|
98
98
|
|
99
99
|
# Use a new lexer instance configured with a sub-locator to enable correct positioning
|
100
100
|
sublexer = self.class.new()
|
101
|
-
locator = Locator::SubLocator.
|
102
|
-
locator.file, heredoc_line, heredoc_offset, leading.length())
|
101
|
+
locator = Locator::SubLocator.new(locator, heredoc_line, heredoc_offset, leading.length())
|
103
102
|
|
104
103
|
# Emit a token that provides the grammar with location information about the lines on which the heredoc
|
105
104
|
# content is based.
|
@@ -189,7 +189,7 @@ class Lexer2
|
|
189
189
|
',' => lambda { emit(TOKEN_COMMA, @scanner.pos) },
|
190
190
|
'[' => lambda do
|
191
191
|
before = @scanner.pos
|
192
|
-
if (before == 0 ||
|
192
|
+
if (before == 0 || locator.string[locator.char_offset(before)-1,1] =~ /[[:blank:]\r\n]+/)
|
193
193
|
emit(TOKEN_LISTSTART, before)
|
194
194
|
else
|
195
195
|
emit(TOKEN_LBRACK, before)
|
data/lib/puppet/pops/pcore.rb
CHANGED
@@ -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
|
@@ -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 }
|